drivers: serial: stm32: prevent race condition

The async_user_callback could be triggered from
both the DMA transfer complete interrupt and
a k_work queue timeout. Since the timeout runs
outside of an ISR context, it could be interrupted
by the DMA ISR. This might leads to a race condition
where both paths access and modify shared
DMA buffer state (offset and length) simultaneously,
causing data corruption or out-of-sequence processing.

Introduces proper synchronization to prevent concurrent
access to shared DMA buffer variables,
ensuring consistent and reliable data handling.

Signed-off-by: Fabrice DJIATSA <fabrice.djiatsa-ext@st.com>
This commit is contained in:
Fabrice DJIATSA 2025-06-10 17:01:01 +02:00 committed by Dan Kalowsky
commit 26a43ca88e

View file

@ -1806,11 +1806,21 @@ static void uart_stm32_async_rx_timeout(struct k_work *work)
LOG_DBG("rx timeout");
/* The DMA is still active and could trigger an interrupt
* while we are processing this timeout, which could cause
* data corruption when the DMA ISR modifies shared data
* as we are operating on it. Prevent data race with ISR by
* masking all interrupts until we're done.
*/
unsigned int key = irq_lock();
if (data->dma_rx.counter == data->dma_rx.buffer_length) {
uart_stm32_async_rx_disable(dev);
} else {
uart_stm32_dma_rx_flush(dev, STM32_ASYNC_STATUS_TIMEOUT);
}
irq_unlock(key);
}
static void uart_stm32_async_tx_timeout(struct k_work *work)