aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJiri Kosina2007-04-23 14:41:21 -0700
committerLinus Torvalds2007-04-24 08:23:09 -0700
commit4bf3631cdb012591667ab927fcd7719d92837833 (patch)
tree25976c75042f3aa557a7bc8ece781ea4901acc62
parentc5408b88ecb8b7127334a34c55d4e0174434f4ec (diff)
8250: fix possible deadlock between serial8250_handle_port() and serial8250_interrupt()
Commit 40b36daa introduced possibility that serial8250_backup_timeout() -> serial8250_handle_port() locks port.lock without disabling irqs, thus allowing deadlock against interrupt handler (port.lock is acquired in serial8250_interrupt()). Spotted by lockdep. Signed-off-by: Jiri Kosina <jkosina@suse.cz> Cc: Dave Jones <davej@codemonkey.org.uk> Cc: Russell King <rmk@arm.linux.org.uk> Cc: Alex Williamson <alex.williamson@hp.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/serial/8250.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index c0c472ac5311..90621c3312bc 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -1334,8 +1334,9 @@ static inline void
serial8250_handle_port(struct uart_8250_port *up)
{
unsigned int status;
+ unsigned long flags;
- spin_lock(&up->port.lock);
+ spin_lock_irqsave(&up->port.lock, flags);
status = serial_inp(up, UART_LSR);
@@ -1347,7 +1348,7 @@ serial8250_handle_port(struct uart_8250_port *up)
if (status & UART_LSR_THRE)
transmit_chars(up);
- spin_unlock(&up->port.lock);
+ spin_unlock_irqrestore(&up->port.lock, flags);
}
/*