From 524d607bb705cda8a6e7af97a10bc75def144cf7 Mon Sep 17 00:00:00 2001 From: dv Date: Wed, 6 Sep 2023 03:35:57 +0000 Subject: [PATCH] vmm(4)/vmd(8): include pending interrupt in vm_run_parmams. 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 | 12 +++++++++++- sys/arch/amd64/include/vmmvar.h | 3 ++- usr.sbin/vmd/vm.c | 20 +++----------------- 3 files changed, 16 insertions(+), 19 deletions(-) diff --git a/sys/arch/amd64/amd64/vmm_machdep.c b/sys/arch/amd64/amd64/vmm_machdep.c index 4e68581d131..8cf51667407 100644 --- a/sys/arch/amd64/amd64/vmm_machdep.c +++ b/sys/arch/amd64/amd64/vmm_machdep.c @@ -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 * @@ -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 diff --git a/sys/arch/amd64/include/vmmvar.h b/sys/arch/amd64/include/vmmvar.h index 4b75fa8ac19..fe55eef9613 100644 --- a/sys/arch/amd64/include/vmmvar.h +++ b/sys/arch/amd64/include/vmmvar.h @@ -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 * @@ -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 */ diff --git a/usr.sbin/vmd/vm.c b/usr.sbin/vmd/vm.c index 5f598bcc14a..15c1dd992df 100644 --- a/usr.sbin/vmd/vm.c +++ b/usr.sbin/vmd/vm.c @@ -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 @@ -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 */ -- 2.20.1