From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EA781316182; Thu, 19 Feb 2026 02:05:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771466714; cv=none; b=uOc+TyepH3jcVmiJG/y5ZlTydQF1DKaIug/lwBAv9FzTgto2QiPtbY3rInabhW6xk88yuWnv2d5LV/uGRxK28W8Y9zpSMtdIt10J1otGc1zd7A3Tn7+rhrGzGZtBgQ1NzVpSZuOGW/9J4U4Pv/FUdL+xzdwrcRM0MUnHaPbQ/Ok= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771466714; c=relaxed/simple; bh=xX8M1F2pCk4jHgcY8DXnKaHEXFtCdd43FcJkHq/IXjE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=DirALkKHERMHuk0gAQA4sdZUGL1ILIcvWJUfD3omVxFYV/kBdWrfQX+T7BQb9Qr+yhqdTFUWgvJQc1ZO1mNeALOg1hqTetZOkea5Y39fL/iivfjG+AEMTOsdvpjdhYt5PY/l0gvAFbiRUu3THM9Ozv44U1yFvOIh87C4xjdYZak= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=D+aRyOqk; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="D+aRyOqk" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C0935C116D0; Thu, 19 Feb 2026 02:05:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1771466713; bh=xX8M1F2pCk4jHgcY8DXnKaHEXFtCdd43FcJkHq/IXjE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=D+aRyOqkIw3LpPc6dEuT+I7X6w1rkv0AA2RCCLbPYtwtpeaJ9dbu7LFBmuY35E5Rm g9sLenwYOSERSsdkU2ZQuS6XQvc49evbN5eDr3U/TlOJVx8GqTYhzfQGSwECtDRAsv uUwFHhylo7UpjXD7iWF34lk2bX+ccxwyG3C+QXy7XShFIMFqpYYQNlrg0AZGixmIGi H1HOZ5wNyTg6S071S52o089gx6RWFeurLWAFB74viVCmJfniTKAaHc9BIx7HdwqLkM iAwsLp23xW+RV5GUW8HfCY4Iph8e5l/imkD4JWFBVWakYUeAIQ8v4pk4hdAuIKKpNw 5qxwLTwQG1Tbw== From: Sasha Levin To: patches@lists.linux.dev, stable@vger.kernel.org Cc: Moteen Shah , Greg Kroah-Hartman , Sasha Levin , jirislaby@kernel.org, linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org Subject: [PATCH AUTOSEL 6.19-5.10] serial: 8250: 8250_omap.c: Clear DMA RX running status only after DMA termination is done Date: Wed, 18 Feb 2026 21:04:15 -0500 Message-ID: <20260219020422.1539798-39-sashal@kernel.org> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260219020422.1539798-1-sashal@kernel.org> References: <20260219020422.1539798-1-sashal@kernel.org> Precedence: bulk X-Mailing-List: stable@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore X-stable-base: Linux 6.19.2 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: Moteen Shah [ Upstream commit a5fd8945a478ff9be14812693891d7c9b4185a50 ] Clear rx_running flag only after DMA teardown polling completes. In the previous implementation the flag was being cleared while hardware teardown was still in progress, creating a mismatch between software state (flag = 0, "ready") and hardware state (still terminating). Signed-off-by: Moteen Shah Link: https://patch.msgid.link/20260112081829.63049-3-m-shah@ti.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- LLM Generated explanations, may be completely bogus: ## 3. Classification This is a **bug fix** — specifically a **state synchronization/race condition fix** between software state and hardware state. The `rx_running` flag was being cleared prematurely, before DMA hardware teardown completed, creating a window where software and hardware states were inconsistent. ## 4. Scope and Risk Assessment - **Lines changed**: 2 lines — one line removed, one line added (just moving `dma->rx_running = 0;`) - **Files touched**: 1 file (drivers/tty/serial/8250/8250_omap.c) - **Complexity**: Minimal — a single line is moved to a later position in the same function - **Risk**: Very low. The change only affects the timing of when `rx_running` is cleared. The core logic is unchanged. - **Potential concern**: The `count == 0` early return path (`goto out`) now skips clearing `rx_running`, which could theoretically leave the flag set. However, this is a minor edge case that likely doesn't occur in practice (DMA completion with zero data transfer). ## 5. User Impact - **Who is affected**: Users of OMAP SoC serial ports with DMA (TI AM335x, AM437x, AM65x, etc.) — widely used in embedded/industrial systems - **Severity if triggered**: The state mismatch could cause: - A new DMA being started while old hardware teardown is still in progress - Potential data corruption or missed serial data - Possible DMA engine errors or hangs - **Likelihood**: Moderate — this would occur when DMA teardown takes time (in-flight bytes scenario) and another DMA operation is attempted during the teardown window ## 6. Stability Indicators - Author is from TI (SoC vendor) — deep knowledge of the hardware - Reviewed by another TI engineer (Kumar, Udit) - Accepted by Greg Kroah-Hartman (serial subsystem maintainer) - Small, obviously correct fix with clear rationale - Self-contained — no dependencies on other patches in the series ## 7. Stable Kernel Criteria Assessment | Criterion | Met? | |-----------|------| | Obviously correct and tested | Yes — simple line movement, accepted by maintainer | | Fixes a real bug | Yes — software/hardware state mismatch | | Fixes important issue | Yes — potential data corruption/DMA errors | | Small and contained | Yes — 2 lines in 1 file | | No new features | Correct — pure bug fix | | No new APIs | Correct | ## Verification - **Code analysis**: Read `__dma_rx_do_complete()` at lines 916-971 to understand the full function flow and confirm the bug mechanism (premature flag clearing before teardown polling) - **Caller analysis**: Verified `__dma_rx_do_complete` is called from `__dma_rx_complete` (line 991, DMA completion callback) and `omap_8250_rx_dma_flush` (line 1022, flush path) - **Lock analysis**: Verified that `__dma_rx_complete` does NOT hold `rx_dma_lock` (only port lock at line 981), while `omap_8250_rx_dma_flush` does hold `rx_dma_lock` (line 1009). This confirms a real synchronization gap. - **Race window**: After `__dma_rx_complete` calls `__dma_rx_do_complete`, it calls `omap_8250_rx_dma(p)` at line 998, which checks `rx_running`. With old code, `rx_running==0` was visible during teardown polling. - **Self-contained**: Verified patch 2/3 (623b07b370e99) modifies different functions (`am654_8250_handle_rx_dma`, `am654_8250_handle_uart_errors`) and does not conflict with or depend on this patch - **File history**: `8250_omap.c` DMA-RX callback added in commit 0e31c8d173ab1 (2014-09-29), present in all active stable trees - **Mailing list**: Found the patch on lore.kernel.org, reviewed by Kumar, Udit (TI), accepted by Greg KH - **count==0 edge case**: Identified that with the patch, the `goto out` for `count==0` skips clearing `rx_running`. This is a minor concern but the count==0 case after DMA completion is unusual. This was NOT verified to be problematic in practice (unverified edge case concern). ## Conclusion This is a small, surgical, obviously correct fix for a real state synchronization bug in the OMAP 8250 serial DMA path. The `rx_running` flag was cleared too early, before hardware DMA teardown completed, creating a window where software and hardware state were inconsistent. This could lead to DMA conflicts, data corruption, or hangs on OMAP/AM series SoCs which are widely used in embedded systems. The fix is minimal (moving one line), self-contained, has no dependencies, was written by the SoC vendor (TI), reviewed by another TI engineer, and accepted by the serial subsystem maintainer. It meets all stable kernel criteria. **YES** drivers/tty/serial/8250/8250_omap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index e26bae0a6488f..272bc07c9a6b5 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -931,7 +931,6 @@ static void __dma_rx_do_complete(struct uart_8250_port *p) goto out; cookie = dma->rx_cookie; - dma->rx_running = 0; /* Re-enable RX FIFO interrupt now that transfer is complete */ if (priv->habit & UART_HAS_RHR_IT_DIS) { @@ -965,6 +964,7 @@ static void __dma_rx_do_complete(struct uart_8250_port *p) goto out; ret = tty_insert_flip_string(tty_port, dma->rx_buf, count); + dma->rx_running = 0; p->port.icount.rx += ret; p->port.icount.buf_overrun += count - ret; out: -- 2.51.0