Module Name: src Committed By: maxv Date: Sat Apr 27 09:06:18 UTC 2019
Modified Files: src/sys/dev/nvmm/x86: nvmm_x86_svm.c nvmm_x86_vmx.c Log Message: If guest events were being processed when a #VMEXIT occurred, reschedule the events rather than dismissing them. This can happen for instance when a guest wants to process an exception and an #NPF occurs on the guest IDT. In practice it occurs only when the host swapped out specific guest pages. To generate a diff of this commit: cvs rdiff -u -r1.40 -r1.41 src/sys/dev/nvmm/x86/nvmm_x86_svm.c cvs rdiff -u -r1.28 -r1.29 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/nvmm/x86/nvmm_x86_svm.c diff -u src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.40 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.41 --- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.40 Wed Apr 24 18:19:28 2019 +++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c Sat Apr 27 09:06:18 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: nvmm_x86_svm.c,v 1.40 2019/04/24 18:19:28 maxv Exp $ */ +/* $NetBSD: nvmm_x86_svm.c,v 1.41 2019/04/27 09:06:18 maxv Exp $ */ /* * Copyright (c) 2018 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.40 2019/04/24 18:19:28 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.41 2019/04/27 09:06:18 maxv Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -1259,6 +1259,17 @@ svm_htlb_flush_ack(struct svm_cpudata *c } } +static inline void +svm_exit_evt(struct svm_cpudata *cpudata, struct vmcb *vmcb) +{ + cpudata->evt_pending = false; + + if (__predict_false(vmcb->ctrl.exitintinfo & VMCB_CTRL_EXITINTINFO_V)) { + vmcb->ctrl.eventinj = vmcb->ctrl.exitintinfo; + cpudata->evt_pending = true; + } +} + static int svm_vcpu_run(struct nvmm_machine *mach, struct nvmm_cpu *vcpu, struct nvmm_exit *exit) @@ -1310,7 +1321,7 @@ svm_vcpu_run(struct nvmm_machine *mach, cpudata->gtsc_want_update = false; vcpu->hcpu_last = hcpu; } - cpudata->evt_pending = false; + svm_exit_evt(cpudata, vmcb); switch (vmcb->ctrl.exitcode) { case VMCB_EXITCODE_INTR: Index: src/sys/dev/nvmm/x86/nvmm_x86_vmx.c diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.28 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.29 --- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.28 Sat Apr 27 08:16:19 2019 +++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c Sat Apr 27 09:06:18 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: nvmm_x86_vmx.c,v 1.28 2019/04/27 08:16:19 maxv Exp $ */ +/* $NetBSD: nvmm_x86_vmx.c,v 1.29 2019/04/27 09:06:18 maxv Exp $ */ /* * Copyright (c) 2018 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.28 2019/04/27 08:16:19 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.29 2019/04/27 09:06:18 maxv Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -1844,6 +1844,25 @@ vmx_htlb_flush_ack(struct vmx_cpudata *c kcpuset_clear(cpudata->htlb_want_flush, cpu_number()); } +static inline void +vmx_exit_evt(struct vmx_cpudata *cpudata) +{ + uint64_t info, err; + + cpudata->evt_pending = false; + + info = vmx_vmread(VMCS_IDT_VECTORING_INFO); + if (__predict_true((info & INTR_INFO_VALID) == 0)) { + return; + } + err = vmx_vmread(VMCS_IDT_VECTORING_ERROR); + + vmx_vmwrite(VMCS_ENTRY_INTR_INFO, info); + vmx_vmwrite(VMCS_ENTRY_EXCEPTION_ERROR, err); + + cpudata->evt_pending = true; +} + static int vmx_vcpu_run(struct nvmm_machine *mach, struct nvmm_cpu *vcpu, struct nvmm_exit *exit) @@ -1909,7 +1928,7 @@ vmx_vcpu_run(struct nvmm_machine *mach, exit->reason = NVMM_EXIT_INVALID; break; } - cpudata->evt_pending = false; + vmx_exit_evt(cpudata); launched = true;