serial: 8250_dma: Fix DMA Rx completion race

__dma_rx_complete() is called from two places:
- Through the DMA completion callback dma_rx_complete()
- From serial8250_rx_dma_flush() after IIR_RLSI or IIR_RX_TIMEOUT
The former does not hold port's lock during __dma_rx_complete() which
allows these two to race and potentially insert the same data twice.

Extend port's lock coverage in dma_rx_complete() to prevent the race
and check if the DMA Rx is still pending completion before calling
into __dma_rx_complete().

Reported-by: Gilles BULOZ <gilles.buloz@kontron.com>
Tested-by: Gilles BULOZ <gilles.buloz@kontron.com>
Fixes: 9ee4b83e51f7 ("serial: 8250: Add support for dmaengine")
Cc: stable@vger.kernel.org
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Link: https://lore.kernel.org/r/20230130114841.25749-2-ilpo.jarvinen@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by Ilpo Järvinen and committed by Greg Kroah-Hartman 31352811 3f6c02fa

Changed files
+7 -2
drivers
tty
serial
8250
+7 -2
drivers/tty/serial/8250/8250_dma.c
··· 62 62 struct uart_8250_dma *dma = p->dma; 63 63 unsigned long flags; 64 64 65 - __dma_rx_complete(p); 66 - 67 65 spin_lock_irqsave(&p->port.lock, flags); 66 + if (dma->rx_running) 67 + __dma_rx_complete(p); 68 + 69 + /* 70 + * Cannot be combined with the previous check because __dma_rx_complete() 71 + * changes dma->rx_running. 72 + */ 68 73 if (!dma->rx_running && (serial_lsr_in(p) & UART_LSR_DR)) 69 74 p->dma->rx_dma(p); 70 75 spin_unlock_irqrestore(&p->port.lock, flags);