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;
 

Reply via email to