diff options
author | Dave Voutila <dv@cvs.openbsd.org> | 2023-01-30 21:43:13 +0000 |
---|---|---|
committer | Dave Voutila <dv@cvs.openbsd.org> | 2023-01-30 21:43:13 +0000 |
commit | 5e49cce84bbae151f792ee7b3e02ed888dac2ee2 (patch) | |
tree | da7ac67d98f6da8f65024d07a97af7feae32b182 /usr.sbin | |
parent | 04da052954425aebad15c530d9ca81bb70e5685c (diff) |
vmd(8): fix an interrupt storm in ns8250.
On slower hosts, such as those in a nested virtualization scenario
of OpenBSD guest inside OpenBSD atop Linux KVM, ns8250 can cause a
race between the kevent firing and the vcpu being kicked by an
assert/deassert of the irq.
The end user experiences a "stuck" serial console and the host will
see a vmd process peg the cpu.
This change only toggles the irq if we were in a position of being
ready to receive data on the device so while the kevent might
continuously fire, the vcpu will not be kicked repeatedly.
OK mlarkin@
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/vmd/ns8250.c | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/usr.sbin/vmd/ns8250.c b/usr.sbin/vmd/ns8250.c index dbb6568714c..f9d14338323 100644 --- a/usr.sbin/vmd/ns8250.c +++ b/usr.sbin/vmd/ns8250.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ns8250.c,v 1.34 2022/12/28 21:30:19 jmc Exp $ */ +/* $OpenBSD: ns8250.c,v 1.35 2023/01/30 21:43:12 dv Exp $ */ /* * Copyright (c) 2016 Mike Larkin <mlarkin@openbsd.org> * @@ -153,14 +153,15 @@ com_rcv_event(int fd, short kind, void *arg) return; } - if ((com1_dev.regs.lsr & LSR_RXRDY) == 0) + if ((com1_dev.regs.lsr & LSR_RXRDY) == 0) { com_rcv(&com1_dev, (uintptr_t)arg, 0); - /* If pending interrupt, inject */ - if ((com1_dev.regs.iir & IIR_NOPEND) == 0) { - /* XXX: vcpu_id */ - vcpu_assert_pic_irq((uintptr_t)arg, 0, com1_dev.irq); - vcpu_deassert_pic_irq((uintptr_t)arg, 0, com1_dev.irq); + /* If pending interrupt, inject */ + if ((com1_dev.regs.iir & IIR_NOPEND) == 0) { + /* XXX: vcpu_id */ + vcpu_assert_pic_irq((uintptr_t)arg, 0, com1_dev.irq); + vcpu_deassert_pic_irq((uintptr_t)arg, 0, com1_dev.irq); + } } mutex_unlock(&com1_dev.mutex); |