From: dv Date: Mon, 30 Jan 2023 21:43:12 +0000 (+0000) Subject: vmd(8): fix an interrupt storm in ns8250. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=2a7454b28a30a4c3757bcbbe151e946e70400d55;p=openbsd 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@ --- 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 * @@ -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);