From b1357cdc0de255b5fdf5515fd52e4f0e3e822889 Mon Sep 17 00:00:00 2001 From: Mingqiang Chi Date: Wed, 1 Jul 2020 14:53:25 +0800 Subject: [PATCH] hv:use spinlock_irqsave_obtain api for uart replace spinlock_obtain/spinlock_release with spinlock_irqsave_obtain and spinlock_irqrestore_release to avoid dead lock for uart module. this uart lock may be accessed in ISR context like this path: dispatch_interrupt->pr_err/pr_xxx or printf ->console_write->uart16550_puts Tracked-On: #4958 Signed-off-by: Mingqiang Chi --- hypervisor/debug/uart16550.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/hypervisor/debug/uart16550.c b/hypervisor/debug/uart16550.c index affa0e135..672fcd63e 100644 --- a/hypervisor/debug/uart16550.c +++ b/hypervisor/debug/uart16550.c @@ -172,20 +172,20 @@ void uart16550_init(bool early_boot) char uart16550_getc(void) { char ret = -1; + uint64_t rflags; if (!uart.enabled) { return ret; } - spinlock_obtain(&uart.rx_lock); - + spinlock_irqsave_obtain(&uart.rx_lock, &rflags); /* If a character has been received, read it */ if ((uart16550_read_reg(uart, UART16550_LSR) & LSR_DR) == LSR_DR) { /* Read a character */ ret = uart16550_read_reg(uart, UART16550_RBR); } - spinlock_release(&uart.rx_lock); + spinlock_irqrestore_release(&uart.rx_lock, rflags); return ret; } @@ -210,10 +210,13 @@ static void uart16550_putc(char c) size_t uart16550_puts(const char *buf, uint32_t len) { uint32_t i; + uint64_t rflags; + if (!uart.enabled) { return len; } - spinlock_obtain(&uart.tx_lock); + + spinlock_irqsave_obtain(&uart.tx_lock, &rflags); for (i = 0U; i < len; i++) { /* Transmit character */ uart16550_putc(*buf); @@ -223,7 +226,7 @@ size_t uart16550_puts(const char *buf, uint32_t len) } buf++; } - spinlock_release(&uart.tx_lock); + spinlock_irqrestore_release(&uart.tx_lock, rflags); return len; }