mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-08-08 03:35:14 +00:00
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 <mingqiang.chi@intel.com>
This commit is contained in:
parent
0080c6ca72
commit
b1357cdc0d
@ -172,20 +172,20 @@ void uart16550_init(bool early_boot)
|
|||||||
char uart16550_getc(void)
|
char uart16550_getc(void)
|
||||||
{
|
{
|
||||||
char ret = -1;
|
char ret = -1;
|
||||||
|
uint64_t rflags;
|
||||||
|
|
||||||
if (!uart.enabled) {
|
if (!uart.enabled) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
spinlock_obtain(&uart.rx_lock);
|
spinlock_irqsave_obtain(&uart.rx_lock, &rflags);
|
||||||
|
|
||||||
/* If a character has been received, read it */
|
/* If a character has been received, read it */
|
||||||
if ((uart16550_read_reg(uart, UART16550_LSR) & LSR_DR) == LSR_DR) {
|
if ((uart16550_read_reg(uart, UART16550_LSR) & LSR_DR) == LSR_DR) {
|
||||||
/* Read a character */
|
/* Read a character */
|
||||||
ret = uart16550_read_reg(uart, UART16550_RBR);
|
ret = uart16550_read_reg(uart, UART16550_RBR);
|
||||||
|
|
||||||
}
|
}
|
||||||
spinlock_release(&uart.rx_lock);
|
spinlock_irqrestore_release(&uart.rx_lock, rflags);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,10 +210,13 @@ static void uart16550_putc(char c)
|
|||||||
size_t uart16550_puts(const char *buf, uint32_t len)
|
size_t uart16550_puts(const char *buf, uint32_t len)
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
uint64_t rflags;
|
||||||
|
|
||||||
if (!uart.enabled) {
|
if (!uart.enabled) {
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
spinlock_obtain(&uart.tx_lock);
|
|
||||||
|
spinlock_irqsave_obtain(&uart.tx_lock, &rflags);
|
||||||
for (i = 0U; i < len; i++) {
|
for (i = 0U; i < len; i++) {
|
||||||
/* Transmit character */
|
/* Transmit character */
|
||||||
uart16550_putc(*buf);
|
uart16550_putc(*buf);
|
||||||
@ -223,7 +226,7 @@ size_t uart16550_puts(const char *buf, uint32_t len)
|
|||||||
}
|
}
|
||||||
buf++;
|
buf++;
|
||||||
}
|
}
|
||||||
spinlock_release(&uart.tx_lock);
|
spinlock_irqrestore_release(&uart.tx_lock, rflags);
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user