[PATCH] tty: serial: samsung: use dmaengine_terminate_sync() in release_dma
Marek Szyprowski
m.szyprowski at samsung.com
Fri Oct 30 17:02:32 PDT 2026
On 30.10.2026 17:23, Samarth Narang wrote:
> s3c24xx_serial_release_dma() stops the RX and TX DMA channels using the
> deprecated dmaengine_terminate_all() before unmapping their buffers and
> freeing the RX buffer. Since this does not guarantee that DMA transfers
> or their completion callbacks have finished, the controller may continue
> accessing memory after it has been unmapped or returned to the
> allocator, particularly when the port is shut down while RX DMA is
> active.
>
> Replace dmaengine_terminate_all() with dmaengine_terminate_sync() to
> ensure that outstanding DMA activity is terminated before the buffers
> are released. Both callers of s3c24xx_serial_release_dma() run in
> process context, where synchronous termination is permitted.
>
> Fixes: 62c37eedb74c ("serial: samsung: add dma reqest/release functions")
> Assisted-by: LLM
> Signed-off-by: Samarth Narang <samarth.colleges at gmail.com>
Reviewed-by: Marek Szyprowski <m.szyprowski at samsung.com>
> ---
> This issue was identified by a research static analyzer for DMA
> lifecycle ordering and has not been validated on hardware. The patch has
> only been compile-tested on arm64 with W=1.
>
> On Exynos systems, the UART uses PL330, which does not implement a
> device_synchronize callback, so this change follows the DMAengine API
> contract without independently establishing that all hardware activity
> has stopped. The PL330 termination behavior is being raised separately
> with the DMAengine maintainers.
>
> Two related questions outside the scope of this patch:
>
> - s3c24xx_serial_rx_dma_complete() unconditionally re-arms RX DMA,
> potentially racing with release_dma() and submitting another
> descriptor after termination. Should shutdown prevent further
> submissions before terminating the channel?
Yes, this need to be fixed.
> - s3c24xx_serial_stop_rx() calls dmaengine_pause(dma->tx_chan) before
> checking the RX channel's residue. Should this instead use
> dma->rx_chan?
Right, definitely that's a bug in current code.
>
> drivers/tty/serial/samsung_tty.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c
> index 640f85e2d..4eeef149b 100644
> --- a/drivers/tty/serial/samsung_tty.c
> +++ b/drivers/tty/serial/samsung_tty.c
> @@ -1145,7 +1145,7 @@ static void s3c24xx_serial_release_dma(struct s3c24xx_uart_port *p)
> struct s3c24xx_uart_dma *dma = p->dma;
>
> if (dma->rx_chan) {
> - dmaengine_terminate_all(dma->rx_chan);
> + dmaengine_terminate_sync(dma->rx_chan);
> dma_unmap_single(dmaengine_get_dma_device(dma->rx_chan), dma->rx_addr,
> dma->rx_size, DMA_FROM_DEVICE);
> kfree(dma->rx_buf);
> @@ -1154,7 +1154,7 @@ static void s3c24xx_serial_release_dma(struct s3c24xx_uart_port *p)
> }
>
> if (dma->tx_chan) {
> - dmaengine_terminate_all(dma->tx_chan);
> + dmaengine_terminate_sync(dma->tx_chan);
> dma_unmap_single(dmaengine_get_dma_device(dma->tx_chan), dma->tx_addr,
> UART_XMIT_SIZE, DMA_TO_DEVICE);
> dma_release_channel(dma->tx_chan);
>
> base-commit: 83f32c773255720a661aa45d83e36278135f23f5
>
>
Best regards
--
Marek Szyprowski, PhD
Samsung R&D Institute Poland
More information about the linux-arm-kernel
mailing list