From 61a2d25a01f59de21e0396feaf0d29351aadb23f Mon Sep 17 00:00:00 2001 From: Jacob Garber Date: Tue, 8 Oct 2019 21:24:27 -0600 Subject: [PATCH] soc/nvidia/tegra124: Fix null pointer and logic bug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 680027edf6 fixed a null dereference and logic bug in the tegra210 spi code: soc/nvidia/tegra210: Fix potential NULL pointer dereference Recent Coverity scan indicated potential NULL deference; if either spi->dma_in or spi->dma_out are NULL, the fifo_error() check could dereference a NULL pointer. Also fixed what appears to be a logic bug for the spi->dma_out case, where it was using the todo (count) from spi->dma_in. Coverity is warning about the same problem for tegra124, so apply the same fix there. Also, add braces around a while statement. Change-Id: I6a7403417ee83b703cf4ca495129f73c66691ea9 Signed-off-by: Jacob Garber Found-by: Coverity CID 124183, 124185 Reviewed-on: https://review.coreboot.org/c/coreboot/+/35904 Tested-by: build bot (Jenkins) Reviewed-by: Kyösti Mälkki --- src/soc/nvidia/tegra124/spi.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/soc/nvidia/tegra124/spi.c b/src/soc/nvidia/tegra124/spi.c index 2d6469cc3f..27ae1faf22 100644 --- a/src/soc/nvidia/tegra124/spi.c +++ b/src/soc/nvidia/tegra124/spi.c @@ -288,6 +288,9 @@ static void dump_spi_regs(struct tegra_spi_channel *spi) static void dump_dma_regs(struct apb_dma_channel *dma) { + if (dma == NULL) + return; + printk(BIOS_INFO, "DMA regs:\n" "\tahb_ptr: 0x%08x\n" "\tapb_ptr: 0x%08x\n" @@ -545,9 +548,9 @@ static int tegra_spi_dma_finish(struct tegra_spi_channel *spi) int ret; unsigned int todo; - todo = read32(&spi->dma_in->regs->wcount); - if (spi->dma_in) { + todo = read32(&spi->dma_in->regs->wcount); + while ((read32(&spi->dma_in->regs->dma_byte_sta) < todo) || dma_busy(spi->dma_in)) ; /* this shouldn't take long, no udelay */ @@ -557,9 +560,12 @@ static int tegra_spi_dma_finish(struct tegra_spi_channel *spi) } if (spi->dma_out) { + todo = read32(&spi->dma_out->regs->wcount); + while ((read32(&spi->dma_out->regs->dma_byte_sta) < todo) || - dma_busy(spi->dma_out)) + dma_busy(spi->dma_out)) { spi_delay(spi, todo - spi_byte_count(spi)); + } clrbits_le32(&spi->regs->command1, SPI_CMD1_TX_EN); dma_stop(spi->dma_out); dma_release(spi->dma_out);