mirror of
https://github.com/edk2-porting/linux-next.git
synced 2025-01-27 08:05:27 +08:00
tty/serial: at91: Handle shutdown more safely
Interrupts were being cleaned up late in the shutdown handler, it is possible that an interrupt can occur and schedule a tasklet that runs after the port is cleaned up. There is a null dereference due to this race condition with the following stacktrace: [<c02092b0>] (atmel_tasklet_func+0x514/0x814) from [<c001fd34>] (tasklet_action+0x70/0xa8) [<c001fd34>] (tasklet_action+0x70/0xa8) from [<c001f60c>] (__do_softirq+0x90/0x144) [<c001f60c>] (__do_softirq+0x90/0x144) from [<c001fa18>] (irq_exit+0x40/0x4c) [<c001fa18>] (irq_exit+0x40/0x4c) from [<c000e298>] (handle_IRQ+0x64/0x84) [<c000e298>] (handle_IRQ+0x64/0x84) from [<c000d6c0>] (__irq_svc+0x40/0x50) [<c000d6c0>] (__irq_svc+0x40/0x50) from [<c0208060>] (atmel_rx_dma_release+0x88/0xb8) [<c0208060>] (atmel_rx_dma_release+0x88/0xb8) from [<c0209740>] (atmel_shutdown+0x104/0x160) [<c0209740>] (atmel_shutdown+0x104/0x160) from [<c0205e8c>] (uart_port_shutdown+0x2c/0x38) Signed-off-by: Marek Roszko <mark.roszko@gmail.com> Acked-by: Leilei Zhao <leilei.zhao@atmel.com> Cc: <stable@vger.kernel.org> # v3.12 Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
df8d4aa0d8
commit
0cc7c6c791
@ -1650,12 +1650,24 @@ static int atmel_startup(struct uart_port *port)
|
||||
static void atmel_shutdown(struct uart_port *port)
|
||||
{
|
||||
struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
|
||||
|
||||
/*
|
||||
* Ensure everything is stopped.
|
||||
* Clear out any scheduled tasklets before
|
||||
* we destroy the buffers
|
||||
*/
|
||||
tasklet_kill(&atmel_port->tasklet);
|
||||
|
||||
/*
|
||||
* Ensure everything is stopped and
|
||||
* disable all interrupts, port and break condition.
|
||||
*/
|
||||
atmel_stop_rx(port);
|
||||
atmel_stop_tx(port);
|
||||
|
||||
UART_PUT_CR(port, ATMEL_US_RSTSTA);
|
||||
UART_PUT_IDR(port, -1);
|
||||
|
||||
|
||||
/*
|
||||
* Shut-down the DMA.
|
||||
*/
|
||||
@ -1664,12 +1676,6 @@ static void atmel_shutdown(struct uart_port *port)
|
||||
if (atmel_port->release_tx)
|
||||
atmel_port->release_tx(port);
|
||||
|
||||
/*
|
||||
* Disable all interrupts, port and break condition.
|
||||
*/
|
||||
UART_PUT_CR(port, ATMEL_US_RSTSTA);
|
||||
UART_PUT_IDR(port, -1);
|
||||
|
||||
/*
|
||||
* Free the interrupt
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user