vmd(8): stop toggling irq deassert for edge triggered devs.
authordv <dv@openbsd.org>
Wed, 25 Oct 2023 12:44:28 +0000 (12:44 +0000)
committerdv <dv@openbsd.org>
Wed, 25 Oct 2023 12:44:28 +0000 (12:44 +0000)
For edge-triggered devices, there's no need to deassert an irq given
how vmd(8) emulates a pic.  Deassertion grabs a lock and can trigger
the ioctl for toggling pending interrupts causing a race condition.
This results in a storm of vm-exits and guest vcpu becoming
unresponsive.

The original sign of this issue is guest "pauses" when pasting text
into a serial console connection in something like xterm(1).

Tested by mbuhl@, cheloha@, sashan@, kn@, and mlarkin@.

"go for it", mlarkin@

usr.sbin/vmd/i8253.c
usr.sbin/vmd/mc146818.c
usr.sbin/vmd/ns8250.c

index b98e7bd..9cc06d3 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: i8253.c,v 1.37 2023/04/14 15:31:17 tb Exp $ */
+/* $OpenBSD: i8253.c,v 1.38 2023/10/25 12:44:28 dv Exp $ */
 /*
  * Copyright (c) 2016 Mike Larkin <mlarkin@openbsd.org>
  *
@@ -371,7 +371,6 @@ i8253_fire(int fd, short type, void *arg)
        struct i8253_channel *ctr = (struct i8253_channel *)arg;
 
        vcpu_assert_pic_irq(ctr->vm_id, 0, 0);
-       vcpu_deassert_pic_irq(ctr->vm_id, 0, 0);
 
        if (ctr->mode != TIMER_INTTC) {
                timerclear(&tv);
index 43dce7b..78139f6 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: mc146818.c,v 1.26 2023/04/18 10:27:38 tb Exp $ */
+/* $OpenBSD: mc146818.c,v 1.27 2023/10/25 12:44:28 dv Exp $ */
 /*
  * Copyright (c) 2016 Mike Larkin <mlarkin@openbsd.org>
  *
@@ -150,7 +150,6 @@ rtc_fireper(int fd, short type, void *arg)
        rtc.regs[MC_REGC] |= MC_REGC_PF;
 
        vcpu_assert_pic_irq((ptrdiff_t)arg, 0, 8);
-       vcpu_deassert_pic_irq((ptrdiff_t)arg, 0, 8);
 
        evtimer_add(&rtc.per, &rtc.per_tv);
 }
index bc23876..425531c 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: ns8250.c,v 1.37 2023/04/18 10:27:38 tb Exp $ */
+/* $OpenBSD: ns8250.c,v 1.38 2023/10/25 12:44:28 dv Exp $ */
 /*
  * Copyright (c) 2016 Mike Larkin <mlarkin@openbsd.org>
  *
@@ -82,7 +82,6 @@ ratelimit(int fd, short type, void *arg)
        com1_dev.regs.iir &= ~IIR_NOPEND;
 
        vcpu_assert_pic_irq(com1_dev.vmid, 0, com1_dev.irq);
-       vcpu_deassert_pic_irq(com1_dev.vmid, 0, com1_dev.irq);
        mutex_unlock(&com1_dev.mutex);
 }
 
@@ -160,7 +159,6 @@ com_rcv_event(int fd, short kind, void *arg)
        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);