vmm(4)/vmd(8): include pending interrupt in vm_run_parmams.
authordv <dv@openbsd.org>
Wed, 6 Sep 2023 03:35:57 +0000 (03:35 +0000)
committerdv <dv@openbsd.org>
Wed, 6 Sep 2023 03:35:57 +0000 (03:35 +0000)
To remove an ioctl(2) from the vcpu thread hotpath in vmd(8), add
a flag in the vm_run_params structure to indicate if there's another
interrupt pending. This reduces latency in vcpu work related to
i/o as we save a trip into the kernel just to flip the interrupt
pending flag on or off.

Tested by phessler@, mbuhl@, stsp@, and Mischa Peters.

ok mlarkin@

sys/arch/amd64/amd64/vmm_machdep.c
sys/arch/amd64/include/vmmvar.h
usr.sbin/vmd/vm.c

index 4e68581..8cf5166 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: vmm_machdep.c,v 1.7 2023/09/05 14:00:40 mlarkin Exp $ */
+/* $OpenBSD: vmm_machdep.c,v 1.8 2023/09/06 03:35:57 dv Exp $ */
 /*
  * Copyright (c) 2014 Mike Larkin <mlarkin@openbsd.org>
  *
@@ -3973,6 +3973,11 @@ vcpu_run_vmx(struct vcpu *vcpu, struct vm_run_params *vrp)
         */
        irq = vrp->vrp_irq;
 
+       if (vrp->vrp_intr_pending)
+               vcpu->vc_intr = 1;
+       else
+               vcpu->vc_intr = 0;
+
        if (vrp->vrp_continue) {
                switch (vcpu->vc_gueststate.vg_exit_reason) {
                case VMX_EXIT_IO:
@@ -6381,6 +6386,11 @@ vcpu_run_svm(struct vcpu *vcpu, struct vm_run_params *vrp)
 
        irq = vrp->vrp_irq;
 
+       if (vrp->vrp_intr_pending)
+               vcpu->vc_intr = 1;
+       else
+               vcpu->vc_intr = 0;
+
        /*
         * If we are returning from userspace (vmd) because we exited
         * last time, fix up any needed vcpu state first. Which state
index 4b75fa8..fe55eef 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: vmmvar.h,v 1.93 2023/09/05 14:00:41 mlarkin Exp $     */
+/*     $OpenBSD: vmmvar.h,v 1.94 2023/09/06 03:35:57 dv Exp $  */
 /*
  * Copyright (c) 2014 Mike Larkin <mlarkin@openbsd.org>
  *
@@ -456,6 +456,7 @@ struct vm_run_params {
        uint32_t        vrp_vcpu_id;
        uint8_t         vrp_continue;           /* Continuing from an exit */
        uint16_t        vrp_irq;                /* IRQ to inject */
+       uint8_t         vrp_intr_pending;       /* Additional intrs pending? */
 
        /* Input/output parameter to VMM_IOC_RUN */
        struct vm_exit  *vrp_exit;              /* updated exit data */
index 5f598bc..15c1dd9 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: vm.c,v 1.90 2023/07/13 18:31:59 dv Exp $      */
+/*     $OpenBSD: vm.c,v 1.91 2023/09/06 03:35:57 dv Exp $      */
 
 /*
  * Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
@@ -1610,22 +1610,8 @@ vcpu_run_loop(void *arg)
                } else
                        vrp->vrp_irq = 0xFFFF;
 
-               /* Still more pending? */
-               if (i8259_is_pending()) {
-                       /*
-                        * XXX can probably avoid ioctls here by providing intr
-                        * in vrp
-                        */
-                       if (vcpu_pic_intr(vrp->vrp_vm_id,
-                           vrp->vrp_vcpu_id, 1)) {
-                               fatal("can't set INTR");
-                       }
-               } else {
-                       if (vcpu_pic_intr(vrp->vrp_vm_id,
-                           vrp->vrp_vcpu_id, 0)) {
-                               fatal("can't clear INTR");
-                       }
-               }
+               /* Still more interrupts pending? */
+               vrp->vrp_intr_pending = i8259_is_pending();
 
                if (ioctl(env->vmd_fd, VMM_IOC_RUN, vrp) == -1) {
                        /* If run ioctl failed, exit */