From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=100.103.45.18 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1793214644; b=NNkVgcZDEjKBzPlXZcaUTdEhU7yYIxCatEVv5/n4L3C6G+RsZqz+yG4vWSej9JKI4UuD X4Oz7E0Kh59/nMPVXljIc6fX5aw/VlzS8ZHAQKF+CgCHYWTJkSVesEy47ACqV7iPihWHc RICUchSTElEGQoLqT8bYttE1gPteG8/Vby39vuyU8Np1ayQ57KZxtGIncWqVt8Ui6hndQ FLXnA0yGHv1xOnEztrWRa4Nzz1QV9alVER7VVCMPTCE3SbffCzcXekJVMFs2AgcQSkM0B Rbb1zfcSVVWwhU0WQ1kb14JtcqA6ZRrz2wyl4cR35vZWV0se16Qf0TojfN1zh7dGrUw== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1793214644; h=Received:DKIM-Signature:From:To:Cc:Subject:Date:Message-ID:X-Mailer: In-Reply-To:References:User-Agent:X-stable:X-Patchwork-Hint: MIME-Version:Content-Transfer-Encoding; bh=A/wYDJUaPJ62aHEfTgKGajl2r80Mnpa72awqx/4Iat4=; b=vpDnJ+4Uds7jzem5A4x3JOJYl+tgMHUrF9JSFNEuveJnAv7RTaytBPJbWmxVk7aDzQcA v+aerU4myXuiGbVazyTvjlKjuJefX8zKt2Uy7mp2Bd8UQLpdHa6LRiZAVD4mOuefoKjAN pVx/kQPfi8qtXhF5S6YPs/iS5wSJUdlIouG3aVscRMrZO+IInVnBiPrGCMPe3Sr46j/zK jz0d8IJS6uB+jBr6Q9ybq4HEAVqyHON5b9D7fszSsWaQvdiHOuuDVm46OGv/mQgk9pRqB Rz9UuI8jMSorA8G5JVhHpr1UgKSQO635jnKl1pe7fy1vSAnXssJx9HFJsc3eSw5pz8w== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass header.d=linuxfoundation.org header.i=@linuxfoundation.org header.a=rsa-sha256 header.s=korg header.b=n+THElOK; arc=none smtp.remote-ip=100.103.45.18 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B992A606A321; Wed, 28 Oct 2026 19:10:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key, unprotected) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.a=rsa-sha256 header.s=korg header.b=n+THElOK Received: by smtp.kernel.org (Postfix) with ESMTPSA id 164541F01825; Wed, 28 Oct 2026 19:10:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1793214643; bh=A/wYDJUaPJ62aHEfTgKGajl2r80Mnpa72awqx/4Iat4=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=n+THElOKN2q4v16CyUVTtuQZFnhtgWsGWWUuHacRXuD7/HSjXpF6YyWMAlH37R2Yh I0QLLiHOOUdalbAG8sfMP4fzdU1AcWhAU2n4obkpvMOhbRdVvvqIMWKlMhprg1NptN Hbbspg2n00Yo7EJ0ifH3mIX2OtWrnNuUkE9E/24Y= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Breno Leitao , Jon Hunter , Thierry Reding , Mark Brown , Sasha Levin Subject: [PATCH 6.1 0930/1887] spi: tegra210-quad: Protect curr_xfer check in IRQ handler Date: Wed, 28 Oct 2026 17:50:26 +0100 Message-ID: <20261028170520.577213042@linuxfoundation.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261028170459.200466217@linuxfoundation.org> References: <20261028170459.200466217@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore X-Mailing-List: patches@lists.linux.dev List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 6.1-stable review patch. If anyone has any objections, please let me know. ------------------ From: Breno Leitao [ Upstream commit edf9088b6e1d6d88982db7eb5e736a0e4fbcc09e ] Now that all other accesses to curr_xfer are done under the lock, protect the curr_xfer NULL check in tegra_qspi_isr_thread() with the spinlock. Without this protection, the following race can occur: CPU0 (ISR thread) CPU1 (timeout path) ---------------- ------------------- if (!tqspi->curr_xfer) // sees non-NULL spin_lock() tqspi->curr_xfer = NULL spin_unlock() handle_*_xfer() spin_lock() t = tqspi->curr_xfer // NULL! ... t->len ... // NULL dereference! With this patch, all curr_xfer accesses are now properly synchronized. Although all accesses to curr_xfer are done under the lock, in tegra_qspi_isr_thread() it checks for NULL, releases the lock and reacquires it later in handle_cpu_based_xfer()/handle_dma_based_xfer(). There is a potential for an update in between, which could cause a NULL pointer dereference. To handle this, add a NULL check inside the handlers after acquiring the lock. This ensures that if the timeout path has already cleared curr_xfer, the handler will safely return without dereferencing the NULL pointer. Fixes: b4e002d8a7ce ("spi: tegra210-quad: Fix timeout handling") Signed-off-by: Breno Leitao Tested-by: Jon Hunter Acked-by: Jon Hunter Acked-by: Thierry Reding Link: https://patch.msgid.link/20260126-tegra_xfer-v2-6-6d2115e4f387@debian.org Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/spi/spi-tegra210-quad.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c index 022cc0ebee77c..cb1b7f251eac2 100644 --- a/drivers/spi/spi-tegra210-quad.c +++ b/drivers/spi/spi-tegra210-quad.c @@ -1342,6 +1342,11 @@ static irqreturn_t handle_cpu_based_xfer(struct tegra_qspi *tqspi) spin_lock_irqsave(&tqspi->lock, flags); t = tqspi->curr_xfer; + if (!t) { + spin_unlock_irqrestore(&tqspi->lock, flags); + return IRQ_HANDLED; + } + if (tqspi->tx_status || tqspi->rx_status) { tegra_qspi_handle_error(tqspi); complete(&tqspi->xfer_completion); @@ -1410,6 +1415,11 @@ static irqreturn_t handle_dma_based_xfer(struct tegra_qspi *tqspi) spin_lock_irqsave(&tqspi->lock, flags); t = tqspi->curr_xfer; + if (!t) { + spin_unlock_irqrestore(&tqspi->lock, flags); + return IRQ_HANDLED; + } + if (err) { tegra_qspi_dma_unmap_xfer(tqspi, t); tegra_qspi_handle_error(tqspi); @@ -1448,6 +1458,7 @@ static irqreturn_t handle_dma_based_xfer(struct tegra_qspi *tqspi) static irqreturn_t tegra_qspi_isr_thread(int irq, void *context_data) { struct tegra_qspi *tqspi = context_data; + unsigned long flags; u32 status; /* @@ -1465,7 +1476,9 @@ static irqreturn_t tegra_qspi_isr_thread(int irq, void *context_data) * If no transfer is in progress, check if this was a real interrupt * that the timeout handler already processed, or a spurious one. */ + spin_lock_irqsave(&tqspi->lock, flags); if (!tqspi->curr_xfer) { + spin_unlock_irqrestore(&tqspi->lock, flags); /* Spurious interrupt - transfer not ready */ if (!(status & QSPI_RDY)) return IRQ_NONE; @@ -1482,7 +1495,14 @@ static irqreturn_t tegra_qspi_isr_thread(int irq, void *context_data) tqspi->rx_status = tqspi->status_reg & (QSPI_RX_FIFO_OVF | QSPI_RX_FIFO_UNF); tegra_qspi_mask_clear_irq(tqspi); + spin_unlock_irqrestore(&tqspi->lock, flags); + /* + * Lock is released here but handlers safely re-check curr_xfer under + * lock before dereferencing. + * DMA handler also needs to sleep in wait_for_completion_*(), which + * cannot be done while holding spinlock. + */ if (!tqspi->is_curr_dma_xfer) return handle_cpu_based_xfer(tqspi); -- 2.53.0