serial-uartlite: fix missing locking in isr
authorRich Felker <dalias@libc.org>
Fri, 8 Jan 2016 20:33:50 +0000 (15:33 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 7 Feb 2016 06:56:43 +0000 (22:56 -0800)
The uartlite driver suffers from missing/duplicate/corrupted character
data when the interrupt handler runs concurrently with access to the
device from another cpu. Take the port spinlock to exclude concurrent
access.

Signed-off-by: Rich Felker <dalias@libc.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/tty/serial/uartlite.c

index c249aee..ee2e8ef 100644 (file)
@@ -194,7 +194,9 @@ static irqreturn_t ulite_isr(int irq, void *dev_id)
 {
        struct uart_port *port = dev_id;
        int busy, n = 0;
+       unsigned long flags;
 
+       spin_lock_irqsave(&port->lock, flags);
        do {
                int stat = uart_in32(ULITE_STATUS, port);
                busy  = ulite_receive(port, stat);
@@ -202,6 +204,8 @@ static irqreturn_t ulite_isr(int irq, void *dev_id)
                n++;
        } while (busy);
 
+       spin_unlock_irqrestore(&port->lock, flags);
+
        /* work done? */
        if (n > 1) {
                tty_flip_buffer_push(&port->state->port);