[PATCH 2/6] spi: tegra210-quad: Move curr_xfer read inside spinlock

Breno Leitao posted 6 patches 3 weeks, 3 days ago
There is a newer version of this series
[PATCH 2/6] spi: tegra210-quad: Move curr_xfer read inside spinlock
Posted by Breno Leitao 3 weeks, 3 days ago
Move the assignment of the transfer pointer from curr_xfer inside the
spinlock critical section in both handle_cpu_based_xfer() and
handle_dma_based_xfer().

Previously, curr_xfer was read before acquiring the lock, creating a
window where the timeout path could clear curr_xfer between reading it
and using it. By moving the read inside the lock, the handlers are
guaranteed to see a consistent value that cannot be modified by the
timeout path.

Fixes: 921fc1838fb0 ("spi: tegra210-quad: Add support for Tegra210 QSPI controller")
Signed-off-by: Breno Leitao <leitao@debian.org>
---
 drivers/spi/spi-tegra210-quad.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c
index f0408c0b4b98..ee291b9e9e9c 100644
--- a/drivers/spi/spi-tegra210-quad.c
+++ b/drivers/spi/spi-tegra210-quad.c
@@ -1440,10 +1440,11 @@ static int tegra_qspi_transfer_one_message(struct spi_controller *host,
 
 static irqreturn_t handle_cpu_based_xfer(struct tegra_qspi *tqspi)
 {
-	struct spi_transfer *t = tqspi->curr_xfer;
+	struct spi_transfer *t;
 	unsigned long flags;
 
 	spin_lock_irqsave(&tqspi->lock, flags);
+	t = tqspi->curr_xfer;
 
 	if (tqspi->tx_status ||  tqspi->rx_status) {
 		tegra_qspi_handle_error(tqspi);
@@ -1474,7 +1475,7 @@ static irqreturn_t handle_cpu_based_xfer(struct tegra_qspi *tqspi)
 
 static irqreturn_t handle_dma_based_xfer(struct tegra_qspi *tqspi)
 {
-	struct spi_transfer *t = tqspi->curr_xfer;
+	struct spi_transfer *t;
 	unsigned int total_fifo_words;
 	unsigned long flags;
 	long wait_status;
@@ -1513,6 +1514,7 @@ static irqreturn_t handle_dma_based_xfer(struct tegra_qspi *tqspi)
 	}
 
 	spin_lock_irqsave(&tqspi->lock, flags);
+	t = tqspi->curr_xfer;
 
 	if (num_errors) {
 		tegra_qspi_dma_unmap_xfer(tqspi, t);

-- 
2.47.3
Re: [PATCH 2/6] spi: tegra210-quad: Move curr_xfer read inside spinlock
Posted by Thierry Reding 3 weeks, 3 days ago
On Fri, Jan 16, 2026 at 02:41:42AM -0800, Breno Leitao wrote:
> Move the assignment of the transfer pointer from curr_xfer inside the
> spinlock critical section in both handle_cpu_based_xfer() and
> handle_dma_based_xfer().
> 
> Previously, curr_xfer was read before acquiring the lock, creating a
> window where the timeout path could clear curr_xfer between reading it
> and using it. By moving the read inside the lock, the handlers are
> guaranteed to see a consistent value that cannot be modified by the
> timeout path.
> 
> Fixes: 921fc1838fb0 ("spi: tegra210-quad: Add support for Tegra210 QSPI controller")
> Signed-off-by: Breno Leitao <leitao@debian.org>
> ---
>  drivers/spi/spi-tegra210-quad.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)

I think this is the root problem of one of the crashes that were
reported. The problem seems to be that the high CPU load can lead to a
case where tqspi->curr_xfer is modified after being copied to the local
variable, and before the check. The window for this is very slim for the
CPU based transfer, but for DMA based transfers I can see that happening
more easily.

Acked-by: Thierry Reding <treding@nvidia.com>