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;