| From e041838edacaf3c812ea976ddbb238388a705b5f Mon Sep 17 00:00:00 2001 |
| From: Richard Genoud <richard.genoud@gmail.com> |
| Date: Mon, 20 Mar 2017 11:52:41 +0100 |
| Subject: [PATCH] tty/serial: atmel: fix race condition (TX+DMA) |
| |
| commit 31ca2c63fdc0aee725cbd4f207c1256f5deaabde upstream. |
| |
| If uart_flush_buffer() is called between atmel_tx_dma() and |
| atmel_complete_tx_dma(), the circular buffer has been cleared, but not |
| atmel_port->tx_len. |
| That leads to a circular buffer overflow (dumping (UART_XMIT_SIZE - |
| atmel_port->tx_len) bytes). |
| |
| Tested-by: Nicolas Ferre <nicolas.ferre@microchip.com> |
| Signed-off-by: Richard Genoud <richard.genoud@gmail.com> |
| Cc: stable <stable@vger.kernel.org> # 3.12+ |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c |
| index 6deae1824894..0a57e20c4d44 100644 |
| --- a/drivers/tty/serial/atmel_serial.c |
| +++ b/drivers/tty/serial/atmel_serial.c |
| @@ -1930,6 +1930,11 @@ static void atmel_flush_buffer(struct uart_port *port) |
| atmel_uart_writel(port, ATMEL_PDC_TCR, 0); |
| atmel_port->pdc_tx.ofs = 0; |
| } |
| + /* |
| + * in uart_flush_buffer(), the xmit circular buffer has just |
| + * been cleared, so we have to reset tx_len accordingly. |
| + */ |
| + atmel_port->tx_len = 0; |
| } |
| |
| /* |
| -- |
| 2.12.0 |
| |