CVS commit: src/sys/dev/nvmm

2021-04-12 Thread matthew green
Module Name:src
Committed By:   mrg
Date:   Mon Apr 12 09:22:58 UTC 2021

Modified Files:
src/sys/dev/nvmm: nvmm.c

Log Message:
be sure to only access vcpu if it was initialised.


To generate a diff of this commit:
cvs rdiff -u -r1.42 -r1.43 src/sys/dev/nvmm/nvmm.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/nvmm.c
diff -u src/sys/dev/nvmm/nvmm.c:1.42 src/sys/dev/nvmm/nvmm.c:1.43
--- src/sys/dev/nvmm/nvmm.c:1.42	Fri Mar 26 15:59:53 2021
+++ src/sys/dev/nvmm/nvmm.c	Mon Apr 12 09:22:58 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm.c,v 1.42 2021/03/26 15:59:53 reinoud Exp $	*/
+/*	$NetBSD: nvmm.c,v 1.43 2021/04/12 09:22:58 mrg Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 Maxime Villard, m00nbsd.net
@@ -29,7 +29,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.42 2021/03/26 15:59:53 reinoud Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.43 2021/04/12 09:22:58 mrg Exp $");
 
 #include 
 #include 
@@ -603,7 +603,7 @@ static int
 nvmm_vcpu_run(struct nvmm_owner *owner, struct nvmm_ioc_vcpu_run *args)
 {
 	struct nvmm_machine *mach;
-	struct nvmm_cpu *vcpu;
+	struct nvmm_cpu *vcpu = NULL;
 	int error;
 
 	error = nvmm_machine_get(owner, args->machid, , false);
@@ -619,7 +619,8 @@ nvmm_vcpu_run(struct nvmm_owner *owner, 
 
 out:
 	nvmm_machine_put(mach);
-	vcpu->comm->stop = 0;
+	if (vcpu)
+		vcpu->comm->stop = 0;
 	return error;
 }
 



CVS commit: src/sys/dev/nvmm

2021-03-26 Thread Reinoud Zandijk
Module Name:src
Committed By:   reinoud
Date:   Fri Mar 26 15:59:53 UTC 2021

Modified Files:
src/sys/dev/nvmm: nvmm.c nvmm.h nvmm_internal.h
src/sys/dev/nvmm/x86: nvmm_x86.h nvmm_x86_svm.c nvmm_x86_vmx.c

Log Message:
Implement nvmm_vcpu::stop, a race-free exit from nvmm_vcpu_run() without
signals. This introduces a new kernel and userland NVMM version indicating
this support.

Patch by Kamil Rytarowski  and committed on his request.


To generate a diff of this commit:
cvs rdiff -u -r1.41 -r1.42 src/sys/dev/nvmm/nvmm.c
cvs rdiff -u -r1.15 -r1.16 src/sys/dev/nvmm/nvmm.h
cvs rdiff -u -r1.19 -r1.20 src/sys/dev/nvmm/nvmm_internal.h
cvs rdiff -u -r1.20 -r1.21 src/sys/dev/nvmm/x86/nvmm_x86.h
cvs rdiff -u -r1.82 -r1.83 src/sys/dev/nvmm/x86/nvmm_x86_svm.c
cvs rdiff -u -r1.81 -r1.82 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/nvmm.c
diff -u src/sys/dev/nvmm/nvmm.c:1.41 src/sys/dev/nvmm/nvmm.c:1.42
--- src/sys/dev/nvmm/nvmm.c:1.41	Tue Sep  8 16:58:38 2020
+++ src/sys/dev/nvmm/nvmm.c	Fri Mar 26 15:59:53 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm.c,v 1.41 2020/09/08 16:58:38 maxv Exp $	*/
+/*	$NetBSD: nvmm.c,v 1.42 2021/03/26 15:59:53 reinoud Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 Maxime Villard, m00nbsd.net
@@ -29,7 +29,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.41 2020/09/08 16:58:38 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.42 2021/03/26 15:59:53 reinoud Exp $");
 
 #include 
 #include 
@@ -574,8 +574,7 @@ nvmm_do_vcpu_run(struct nvmm_machine *ma
 
 	while (1) {
 		/* Got a signal? Or pending resched? Leave. */
-		if (__predict_false(nvmm_return_needed())) {
-			exit->reason = NVMM_VCPU_EXIT_NONE;
+		if (__predict_false(nvmm_return_needed(vcpu, exit))) {
 			return 0;
 		}
 
@@ -620,6 +619,7 @@ nvmm_vcpu_run(struct nvmm_owner *owner, 
 
 out:
 	nvmm_machine_put(mach);
+	vcpu->comm->stop = 0;
 	return error;
 }
 

Index: src/sys/dev/nvmm/nvmm.h
diff -u src/sys/dev/nvmm/nvmm.h:1.15 src/sys/dev/nvmm/nvmm.h:1.16
--- src/sys/dev/nvmm/nvmm.h:1.15	Sat Sep  5 07:22:25 2020
+++ src/sys/dev/nvmm/nvmm.h	Fri Mar 26 15:59:53 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm.h,v 1.15 2020/09/05 07:22:25 maxv Exp $	*/
+/*	$NetBSD: nvmm.h,v 1.16 2021/03/26 15:59:53 reinoud Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 Maxime Villard, m00nbsd.net
@@ -47,7 +47,12 @@ typedef uint32_t	nvmm_cpuid_t;
 #include 
 #endif
 
-#define NVMM_KERN_VERSION		1
+#define NVMM_KERN_VERSION		2
+
+/*
+ * Version 1 - Initial release in NetBSD 9.0.
+ * Version 2 - Added nvmm_vcpu::stop.
+ */
 
 struct nvmm_capability {
 	uint32_t version;
@@ -80,6 +85,9 @@ struct nvmm_comm_page {
 	/* Event. */
 	bool event_commit;
 	struct nvmm_vcpu_event event;
+
+	/* Race-free exit from nvmm_vcpu_run() without signals. */
+	volatile int stop;
 };
 
 /*

Index: src/sys/dev/nvmm/nvmm_internal.h
diff -u src/sys/dev/nvmm/nvmm_internal.h:1.19 src/sys/dev/nvmm/nvmm_internal.h:1.20
--- src/sys/dev/nvmm/nvmm_internal.h:1.19	Sun Sep  6 02:18:53 2020
+++ src/sys/dev/nvmm/nvmm_internal.h	Fri Mar 26 15:59:53 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_internal.h,v 1.19 2020/09/06 02:18:53 riastradh Exp $	*/
+/*	$NetBSD: nvmm_internal.h,v 1.20 2021/03/26 15:59:53 reinoud Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 Maxime Villard, m00nbsd.net
@@ -136,14 +136,22 @@ extern const struct nvmm_impl nvmm_x86_v
 #endif
 
 static inline bool
-nvmm_return_needed(void)
+nvmm_return_needed(struct nvmm_cpu *vcpu, struct nvmm_vcpu_exit *exit)
 {
+
 	if (preempt_needed()) {
+		exit->reason = NVMM_VCPU_EXIT_NONE;
 		return true;
 	}
 	if (curlwp->l_flag & LW_USERRET) {
+		exit->reason = NVMM_VCPU_EXIT_NONE;
+		return true;
+	}
+	if (vcpu->comm->stop) {
+		exit->reason = NVMM_VCPU_EXIT_STOPPED;
 		return true;
 	}
+
 	return false;
 }
 

Index: src/sys/dev/nvmm/x86/nvmm_x86.h
diff -u src/sys/dev/nvmm/x86/nvmm_x86.h:1.20 src/sys/dev/nvmm/x86/nvmm_x86.h:1.21
--- src/sys/dev/nvmm/x86/nvmm_x86.h:1.20	Sat Sep  5 07:22:26 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86.h	Fri Mar 26 15:59:53 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86.h,v 1.20 2020/09/05 07:22:26 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86.h,v 1.21 2021/03/26 15:59:53 reinoud Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 Maxime Villard, m00nbsd.net
@@ -74,6 +74,7 @@ struct nvmm_x86_exit_invalid {
 
 /* Generic. */
 #define NVMM_VCPU_EXIT_NONE		0xULL
+#define NVMM_VCPU_EXIT_STOPPED		0xFFFEULL
 #define NVMM_VCPU_EXIT_INVALID		0xULL
 /* x86: operations. */
 #define NVMM_VCPU_EXIT_MEMORY		0x0001ULL

Index: src/sys/dev/nvmm/x86/nvmm_x86_svm.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.82 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.83
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.82	Sat Oct 24 07:14:30 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Fri Mar 26 15:59:53 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.82 

CVS commit: src/sys/dev/nvmm/x86

2020-09-08 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Tue Sep  8 17:00:07 UTC 2020

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_vmx.c

Log Message:
nvmm-x86-vmx: improve the handling of CR0

 - CR0_ET is hard-wired to 1 in the cpu, so force CR0_ET to 1 in the
   shadow.
 - Clarify.


To generate a diff of this commit:
cvs rdiff -u -r1.78 -r1.79 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_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.78 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.79
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.78	Sun Sep  6 02:18:53 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Tue Sep  8 17:00:07 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.78 2020/09/06 02:18:53 riastradh Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.79 2020/09/08 17:00:07 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 Maxime Villard, m00nbsd.net
@@ -29,7 +29,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.78 2020/09/06 02:18:53 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.79 2020/09/08 17:00:07 maxv Exp $");
 
 #include 
 #include 
@@ -728,8 +728,8 @@ static uint64_t vmx_xcr0_mask __read_mos
 #define MSRBM_NPAGES	1
 #define MSRBM_SIZE	(MSRBM_NPAGES * PAGE_SIZE)
 
-#define CR0_STATIC \
-	(CR0_NW|CR0_CD|CR0_ET)
+#define CR0_STATIC_MASK \
+	(CR0_ET | CR0_NW | CR0_CD)
 
 #define CR4_VALID \
 	(CR4_VME |			\
@@ -1572,7 +1572,7 @@ vmx_inkernel_handle_cr0(struct nvmm_mach
 uint64_t qual)
 {
 	struct vmx_cpudata *cpudata = vcpu->cpudata;
-	uint64_t type, gpr, oldcr0, cr0;
+	uint64_t type, gpr, oldcr0, realcr0, fakecr0;
 	uint64_t efer, ctls1;
 
 	type = __SHIFTOUT(qual, VMX_QUAL_CR_TYPE);
@@ -1584,15 +1584,24 @@ vmx_inkernel_handle_cr0(struct nvmm_mach
 	KASSERT(gpr < 16);
 
 	if (gpr == NVMM_X64_GPR_RSP) {
-		gpr = vmx_vmread(VMCS_GUEST_RSP);
+		fakecr0 = vmx_vmread(VMCS_GUEST_RSP);
 	} else {
-		gpr = cpudata->gprs[gpr];
+		fakecr0 = cpudata->gprs[gpr];
 	}
 
-	cr0 = gpr | CR0_NE | CR0_ET;
-	cr0 &= ~(CR0_NW|CR0_CD);
+	/*
+	 * fakecr0 is the value the guest believes is in %cr0. realcr0 is the
+	 * actual value in %cr0.
+	 *
+	 * In fakecr0 we must force CR0_ET to 1.
+	 *
+	 * In realcr0 we must force CR0_NW and CR0_CD to 0, and CR0_ET and
+	 * CR0_NE to 1.
+	 */
+	fakecr0 |= CR0_ET;
+	realcr0 = (fakecr0 & ~CR0_STATIC_MASK) | CR0_ET | CR0_NE;
 
-	if (vmx_check_cr(cr0, vmx_cr0_fixed0, vmx_cr0_fixed1) == -1) {
+	if (vmx_check_cr(realcr0, vmx_cr0_fixed0, vmx_cr0_fixed1) == -1) {
 		return -1;
 	}
 
@@ -1601,7 +1610,7 @@ vmx_inkernel_handle_cr0(struct nvmm_mach
 	 * from CR3.
 	 */
 
-	if (cr0 & CR0_PG) {
+	if (realcr0 & CR0_PG) {
 		ctls1 = vmx_vmread(VMCS_ENTRY_CTLS);
 		efer = vmx_vmread(VMCS_GUEST_IA32_EFER);
 		if (efer & EFER_LME) {
@@ -1615,14 +1624,14 @@ vmx_inkernel_handle_cr0(struct nvmm_mach
 		vmx_vmwrite(VMCS_ENTRY_CTLS, ctls1);
 	}
 
-	oldcr0 = (vmx_vmread(VMCS_CR0_SHADOW) & CR0_STATIC) |
-	(vmx_vmread(VMCS_GUEST_CR0) & ~CR0_STATIC);
-	if ((oldcr0 ^ gpr) & CR0_TLB_FLUSH) {
+	oldcr0 = (vmx_vmread(VMCS_CR0_SHADOW) & CR0_STATIC_MASK) |
+	(vmx_vmread(VMCS_GUEST_CR0) & ~CR0_STATIC_MASK);
+	if ((oldcr0 ^ fakecr0) & CR0_TLB_FLUSH) {
 		cpudata->gtlb_want_flush = true;
 	}
 
-	vmx_vmwrite(VMCS_CR0_SHADOW, gpr);
-	vmx_vmwrite(VMCS_GUEST_CR0, cr0);
+	vmx_vmwrite(VMCS_CR0_SHADOW, fakecr0);
+	vmx_vmwrite(VMCS_GUEST_CR0, realcr0);
 	vmx_inkernel_advance();
 	return 0;
 }
@@ -2574,15 +2583,26 @@ vmx_vcpu_setstate(struct nvmm_cpu *vcpu)
 
 	if (flags & NVMM_X64_STATE_CRS) {
 		/*
-		 * CR0_NE and CR4_VMXE are mandatory.
+		 * CR0_ET must be 1 both in the shadow and the real register.
+		 * CR0_NE must be 1 in the real register.
+		 * CR0_NW and CR0_CD must be 0 in the real register.
 		 */
-		vmx_vmwrite(VMCS_CR0_SHADOW, state->crs[NVMM_X64_CR_CR0]);
+		vmx_vmwrite(VMCS_CR0_SHADOW,
+		(state->crs[NVMM_X64_CR_CR0] & CR0_STATIC_MASK) |
+		CR0_ET);
 		vmx_vmwrite(VMCS_GUEST_CR0,
-		state->crs[NVMM_X64_CR_CR0] | CR0_NE);
+		(state->crs[NVMM_X64_CR_CR0] & ~CR0_STATIC_MASK) |
+		CR0_ET | CR0_NE);
+
 		cpudata->gcr2 = state->crs[NVMM_X64_CR_CR2];
-		vmx_vmwrite(VMCS_GUEST_CR3, state->crs[NVMM_X64_CR_CR3]); // XXX PDPTE?
+
+		/* XXX We are not handling PDPTE here. */
+		vmx_vmwrite(VMCS_GUEST_CR3, state->crs[NVMM_X64_CR_CR3]);
+
+		/* CR4_VMXE is mandatory. */
 		vmx_vmwrite(VMCS_GUEST_CR4,
 		(state->crs[NVMM_X64_CR_CR4] & CR4_VALID) | CR4_VMXE);
+
 		cpudata->gcr8 = state->crs[NVMM_X64_CR_CR8];
 
 		if (vmx_xcr0_mask != 0) {
@@ -2715,8 +2735,8 @@ vmx_vcpu_getstate(struct nvmm_cpu *vcpu)
 
 	if (flags & NVMM_X64_STATE_CRS) {
 		state->crs[NVMM_X64_CR_CR0] =
-		(vmx_vmread(VMCS_CR0_SHADOW) & CR0_STATIC) |
-		(vmx_vmread(VMCS_GUEST_CR0) & ~CR0_STATIC);
+		(vmx_vmread(VMCS_CR0_SHADOW) & CR0_STATIC_MASK) |
+		(vmx_vmread(VMCS_GUEST_CR0) & ~CR0_STATIC_MASK);
 		

CVS commit: src/sys/dev/nvmm/x86

2020-09-08 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Tue Sep  8 17:02:03 UTC 2020

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_svm.c nvmm_x86_vmx.c

Log Message:
nvmm-x86: avoid hogging behavior observed recently

When the FPU code got rewritten in NetBSD, the dependency on IPL_HIGH was
eliminated, and I took _vcpu_guest_fpu_enter() out of the VCPU loop since
there was no need to be in the splhigh window.

Later, the code was switched to use the kernel FPU API, API that works at
IPL_VM, not at IPL_NONE.

These two changes mean that the whole VCPU loop is now executing at IPL_VM,
which is not desired, because it introduces a delay in interrupt processing
on the host in certain cases.

Fix this by putting _vcpu_guest_fpu_enter() back inside the VCPU loop.


To generate a diff of this commit:
cvs rdiff -u -r1.80 -r1.81 src/sys/dev/nvmm/x86/nvmm_x86_svm.c
cvs rdiff -u -r1.79 -r1.80 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.80 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.81
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.80	Tue Sep  8 16:58:38 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Tue Sep  8 17:02:03 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.80 2020/09/08 16:58:38 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.81 2020/09/08 17:02:03 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 Maxime Villard, m00nbsd.net
@@ -29,7 +29,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.80 2020/09/08 16:58:38 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.81 2020/09/08 17:02:03 maxv Exp $");
 
 #include 
 #include 
@@ -1328,9 +1328,6 @@ svm_exit_xsetbv(struct nvmm_machine *mac
 	}
 
 	cpudata->gxcr0 = val;
-	if (svm_xcr0_mask != 0) {
-		wrxcr(0, cpudata->gxcr0);
-	}
 
 	svm_inkernel_advance(cpudata->vmcb);
 	return;
@@ -1516,7 +1513,6 @@ svm_vcpu_run(struct nvmm_machine *mach, 
 
 	svm_vcpu_guest_dbregs_enter(vcpu);
 	svm_vcpu_guest_misc_enter(vcpu);
-	svm_vcpu_guest_fpu_enter(vcpu);
 
 	while (1) {
 		if (cpudata->gtlb_want_flush) {
@@ -1530,11 +1526,13 @@ svm_vcpu_run(struct nvmm_machine *mach, 
 			svm_vmcb_cache_flush(vmcb, VMCB_CTRL_VMCB_CLEAN_I);
 		}
 
+		svm_vcpu_guest_fpu_enter(vcpu);
 		svm_clgi();
 		machgen = svm_htlb_flush(machdata, cpudata);
 		svm_vmrun(cpudata->vmcb_pa, cpudata->gprs);
 		svm_htlb_flush_ack(cpudata, machgen);
 		svm_stgi();
+		svm_vcpu_guest_fpu_leave(vcpu);
 
 		svm_vmcb_cache_default(vmcb);
 
@@ -1622,7 +1620,6 @@ svm_vcpu_run(struct nvmm_machine *mach, 
 
 	cpudata->gtsc = rdtsc() + vmcb->ctrl.tsc_offset;
 
-	svm_vcpu_guest_fpu_leave(vcpu);
 	svm_vcpu_guest_misc_leave(vcpu);
 	svm_vcpu_guest_dbregs_leave(vcpu);
 

Index: src/sys/dev/nvmm/x86/nvmm_x86_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.79 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.80
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.79	Tue Sep  8 17:00:07 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Tue Sep  8 17:02:03 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.79 2020/09/08 17:00:07 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.80 2020/09/08 17:02:03 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 Maxime Villard, m00nbsd.net
@@ -29,7 +29,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.79 2020/09/08 17:00:07 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.80 2020/09/08 17:02:03 maxv Exp $");
 
 #include 
 #include 
@@ -1969,9 +1969,6 @@ vmx_exit_xsetbv(struct nvmm_machine *mac
 	}
 
 	cpudata->gxcr0 = val;
-	if (vmx_xcr0_mask != 0) {
-		wrxcr(0, cpudata->gxcr0);
-	}
 
 	vmx_inkernel_advance();
 	return;
@@ -2228,7 +2225,6 @@ vmx_vcpu_run(struct nvmm_machine *mach, 
 
 	vmx_vcpu_guest_dbregs_enter(vcpu);
 	vmx_vcpu_guest_misc_enter(vcpu);
-	vmx_vcpu_guest_fpu_enter(vcpu);
 
 	while (1) {
 		if (cpudata->gtlb_want_flush) {
@@ -2243,6 +2239,7 @@ vmx_vcpu_run(struct nvmm_machine *mach, 
 			cpudata->gtsc_want_update = false;
 		}
 
+		vmx_vcpu_guest_fpu_enter(vcpu);
 		vmx_cli();
 		machgen = vmx_htlb_flush(machdata, cpudata);
 		lcr2(cpudata->gcr2);
@@ -2254,6 +2251,7 @@ vmx_vcpu_run(struct nvmm_machine *mach, 
 		cpudata->gcr2 = rcr2();
 		vmx_htlb_flush_ack(cpudata, machgen);
 		vmx_sti();
+		vmx_vcpu_guest_fpu_leave(vcpu);
 
 		if (__predict_false(ret != 0)) {
 			vmx_exit_invalid(exit, -1);
@@ -2349,7 +2347,6 @@ vmx_vcpu_run(struct nvmm_machine *mach, 
 
 	cpudata->gtsc = vmx_vmread(VMCS_TSC_OFFSET) + rdtsc();
 
-	vmx_vcpu_guest_fpu_leave(vcpu);
 	vmx_vcpu_guest_misc_leave(vcpu);
 	vmx_vcpu_guest_dbregs_leave(vcpu);
 



CVS commit: src/sys/dev/nvmm

2020-09-08 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Tue Sep  8 16:58:38 UTC 2020

Modified Files:
src/sys/dev/nvmm: nvmm.c nvmm_ioctl.h
src/sys/dev/nvmm/x86: nvmm_x86.c nvmm_x86_svm.c

Log Message:
nvmm: cosmetic changes

 - Style.
 - Explicitly include ioccom.h.


To generate a diff of this commit:
cvs rdiff -u -r1.40 -r1.41 src/sys/dev/nvmm/nvmm.c
cvs rdiff -u -r1.11 -r1.12 src/sys/dev/nvmm/nvmm_ioctl.h
cvs rdiff -u -r1.20 -r1.21 src/sys/dev/nvmm/x86/nvmm_x86.c
cvs rdiff -u -r1.79 -r1.80 src/sys/dev/nvmm/x86/nvmm_x86_svm.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/nvmm.c
diff -u src/sys/dev/nvmm/nvmm.c:1.40 src/sys/dev/nvmm/nvmm.c:1.41
--- src/sys/dev/nvmm/nvmm.c:1.40	Sat Sep  5 16:30:11 2020
+++ src/sys/dev/nvmm/nvmm.c	Tue Sep  8 16:58:38 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm.c,v 1.40 2020/09/05 16:30:11 riastradh Exp $	*/
+/*	$NetBSD: nvmm.c,v 1.41 2020/09/08 16:58:38 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 Maxime Villard, m00nbsd.net
@@ -29,7 +29,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.40 2020/09/05 16:30:11 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.41 2020/09/08 16:58:38 maxv Exp $");
 
 #include 
 #include 
@@ -1085,7 +1085,7 @@ nvmm_close(file_t *fp)
 	}
 	fp->f_data = NULL;
 
-   	return 0;
+	return 0;
 }
 
 static int

Index: src/sys/dev/nvmm/nvmm_ioctl.h
diff -u src/sys/dev/nvmm/nvmm_ioctl.h:1.11 src/sys/dev/nvmm/nvmm_ioctl.h:1.12
--- src/sys/dev/nvmm/nvmm_ioctl.h:1.11	Sat Sep  5 07:22:25 2020
+++ src/sys/dev/nvmm/nvmm_ioctl.h	Tue Sep  8 16:58:38 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_ioctl.h,v 1.11 2020/09/05 07:22:25 maxv Exp $	*/
+/*	$NetBSD: nvmm_ioctl.h,v 1.12 2020/09/08 16:58:38 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 Maxime Villard, m00nbsd.net
@@ -31,6 +31,7 @@
 #ifndef _NVMM_IOCTL_H_
 #define _NVMM_IOCTL_H_
 
+#include 
 #include 
 
 struct nvmm_ioc_capability {

Index: src/sys/dev/nvmm/x86/nvmm_x86.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86.c:1.20 src/sys/dev/nvmm/x86/nvmm_x86.c:1.21
--- src/sys/dev/nvmm/x86/nvmm_x86.c:1.20	Sun Sep  6 02:18:53 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86.c	Tue Sep  8 16:58:38 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86.c,v 1.20 2020/09/06 02:18:53 riastradh Exp $	*/
+/*	$NetBSD: nvmm_x86.c,v 1.21 2020/09/08 16:58:38 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 Maxime Villard, m00nbsd.net
@@ -29,7 +29,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86.c,v 1.20 2020/09/06 02:18:53 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86.c,v 1.21 2020/09/08 16:58:38 maxv Exp $");
 
 #include 
 #include 
@@ -405,7 +405,7 @@ const struct nvmm_x86_cpuid_mask nvmm_cp
 	CPUID_MPC |
 	CPUID_XD |
 	CPUID_MMXX |
-	CPUID_MMX | 
+	CPUID_MMX |
 	CPUID_FXSR |
 	CPUID_FFXSR |
 	CPUID_PAGE1GB |

Index: src/sys/dev/nvmm/x86/nvmm_x86_svm.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.79 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.80
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.79	Sun Sep  6 02:18:53 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Tue Sep  8 16:58:38 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.79 2020/09/06 02:18:53 riastradh Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.80 2020/09/08 16:58:38 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 Maxime Villard, m00nbsd.net
@@ -29,7 +29,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.79 2020/09/06 02:18:53 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.80 2020/09/08 16:58:38 maxv Exp $");
 
 #include 
 #include 
@@ -787,7 +787,7 @@ svm_inject_gp(struct nvmm_cpu *vcpu)
 	KASSERT(ret == 0);
 }
 
-static inline int 
+static inline int
 svm_vcpu_event_commit(struct nvmm_cpu *vcpu)
 {
 	if (__predict_true(!vcpu->comm->event_commit)) {



CVS commit: src/sys/dev/nvmm/x86

2020-09-04 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Fri Sep  4 17:09:03 UTC 2020

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86.c

Log Message:
nvmm-x86: improve the CPUID emulation

 - Mask DTES64, DS_CPL, CID, SDBG, xTPR, PN.
 - B10, B20 and IA64 do not exist, so just remove them.


To generate a diff of this commit:
cvs rdiff -u -r1.15 -r1.16 src/sys/dev/nvmm/x86/nvmm_x86.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.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86.c:1.15 src/sys/dev/nvmm/x86/nvmm_x86.c:1.16
--- src/sys/dev/nvmm/x86/nvmm_x86.c:1.15	Sat Aug 22 11:00:00 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86.c	Fri Sep  4 17:09:03 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86.c,v 1.15 2020/08/22 11:00:00 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86.c,v 1.16 2020/09/04 17:09:03 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86.c,v 1.15 2020/08/22 11:00:00 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86.c,v 1.16 2020/09/04 17:09:03 maxv Exp $");
 
 #include 
 #include 
@@ -235,19 +235,19 @@ const struct nvmm_x86_cpuid_mask nvmm_cp
 	.ecx =
 	CPUID2_SSE3 |
 	CPUID2_PCLMUL |
-	CPUID2_DTES64 |
+	/* CPUID2_DTES64 excluded */
 	/* CPUID2_MONITOR excluded */
-	CPUID2_DS_CPL |
+	/* CPUID2_DS_CPL excluded */
 	/* CPUID2_VMX excluded */
 	/* CPUID2_SMX excluded */
 	/* CPUID2_EST excluded */
 	/* CPUID2_TM2 excluded */
 	CPUID2_SSSE3 |
-	CPUID2_CID |
-	CPUID2_SDBG |
+	/* CPUID2_CID excluded */
+	/* CPUID2_SDBG excluded */
 	CPUID2_FMA |
 	CPUID2_CX16 |
-	CPUID2_xTPR |
+	/* CPUID2_xTPR excluded */
 	/* CPUID2_PDCM excluded */
 	/* CPUID2_PCID excluded, but re-included in VMX */
 	/* CPUID2_DCA excluded */
@@ -275,7 +275,6 @@ const struct nvmm_x86_cpuid_mask nvmm_cp
 	/* CPUID_MCE excluded */
 	CPUID_CX8 |
 	CPUID_APIC |
-	CPUID_B10 |	
 	CPUID_SEP |
 	/* CPUID_MTRR excluded */
 	CPUID_PGE |
@@ -283,9 +282,8 @@ const struct nvmm_x86_cpuid_mask nvmm_cp
 	CPUID_CMOV |
 	CPUID_PAT |
 	CPUID_PSE36 |
-	CPUID_PN |
+	/* CPUID_PN excluded */
 	CPUID_CFLUSH |
-	CPUID_B20 |
 	/* CPUID_DS excluded */
 	/* CPUID_ACPI excluded */
 	CPUID_MMX |
@@ -295,7 +293,6 @@ const struct nvmm_x86_cpuid_mask nvmm_cp
 	CPUID_SS |
 	CPUID_HTT |
 	/* CPUID_TM excluded */
-	CPUID_IA64 |
 	CPUID_SBF
 };
 



CVS commit: src/sys/dev/nvmm

2020-09-04 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Fri Sep  4 17:08:01 UTC 2020

Modified Files:
src/sys/dev/nvmm: nvmm.c

Log Message:
nvmm: more __read_mostly


To generate a diff of this commit:
cvs rdiff -u -r1.37 -r1.38 src/sys/dev/nvmm/nvmm.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/nvmm.c
diff -u src/sys/dev/nvmm/nvmm.c:1.37 src/sys/dev/nvmm/nvmm.c:1.38
--- src/sys/dev/nvmm/nvmm.c:1.37	Sat Aug 29 07:14:17 2020
+++ src/sys/dev/nvmm/nvmm.c	Fri Sep  4 17:08:01 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm.c,v 1.37 2020/08/29 07:14:17 maxv Exp $	*/
+/*	$NetBSD: nvmm.c,v 1.38 2020/09/04 17:08:01 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.37 2020/08/29 07:14:17 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.38 2020/09/04 17:08:01 maxv Exp $");
 
 #include 
 #include 
@@ -66,7 +66,7 @@ static const struct nvmm_impl *nvmm_impl
 #endif
 };
 
-static const struct nvmm_impl *nvmm_impl = NULL;
+static const struct nvmm_impl *nvmm_impl __read_mostly = NULL;
 
 static struct nvmm_owner root_owner;
 



CVS commit: src/sys/dev/nvmm/x86

2020-09-04 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Fri Sep  4 17:07:33 UTC 2020

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_vmx.c

Log Message:
nvmm-x86-vmx: improve the handling of CR0

 - Flush the guest TLB when certain CR0 bits change.
 - If the guest updates a static bit in CR0, then reflect the change in
   VMCS_CR0_SHADOW, for the guest to get the illusion that the change was
   applied. The "real" CR0 static bits remain unchanged.
 - In vmx_vcpu_{g,s}et_state(), take VMCS_CR0_SHADOW into account.
 - Slightly modify the CR4 handling code, just for more symmetry with CR0.


To generate a diff of this commit:
cvs rdiff -u -r1.74 -r1.75 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_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.74 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.75
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.74	Wed Aug 26 16:32:02 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Fri Sep  4 17:07:33 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.74 2020/08/26 16:32:02 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.75 2020/09/04 17:07:33 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.74 2020/08/26 16:32:02 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.75 2020/09/04 17:07:33 maxv Exp $");
 
 #include 
 #include 
@@ -729,6 +729,9 @@ static uint64_t vmx_xcr0_mask __read_mos
 #define MSRBM_NPAGES	1
 #define MSRBM_SIZE	(MSRBM_NPAGES * PAGE_SIZE)
 
+#define CR0_STATIC \
+	(CR0_NW|CR0_CD|CR0_ET)
+
 #define CR4_VALID \
 	(CR4_VME |			\
 	 CR4_PVI |			\
@@ -1570,7 +1573,7 @@ vmx_inkernel_handle_cr0(struct nvmm_mach
 uint64_t qual)
 {
 	struct vmx_cpudata *cpudata = vcpu->cpudata;
-	uint64_t type, gpr, cr0;
+	uint64_t type, gpr, oldcr0, cr0;
 	uint64_t efer, ctls1;
 
 	type = __SHIFTOUT(qual, VMX_QUAL_CR_TYPE);
@@ -1613,6 +1616,13 @@ vmx_inkernel_handle_cr0(struct nvmm_mach
 		vmx_vmwrite(VMCS_ENTRY_CTLS, ctls1);
 	}
 
+	oldcr0 = (vmx_vmread(VMCS_CR0_SHADOW) & CR0_STATIC) |
+	(vmx_vmread(VMCS_GUEST_CR0) & ~CR0_STATIC);
+	if ((oldcr0 ^ gpr) & CR0_TLB_FLUSH) {
+		cpudata->gtlb_want_flush = true;
+	}
+
+	vmx_vmwrite(VMCS_CR0_SHADOW, gpr);
 	vmx_vmwrite(VMCS_GUEST_CR0, cr0);
 	vmx_inkernel_advance();
 	return 0;
@@ -1623,7 +1633,7 @@ vmx_inkernel_handle_cr4(struct nvmm_mach
 uint64_t qual)
 {
 	struct vmx_cpudata *cpudata = vcpu->cpudata;
-	uint64_t type, gpr, cr4;
+	uint64_t type, gpr, oldcr4, cr4;
 
 	type = __SHIFTOUT(qual, VMX_QUAL_CR_TYPE);
 	if (type != CR_TYPE_WRITE) {
@@ -1647,7 +1657,8 @@ vmx_inkernel_handle_cr4(struct nvmm_mach
 		return -1;
 	}
 
-	if ((vmx_vmread(VMCS_GUEST_CR4) ^ cr4) & CR4_TLB_FLUSH) {
+	oldcr4 = vmx_vmread(VMCS_GUEST_CR4);
+	if ((oldcr4 ^ gpr) & CR4_TLB_FLUSH) {
 		cpudata->gtlb_want_flush = true;
 	}
 
@@ -2566,6 +2577,7 @@ vmx_vcpu_setstate(struct nvmm_cpu *vcpu)
 		/*
 		 * CR0_NE and CR4_VMXE are mandatory.
 		 */
+		vmx_vmwrite(VMCS_CR0_SHADOW, state->crs[NVMM_X64_CR_CR0]);
 		vmx_vmwrite(VMCS_GUEST_CR0,
 		state->crs[NVMM_X64_CR_CR0] | CR0_NE);
 		cpudata->gcr2 = state->crs[NVMM_X64_CR_CR2];
@@ -2703,7 +2715,9 @@ vmx_vcpu_getstate(struct nvmm_cpu *vcpu)
 	}
 
 	if (flags & NVMM_X64_STATE_CRS) {
-		state->crs[NVMM_X64_CR_CR0] = vmx_vmread(VMCS_GUEST_CR0);
+		state->crs[NVMM_X64_CR_CR0] =
+		(vmx_vmread(VMCS_CR0_SHADOW) & CR0_STATIC) |
+		(vmx_vmread(VMCS_GUEST_CR0) & ~CR0_STATIC);
 		state->crs[NVMM_X64_CR_CR2] = cpudata->gcr2;
 		state->crs[NVMM_X64_CR_CR3] = vmx_vmread(VMCS_GUEST_CR3);
 		state->crs[NVMM_X64_CR_CR4] = vmx_vmread(VMCS_GUEST_CR4);
@@ -2892,9 +2906,8 @@ vmx_vcpu_init(struct nvmm_machine *mach,
 	vmx_vmwrite(VMCS_ENTRY_MSR_LOAD_COUNT, vmx_msrlist_entry_nmsr);
 	vmx_vmwrite(VMCS_EXIT_MSR_STORE_COUNT, VMX_MSRLIST_EXIT_NMSR);
 
-	/* Force CR0_NW and CR0_CD to zero, CR0_ET to one. */
-	vmx_vmwrite(VMCS_CR0_MASK, CR0_NW|CR0_CD|CR0_ET);
-	vmx_vmwrite(VMCS_CR0_SHADOW, CR0_ET);
+	/* Set the CR0 mask. Any change of these bits causes a VMEXIT. */
+	vmx_vmwrite(VMCS_CR0_MASK, CR0_STATIC);
 
 	/* Force unsupported CR4 fields to zero. */
 	vmx_vmwrite(VMCS_CR4_MASK, CR4_INVALID);



CVS commit: src/sys/dev/nvmm/x86

2020-09-04 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Fri Sep  4 17:06:23 UTC 2020

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_svm.c

Log Message:
nvmm-x86-svm: check the SVM revision

Only revision 1 exists, but check it, for future-proofness.


To generate a diff of this commit:
cvs rdiff -u -r1.74 -r1.75 src/sys/dev/nvmm/x86/nvmm_x86_svm.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.74 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.75
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.74	Wed Aug 26 16:33:03 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Fri Sep  4 17:06:23 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.74 2020/08/26 16:33:03 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.75 2020/09/04 17:06:23 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.74 2020/08/26 16:33:03 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.75 2020/09/04 17:06:23 maxv Exp $");
 
 #include 
 #include 
@@ -2445,6 +2445,12 @@ svm_ident(void)
 	}
 	x86_cpuid(0x800a, descs);
 
+	/* Expect revision 1. */
+	if (__SHIFTOUT(descs[0], CPUID_AMD_SVM_REV) != 1) {
+		printf("NVMM: SVM revision not supported\n");
+		return false;
+	}
+
 	/* Want Nested Paging. */
 	if (!(descs[3] & CPUID_AMD_SVM_NP)) {
 		printf("NVMM: SVM-NP not supported\n");



CVS commit: src/sys/dev/nvmm

2020-08-29 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Sat Aug 29 07:14:17 UTC 2020

Modified Files:
src/sys/dev/nvmm: nvmm.c

Log Message:
nvmm: explicitly include atomic.h


To generate a diff of this commit:
cvs rdiff -u -r1.36 -r1.37 src/sys/dev/nvmm/nvmm.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/nvmm.c
diff -u src/sys/dev/nvmm/nvmm.c:1.36 src/sys/dev/nvmm/nvmm.c:1.37
--- src/sys/dev/nvmm/nvmm.c:1.36	Wed Aug 26 16:28:17 2020
+++ src/sys/dev/nvmm/nvmm.c	Sat Aug 29 07:14:17 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm.c,v 1.36 2020/08/26 16:28:17 maxv Exp $	*/
+/*	$NetBSD: nvmm.c,v 1.37 2020/08/29 07:14:17 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,12 +30,13 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.36 2020/08/26 16:28:17 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.37 2020/08/29 07:14:17 maxv Exp $");
 
 #include 
 #include 
 #include 
 
+#include 
 #include 
 #include 
 #include 



CVS commit: src/sys/dev/nvmm/x86

2020-08-26 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Wed Aug 26 16:33:03 UTC 2020

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_svm.c

Log Message:
nvmm-x86-svm: improve the handling of MSR_EFER

Intercept reads of it as well, just to mask EFER_SVME, which the guest
doesn't need to see.


To generate a diff of this commit:
cvs rdiff -u -r1.73 -r1.74 src/sys/dev/nvmm/x86/nvmm_x86_svm.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.73 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.74
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.73	Wed Aug 26 16:32:02 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Wed Aug 26 16:33:03 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.73 2020/08/26 16:32:02 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.74 2020/08/26 16:33:03 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.73 2020/08/26 16:32:02 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.74 2020/08/26 16:33:03 maxv Exp $");
 
 #include 
 #include 
@@ -1170,6 +1170,12 @@ svm_inkernel_handle_msr(struct nvmm_mach
 	size_t i;
 
 	if (exit->reason == NVMM_VCPU_EXIT_RDMSR) {
+		if (exit->u.rdmsr.msr == MSR_EFER) {
+			val = vmcb->state.efer & ~EFER_SVME;
+			vmcb->state.rax = (val & 0x);
+			cpudata->gprs[NVMM_X64_GPR_RDX] = (val >> 32);
+			goto handled;
+		}
 		if (exit->u.rdmsr.msr == MSR_NB_CFG) {
 			val = NB_CFG_INITAPICCPUIDLO;
 			vmcb->state.rax = (val & 0x);
@@ -2195,7 +2201,6 @@ svm_vcpu_init(struct nvmm_machine *mach,
 
 	/* Allow direct access to certain MSRs. */
 	memset(cpudata->msrbm, 0xFF, MSRBM_SIZE);
-	svm_vcpu_msr_allow(cpudata->msrbm, MSR_EFER, true, false);
 	svm_vcpu_msr_allow(cpudata->msrbm, MSR_STAR, true, true);
 	svm_vcpu_msr_allow(cpudata->msrbm, MSR_LSTAR, true, true);
 	svm_vcpu_msr_allow(cpudata->msrbm, MSR_CSTAR, true, true);



CVS commit: src/sys/dev/nvmm/x86

2020-08-26 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Wed Aug 26 16:32:03 UTC 2020

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_svm.c nvmm_x86_vmx.c

Log Message:
nvmm-x86: improve the handling of RFLAGS.RF

 - When injecting certain exceptions, set RF. For us to have an up-to-date
   view of RFLAGS, we commit the state before the event.
 - When advancing RIP, clear RF.


To generate a diff of this commit:
cvs rdiff -u -r1.72 -r1.73 src/sys/dev/nvmm/x86/nvmm_x86_svm.c
cvs rdiff -u -r1.73 -r1.74 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.72 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.73
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.72	Wed Aug 26 16:29:19 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Wed Aug 26 16:32:02 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.72 2020/08/26 16:29:19 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.73 2020/08/26 16:32:02 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.72 2020/08/26 16:29:19 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.73 2020/08/26 16:32:02 maxv Exp $");
 
 #include 
 #include 
@@ -676,8 +676,22 @@ svm_event_waitexit_disable(struct nvmm_c
 	svm_vmcb_cache_flush(vmcb, VMCB_CTRL_VMCB_CLEAN_I);
 }
 
+static inline bool
+svm_excp_has_rf(uint8_t vector)
+{
+	switch (vector) {
+	case 1:		/* #DB */
+	case 4:		/* #OF */
+	case 8:		/* #DF */
+	case 18:	/* #MC */
+		return false;
+	default:
+		return true;
+	}
+}
+
 static inline int
-svm_event_has_error(uint8_t vector)
+svm_excp_has_error(uint8_t vector)
 {
 	switch (vector) {
 	case 8:		/* #DF */
@@ -717,7 +731,10 @@ svm_vcpu_inject(struct nvmm_cpu *vcpu)
 			return EINVAL;
 		if (vector == 3 || vector == 0)
 			return EINVAL;
-		err = svm_event_has_error(vector);
+		if (svm_excp_has_rf(vector)) {
+			vmcb->state.rflags |= PSL_RF;
+		}
+		err = svm_excp_has_error(vector);
 		break;
 	case NVMM_VCPU_EVENT_INTR:
 		type = SVM_EVENT_TYPE_HW_INT;
@@ -790,6 +807,7 @@ svm_inkernel_advance(struct vmcb *vmcb)
 	 * debugger.
 	 */
 	vmcb->state.rip = vmcb->ctrl.nrip;
+	vmcb->state.rflags &= ~PSL_RF;
 	vmcb->ctrl.intr &= ~VMCB_CTRL_INTR_SHADOW;
 }
 
@@ -1473,11 +1491,12 @@ svm_vcpu_run(struct nvmm_machine *mach, 
 	uint64_t machgen;
 	int hcpu;
 
+	svm_vcpu_state_commit(vcpu);
+	comm->state_cached = 0;
+
 	if (__predict_false(svm_vcpu_event_commit(vcpu) != 0)) {
 		return EINVAL;
 	}
-	svm_vcpu_state_commit(vcpu);
-	comm->state_cached = 0;
 
 	kpreempt_disable();
 	hcpu = cpu_number();

Index: src/sys/dev/nvmm/x86/nvmm_x86_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.73 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.74
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.73	Wed Aug 26 16:30:50 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Wed Aug 26 16:32:02 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.73 2020/08/26 16:30:50 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.74 2020/08/26 16:32:02 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.73 2020/08/26 16:30:50 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.74 2020/08/26 16:32:02 maxv Exp $");
 
 #include 
 #include 
@@ -1038,8 +1038,22 @@ vmx_event_waitexit_disable(struct nvmm_c
 	vmx_vmwrite(VMCS_PROCBASED_CTLS, ctls1);
 }
 
+static inline bool
+vmx_excp_has_rf(uint8_t vector)
+{
+	switch (vector) {
+	case 1:		/* #DB */
+	case 4:		/* #OF */
+	case 8:		/* #DF */
+	case 18:	/* #MC */
+		return false;
+	default:
+		return true;
+	}
+}
+
 static inline int
-vmx_event_has_error(uint8_t vector)
+vmx_excp_has_error(uint8_t vector)
 {
 	switch (vector) {
 	case 8:		/* #DF */
@@ -1062,9 +1076,9 @@ vmx_vcpu_inject(struct nvmm_cpu *vcpu)
 	struct nvmm_comm_page *comm = vcpu->comm;
 	struct vmx_cpudata *cpudata = vcpu->cpudata;
 	int type = 0, err = 0, ret = EINVAL;
+	uint64_t rflags, info, error;
 	u_int evtype;
 	uint8_t vector;
-	uint64_t info, error;
 
 	evtype = comm->event.type;
 	vector = comm->event.vector;
@@ -1079,8 +1093,12 @@ vmx_vcpu_inject(struct nvmm_cpu *vcpu)
 			goto out;
 		if (vector == 3 || vector == 0)
 			goto out;
+		if (vmx_excp_has_rf(vector)) {
+			rflags = vmx_vmread(VMCS_GUEST_RFLAGS);
+			vmx_vmwrite(VMCS_GUEST_RFLAGS, rflags | PSL_RF);
+		}
 		type = INTR_TYPE_HW_EXC;
-		err = vmx_event_has_error(vector);
+		err = vmx_excp_has_error(vector);
 		break;
 	case NVMM_VCPU_EVENT_INTR:
 		type = INTR_TYPE_EXT_INT;
@@ -1151,16 +1169,21 @@ vmx_vcpu_event_commit(struct nvmm_cpu *v
 static inline void
 vmx_inkernel_advance(void)
 {
-	uint64_t rip, inslen, intstate;
+	uint64_t rip, inslen, intstate, rflags;
 
 	/*
 	 * Maybe we should also apply single-stepping and debug exceptions.
 	 * Matters for 

CVS commit: src/sys/dev/nvmm/x86

2020-08-26 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Wed Aug 26 16:30:50 UTC 2020

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_vmx.c

Log Message:
nvmm-x86-vmx: improve the handling of CR4

 - Filter out certain features we don't want the guest to enable. This is
   for general correctness, and future-proofness.
 - Flush the guest TLB when certain flags change.


To generate a diff of this commit:
cvs rdiff -u -r1.72 -r1.73 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_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.72 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.73
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.72	Sat Aug 22 11:01:10 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Wed Aug 26 16:30:50 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.72 2020/08/22 11:01:10 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.73 2020/08/26 16:30:50 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.72 2020/08/22 11:01:10 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.73 2020/08/26 16:30:50 maxv Exp $");
 
 #include 
 #include 
@@ -729,6 +729,33 @@ static uint64_t vmx_xcr0_mask __read_mos
 #define MSRBM_NPAGES	1
 #define MSRBM_SIZE	(MSRBM_NPAGES * PAGE_SIZE)
 
+#define CR4_VALID \
+	(CR4_VME |			\
+	 CR4_PVI |			\
+	 CR4_TSD |			\
+	 CR4_DE |			\
+	 CR4_PSE |			\
+	 CR4_PAE |			\
+	 CR4_MCE |			\
+	 CR4_PGE |			\
+	 CR4_PCE |			\
+	 CR4_OSFXSR |			\
+	 CR4_OSXMMEXCPT |		\
+	 CR4_UMIP |			\
+	 /* CR4_LA57 excluded */	\
+	 /* CR4_VMXE excluded */	\
+	 /* CR4_SMXE excluded */	\
+	 CR4_FSGSBASE |			\
+	 CR4_PCIDE |			\
+	 CR4_OSXSAVE |			\
+	 CR4_SMEP |			\
+	 CR4_SMAP			\
+	 /* CR4_PKE excluded */		\
+	 /* CR4_CET excluded */		\
+	 /* CR4_PKS excluded */)
+#define CR4_INVALID \
+	(0xULL & ~CR4_VALID)
+
 #define EFER_TLB_FLUSH \
 	(EFER_NXE|EFER_LMA|EFER_LME)
 #define CR0_TLB_FLUSH \
@@ -1589,12 +1616,18 @@ vmx_inkernel_handle_cr4(struct nvmm_mach
 		gpr = cpudata->gprs[gpr];
 	}
 
+	if (gpr & CR4_INVALID) {
+		return -1;
+	}
 	cr4 = gpr | CR4_VMXE;
-
 	if (vmx_check_cr(cr4, vmx_cr4_fixed0, vmx_cr4_fixed1) == -1) {
 		return -1;
 	}
 
+	if ((vmx_vmread(VMCS_GUEST_CR4) ^ cr4) & CR4_TLB_FLUSH) {
+		cpudata->gtlb_want_flush = true;
+	}
+
 	vmx_vmwrite(VMCS_GUEST_CR4, cr4);
 	vmx_inkernel_advance();
 	return 0;
@@ -2514,7 +2547,7 @@ vmx_vcpu_setstate(struct nvmm_cpu *vcpu)
 		cpudata->gcr2 = state->crs[NVMM_X64_CR_CR2];
 		vmx_vmwrite(VMCS_GUEST_CR3, state->crs[NVMM_X64_CR_CR3]); // XXX PDPTE?
 		vmx_vmwrite(VMCS_GUEST_CR4,
-		state->crs[NVMM_X64_CR_CR4] | CR4_VMXE);
+		(state->crs[NVMM_X64_CR_CR4] & CR4_VALID) | CR4_VMXE);
 		cpudata->gcr8 = state->crs[NVMM_X64_CR_CR8];
 
 		if (vmx_xcr0_mask != 0) {
@@ -2839,8 +2872,9 @@ vmx_vcpu_init(struct nvmm_machine *mach,
 	vmx_vmwrite(VMCS_CR0_MASK, CR0_NW|CR0_CD|CR0_ET);
 	vmx_vmwrite(VMCS_CR0_SHADOW, CR0_ET);
 
-	/* Force CR4_VMXE to zero. */
-	vmx_vmwrite(VMCS_CR4_MASK, CR4_VMXE);
+	/* Force unsupported CR4 fields to zero. */
+	vmx_vmwrite(VMCS_CR4_MASK, CR4_INVALID);
+	vmx_vmwrite(VMCS_CR4_SHADOW, 0);
 
 	/* Set the Host state for resuming. */
 	vmx_vmwrite(VMCS_HOST_RIP, (uint64_t)_resume_rip);



CVS commit: src/sys/dev/nvmm

2020-08-26 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Wed Aug 26 16:29:49 UTC 2020

Modified Files:
src/sys/dev/nvmm: nvmm_ioctl.h

Log Message:
nvmm: slightly clarify


To generate a diff of this commit:
cvs rdiff -u -r1.9 -r1.10 src/sys/dev/nvmm/nvmm_ioctl.h

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/nvmm_ioctl.h
diff -u src/sys/dev/nvmm/nvmm_ioctl.h:1.9 src/sys/dev/nvmm/nvmm_ioctl.h:1.10
--- src/sys/dev/nvmm/nvmm_ioctl.h:1.9	Mon Oct 28 09:00:08 2019
+++ src/sys/dev/nvmm/nvmm_ioctl.h	Wed Aug 26 16:29:49 2020
@@ -1,7 +1,7 @@
-/*	$NetBSD: nvmm_ioctl.h,v 1.9 2019/10/28 09:00:08 maxv Exp $	*/
+/*	$NetBSD: nvmm_ioctl.h,v 1.10 2020/08/26 16:29:49 maxv Exp $	*/
 
 /*
- * Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
+ * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -121,7 +121,9 @@ struct nvmm_ioc_gpa_unmap {
 };
 
 struct nvmm_ctl_mach_info {
+	/* input */
 	nvmm_machid_t machid;
+	/* output */
 	uint32_t nvcpus;
 	uint64_t nram;
 	pid_t pid;
@@ -151,7 +153,6 @@ struct nvmm_ioc_ctl {
 #define NVMM_IOC_GPA_UNMAP		_IOW ('N', 12, struct nvmm_ioc_gpa_unmap)
 #define NVMM_IOC_HVA_MAP		_IOW ('N', 13, struct nvmm_ioc_hva_map)
 #define NVMM_IOC_HVA_UNMAP		_IOW ('N', 14, struct nvmm_ioc_hva_unmap)
-
 #define NVMM_IOC_CTL			_IOW ('N', 20, struct nvmm_ioc_ctl)
 
 #endif /* _NVMM_IOCTL_H_ */



CVS commit: src/sys/dev/nvmm/x86

2020-08-26 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Wed Aug 26 16:29:20 UTC 2020

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_svm.c

Log Message:
nvmm-x86-svm: don't forget to intercept INVD

INVD executed in the guest can be dangerous for the host, due to CPU
caches being flushed without write-back.


To generate a diff of this commit:
cvs rdiff -u -r1.71 -r1.72 src/sys/dev/nvmm/x86/nvmm_x86_svm.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.71 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.72
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.71	Sat Aug 22 10:59:05 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Wed Aug 26 16:29:19 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.71 2020/08/22 10:59:05 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.72 2020/08/26 16:29:19 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.71 2020/08/22 10:59:05 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.72 2020/08/26 16:29:19 maxv Exp $");
 
 #include 
 #include 
@@ -2118,7 +2118,6 @@ svm_vcpu_init(struct nvmm_machine *mach,
 	 *  - POPF [popf instruction]
 	 *  - IRET [iret instruction]
 	 *  - INTN [int $n instructions]
-	 *  - INVD [invd instruction]
 	 *  - PAUSE [pause instruction]
 	 *  - INVLPG [invplg instruction]
 	 *  - TASKSW [task switches]
@@ -2132,6 +2131,7 @@ svm_vcpu_init(struct nvmm_machine *mach,
 	VMCB_CTRL_INTERCEPT_RDPMC |
 	VMCB_CTRL_INTERCEPT_CPUID |
 	VMCB_CTRL_INTERCEPT_RSM |
+	VMCB_CTRL_INTERCEPT_INVD |
 	VMCB_CTRL_INTERCEPT_HLT |
 	VMCB_CTRL_INTERCEPT_INVLPGA |
 	VMCB_CTRL_INTERCEPT_IOIO_PROT |



CVS commit: src/sys/dev/nvmm

2020-08-26 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Wed Aug 26 16:28:17 UTC 2020

Modified Files:
src/sys/dev/nvmm: nvmm.c

Log Message:
nvmm: misc improvements

 - use mach->ncpus to get the number of vcpus, now that we have it
 - don't forget to decrement mach->ncpus when a machine gets killed
 - add more __predict_false()


To generate a diff of this commit:
cvs rdiff -u -r1.35 -r1.36 src/sys/dev/nvmm/nvmm.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/nvmm.c
diff -u src/sys/dev/nvmm/nvmm.c:1.35 src/sys/dev/nvmm/nvmm.c:1.36
--- src/sys/dev/nvmm/nvmm.c:1.35	Tue Aug 18 17:04:37 2020
+++ src/sys/dev/nvmm/nvmm.c	Wed Aug 26 16:28:17 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm.c,v 1.35 2020/08/18 17:04:37 maxv Exp $	*/
+/*	$NetBSD: nvmm.c,v 1.36 2020/08/26 16:28:17 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.35 2020/08/18 17:04:37 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.36 2020/08/26 16:28:17 maxv Exp $");
 
 #include 
 #include 
@@ -112,17 +112,17 @@ nvmm_machine_get(struct nvmm_owner *owne
 	struct nvmm_machine *mach;
 	krw_t op = writer ? RW_WRITER : RW_READER;
 
-	if (machid >= NVMM_MAX_MACHINES) {
+	if (__predict_false(machid >= NVMM_MAX_MACHINES)) {
 		return EINVAL;
 	}
 	mach = [machid];
 
 	rw_enter(>lock, op);
-	if (!mach->present) {
+	if (__predict_false(!mach->present)) {
 		rw_exit(>lock);
 		return ENOENT;
 	}
-	if (owner != _owner && mach->owner != owner) {
+	if (__predict_false(mach->owner != owner && owner != _owner)) {
 		rw_exit(>lock);
 		return EPERM;
 	}
@@ -179,13 +179,13 @@ nvmm_vcpu_get(struct nvmm_machine *mach,
 {
 	struct nvmm_cpu *vcpu;
 
-	if (cpuid >= NVMM_MAX_VCPUS) {
+	if (__predict_false(cpuid >= NVMM_MAX_VCPUS)) {
 		return EINVAL;
 	}
 	vcpu = >cpus[cpuid];
 
 	mutex_enter(>lock);
-	if (!vcpu->present) {
+	if (__predict_false(!vcpu->present)) {
 		mutex_exit(>lock);
 		return ENOENT;
 	}
@@ -227,6 +227,7 @@ nvmm_kill_machines(struct nvmm_owner *ow
 			(*nvmm_impl->vcpu_destroy)(mach, vcpu);
 			nvmm_vcpu_free(mach, vcpu);
 			nvmm_vcpu_put(vcpu);
+			atomic_dec_uint(>ncpus);
 		}
 		(*nvmm_impl->machine_destroy)(mach);
 		uvmspace_free(mach->vm);
@@ -314,6 +315,7 @@ nvmm_machine_destroy(struct nvmm_owner *
 		(*nvmm_impl->vcpu_destroy)(mach, vcpu);
 		nvmm_vcpu_free(mach, vcpu);
 		nvmm_vcpu_put(vcpu);
+		atomic_dec_uint(>ncpus);
 	}
 
 	(*nvmm_impl->machine_destroy)(mach);
@@ -414,7 +416,6 @@ nvmm_vcpu_create(struct nvmm_owner *owne
 	}
 
 	nvmm_vcpu_put(vcpu);
-
 	atomic_inc_uint(>ncpus);
 
 out:
@@ -440,7 +441,6 @@ nvmm_vcpu_destroy(struct nvmm_owner *own
 	(*nvmm_impl->vcpu_destroy)(mach, vcpu);
 	nvmm_vcpu_free(mach, vcpu);
 	nvmm_vcpu_put(vcpu);
-
 	atomic_dec_uint(>ncpus);
 
 out:
@@ -907,7 +907,6 @@ nvmm_ctl_mach_info(struct nvmm_owner *ow
 {
 	struct nvmm_ctl_mach_info ctl;
 	struct nvmm_machine *mach;
-	struct nvmm_cpu *vcpu;
 	int error;
 	size_t i;
 
@@ -921,14 +920,7 @@ nvmm_ctl_mach_info(struct nvmm_owner *ow
 	if (error)
 		return error;
 
-	ctl.nvcpus = 0;
-	for (i = 0; i < NVMM_MAX_VCPUS; i++) {
-		error = nvmm_vcpu_get(mach, i, );
-		if (error)
-			continue;
-		ctl.nvcpus++;
-		nvmm_vcpu_put(vcpu);
-	}
+	ctl.nvcpus = mach->ncpus;
 
 	ctl.nram = 0;
 	for (i = 0; i < NVMM_MAX_HMAPPINGS; i++) {



CVS commit: src/sys/dev/nvmm/x86

2020-08-22 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Sat Aug 22 11:01:10 UTC 2020

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_vmx.c

Log Message:
nvmm-x86-vmx: fix detection of the BIOS lock

If it's locked, ensure it's locked with VMX enabled. If it's not locked,
then lock it ourselves with VMX enabled.

Should fix NetBSD PR/55596.


To generate a diff of this commit:
cvs rdiff -u -r1.71 -r1.72 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_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.71 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.72
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.71	Thu Aug 20 11:09:56 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Sat Aug 22 11:01:10 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.71 2020/08/20 11:09:56 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.72 2020/08/22 11:01:10 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.71 2020/08/20 11:09:56 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.72 2020/08/22 11:01:10 maxv Exp $");
 
 #include 
 #include 
@@ -3192,11 +3192,8 @@ vmx_ident(void)
 	}
 
 	msr = rdmsr(MSR_IA32_FEATURE_CONTROL);
-	if ((msr & IA32_FEATURE_CONTROL_LOCK) == 0) {
-		printf("NVMM: VMX disabled in BIOS\n");
-		return false;
-	}
-	if ((msr & IA32_FEATURE_CONTROL_OUT_SMX) == 0) {
+	if ((msr & IA32_FEATURE_CONTROL_LOCK) != 0 &&
+	(msr & IA32_FEATURE_CONTROL_OUT_SMX) == 0) {
 		printf("NVMM: VMX disabled in BIOS\n");
 		return false;
 	}
@@ -3322,7 +3319,17 @@ vmx_change_cpu(void *arg1, void *arg2)
 {
 	struct cpu_info *ci = curcpu();
 	bool enable = arg1 != NULL;
-	uint64_t cr4;
+	uint64_t msr, cr4;
+
+	if (enable) {
+		msr = rdmsr(MSR_IA32_FEATURE_CONTROL);
+		if ((msr & IA32_FEATURE_CONTROL_LOCK) == 0) {
+			/* Lock now, with VMX-outside-SMX enabled. */
+			wrmsr(MSR_IA32_FEATURE_CONTROL, msr |
+			IA32_FEATURE_CONTROL_LOCK |
+			IA32_FEATURE_CONTROL_OUT_SMX);
+		}
+	}
 
 	if (!enable) {
 		vmx_vmxoff();



CVS commit: src/sys/dev/nvmm/x86

2020-08-22 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Sat Aug 22 11:00:01 UTC 2020

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86.c

Log Message:
nvmm-x86: hide more CPUID flags, mostly related to perf monitors


To generate a diff of this commit:
cvs rdiff -u -r1.14 -r1.15 src/sys/dev/nvmm/x86/nvmm_x86.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.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86.c:1.14 src/sys/dev/nvmm/x86/nvmm_x86.c:1.15
--- src/sys/dev/nvmm/x86/nvmm_x86.c:1.14	Thu Aug 20 11:09:56 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86.c	Sat Aug 22 11:00:00 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86.c,v 1.14 2020/08/20 11:09:56 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86.c,v 1.15 2020/08/22 11:00:00 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86.c,v 1.14 2020/08/20 11:09:56 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86.c,v 1.15 2020/08/22 11:00:00 maxv Exp $");
 
 #include 
 #include 
@@ -389,22 +389,22 @@ const struct nvmm_x86_cpuid_mask nvmm_cp
 	CPUID_MISALIGNSSE |
 	CPUID_3DNOWPF |
 	/* CPUID_OSVW excluded */
-	CPUID_IBS |
+	/* CPUID_IBS excluded */
 	CPUID_XOP |
 	/* CPUID_SKINIT excluded */
-	CPUID_WDT |
-	CPUID_LWP |
+	/* CPUID_WDT excluded */
+	/* CPUID_LWP excluded */
 	CPUID_FMA4 |
 	CPUID_TCE |
-	CPUID_NODEID |
+	/* CPUID_NODEID excluded */
 	CPUID_TBM |
-	CPUID_TOPOEXT |
-	CPUID_PCEC |
-	CPUID_PCENB |
-	CPUID_SPM |
-	CPUID_DBE |
-	CPUID_PTSC |
-	CPUID_L2IPERFC,
+	CPUID_TOPOEXT,
+	/* CPUID_PCEC excluded */
+	/* CPUID_PCENB excluded */
+	/* CPUID_SPM excluded */
+	/* CPUID_DBE excluded */
+	/* CPUID_PTSC excluded */
+	/* CPUID_L2IPERFC excluded */
 	/* CPUID_MWAITX excluded */
 	.edx =
 	CPUID_SYSCALL |



CVS commit: src/sys/dev/nvmm/x86

2020-08-22 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Sat Aug 22 10:59:05 UTC 2020

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_svm.c

Log Message:
nvmm-x86-svm: dedup code


To generate a diff of this commit:
cvs rdiff -u -r1.70 -r1.71 src/sys/dev/nvmm/x86/nvmm_x86_svm.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.70 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.71
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.70	Thu Aug 20 11:09:56 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Sat Aug 22 10:59:05 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.70 2020/08/20 11:09:56 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.71 2020/08/22 10:59:05 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.70 2020/08/20 11:09:56 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.71 2020/08/22 10:59:05 maxv Exp $");
 
 #include 
 #include 
@@ -1022,18 +1022,11 @@ svm_exit_cpuid(struct nvmm_machine *mach
 	struct svm_cpudata *cpudata = vcpu->cpudata;
 	struct nvmm_vcpu_conf_cpuid *cpuid;
 	uint64_t eax, ecx;
-	u_int descs[4];
 	size_t i;
 
 	eax = cpudata->vmcb->state.rax;
 	ecx = cpudata->gprs[NVMM_X64_GPR_RCX];
-	x86_cpuid2(eax, ecx, descs);
-
-	cpudata->vmcb->state.rax = descs[0];
-	cpudata->gprs[NVMM_X64_GPR_RBX] = descs[1];
-	cpudata->gprs[NVMM_X64_GPR_RCX] = descs[2];
-	cpudata->gprs[NVMM_X64_GPR_RDX] = descs[3];
-
+	svm_inkernel_exec_cpuid(cpudata, eax, ecx);
 	svm_inkernel_handle_cpuid(vcpu, eax, ecx);
 
 	for (i = 0; i < SVM_NCPUIDS; i++) {



CVS commit: src/sys/dev/nvmm/x86

2020-08-20 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Thu Aug 20 11:09:56 UTC 2020

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86.c nvmm_x86.h nvmm_x86_svm.c
nvmm_x86_vmx.c

Log Message:
nvmm-x86: improve the CPUID emulation

 - x86-svm: explicitly handle 0x8007 and 0x8008. The latter
   contains extended features we must filter out. Apply the same in
   x86-vmx for symmetry.
 - x86-svm: explicitly handle extended leaves until 0x801F, and
   truncate to it.


To generate a diff of this commit:
cvs rdiff -u -r1.13 -r1.14 src/sys/dev/nvmm/x86/nvmm_x86.c
cvs rdiff -u -r1.18 -r1.19 src/sys/dev/nvmm/x86/nvmm_x86.h
cvs rdiff -u -r1.69 -r1.70 src/sys/dev/nvmm/x86/nvmm_x86_svm.c
cvs rdiff -u -r1.70 -r1.71 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.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86.c:1.13 src/sys/dev/nvmm/x86/nvmm_x86.c:1.14
--- src/sys/dev/nvmm/x86/nvmm_x86.c:1.13	Thu Aug 20 11:07:43 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86.c	Thu Aug 20 11:09:56 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86.c,v 1.13 2020/08/20 11:07:43 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86.c,v 1.14 2020/08/20 11:09:56 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86.c,v 1.13 2020/08/20 11:07:43 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86.c,v 1.14 2020/08/20 11:09:56 maxv Exp $");
 
 #include 
 #include 
@@ -421,6 +421,26 @@ const struct nvmm_x86_cpuid_mask nvmm_cp
 	CPUID_3DNOW
 };
 
+const struct nvmm_x86_cpuid_mask nvmm_cpuid_8007 = {
+	.eax = 0,
+	.ebx = 0,
+	.ecx = 0,
+	.edx = CPUID_APM_ITSC
+};
+
+const struct nvmm_x86_cpuid_mask nvmm_cpuid_8008 = {
+	.eax = ~0,
+	.ebx =
+	CPUID_CAPEX_CLZERO |
+	/* CPUID_CAPEX_IRPERF excluded */
+	CPUID_CAPEX_XSAVEERPTR |
+	/* CPUID_CAPEX_RDPRU excluded */
+	/* CPUID_CAPEX_MCOMMIT excluded */
+	CPUID_CAPEX_WBNOINVD,
+	.ecx = ~0, /* TODO? */
+	.edx = 0
+};
+
 bool
 nvmm_x86_pat_validate(uint64_t val)
 {

Index: src/sys/dev/nvmm/x86/nvmm_x86.h
diff -u src/sys/dev/nvmm/x86/nvmm_x86.h:1.18 src/sys/dev/nvmm/x86/nvmm_x86.h:1.19
--- src/sys/dev/nvmm/x86/nvmm_x86.h:1.18	Mon Oct 28 08:30:49 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86.h	Thu Aug 20 11:09:56 2020
@@ -1,7 +1,7 @@
-/*	$NetBSD: nvmm_x86.h,v 1.18 2019/10/28 08:30:49 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86.h,v 1.19 2020/08/20 11:09:56 maxv Exp $	*/
 
 /*
- * Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
+ * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -320,6 +320,8 @@ extern const struct nvmm_x64_state nvmm_
 extern const struct nvmm_x86_cpuid_mask nvmm_cpuid_0001;
 extern const struct nvmm_x86_cpuid_mask nvmm_cpuid_0007;
 extern const struct nvmm_x86_cpuid_mask nvmm_cpuid_8001;
+extern const struct nvmm_x86_cpuid_mask nvmm_cpuid_8007;
+extern const struct nvmm_x86_cpuid_mask nvmm_cpuid_8008;
 bool nvmm_x86_pat_validate(uint64_t);
 #endif
 

Index: src/sys/dev/nvmm/x86/nvmm_x86_svm.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.69 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.70
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.69	Tue Aug 18 17:08:05 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Thu Aug 20 11:09:56 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.69 2020/08/18 17:08:05 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.70 2020/08/20 11:09:56 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.69 2020/08/18 17:08:05 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.70 2020/08/20 11:09:56 maxv Exp $");
 
 #include 
 #include 
@@ -795,7 +795,9 @@ svm_inkernel_advance(struct vmcb *vmcb)
 
 #define SVM_CPUID_MAX_BASIC		0xD
 #define SVM_CPUID_MAX_HYPERVISOR	0x4000
+#define SVM_CPUID_MAX_EXTENDED		0x801F
 static uint32_t svm_cpuid_max_basic __read_mostly;
+static uint32_t svm_cpuid_max_extended __read_mostly;
 
 static void
 svm_inkernel_exec_cpuid(struct svm_cpudata *cpudata, uint64_t eax, uint64_t ecx)
@@ -825,6 +827,11 @@ svm_inkernel_handle_cpuid(struct nvmm_cp
 			eax = svm_cpuid_max_basic;
 			svm_inkernel_exec_cpuid(cpudata, eax, ecx);
 		}
+	} else {
+		if (__predict_false(eax > svm_cpuid_max_extended)) {
+			eax = svm_cpuid_max_basic;
+			svm_inkernel_exec_cpuid(cpudata, eax, ecx);
+		}
 	}
 
 	switch (eax) {
@@ -928,12 +935,74 @@ svm_inkernel_handle_cpuid(struct nvmm_cp
 		memcpy(>gprs[NVMM_X64_GPR_RDX], " ___", 4);
 		break;
 
+	case 0x8000:
+		cpudata->vmcb->state.rax = svm_cpuid_max_extended;
+		break;
 	case 0x8001:
 		cpudata->vmcb->state.rax &= nvmm_cpuid_8001.eax;
 		cpudata->gprs[NVMM_X64_GPR_RBX] &= nvmm_cpuid_8001.ebx;
 		

CVS commit: src/sys/dev/nvmm/x86

2020-08-20 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Thu Aug 20 11:07:43 UTC 2020

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86.c

Log Message:
nvmm-x86: advertise the SERIALIZE instruction, available on future CPUs


To generate a diff of this commit:
cvs rdiff -u -r1.12 -r1.13 src/sys/dev/nvmm/x86/nvmm_x86.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.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86.c:1.12 src/sys/dev/nvmm/x86/nvmm_x86.c:1.13
--- src/sys/dev/nvmm/x86/nvmm_x86.c:1.12	Tue Aug 11 15:23:10 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86.c	Thu Aug 20 11:07:43 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86.c,v 1.12 2020/08/11 15:23:10 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86.c,v 1.13 2020/08/20 11:07:43 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86.c,v 1.12 2020/08/11 15:23:10 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86.c,v 1.13 2020/08/20 11:07:43 maxv Exp $");
 
 #include 
 #include 
@@ -363,7 +363,7 @@ const struct nvmm_x86_cpuid_mask nvmm_cp
 	/* CPUID_SEF_SRBDS_CTRL excluded */
 	CPUID_SEF_MD_CLEAR |
 	/* CPUID_SEF_TSX_FORCE_ABORT excluded */
-	/* CPUID_SEF_SERIALIZE excluded */
+	CPUID_SEF_SERIALIZE |
 	/* CPUID_SEF_HYBRID excluded */
 	/* CPUID_SEF_TSXLDTRK excluded */
 	/* CPUID_SEF_CET_IBT excluded */



CVS commit: src/sys/dev/nvmm/x86

2020-08-18 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Tue Aug 18 17:08:05 UTC 2020

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_svm.c

Log Message:
nvmm-x86-svm: improve the CPUID emulation

Limit the hypervisor range, and properly handle each basic leaf until 0xD.


To generate a diff of this commit:
cvs rdiff -u -r1.68 -r1.69 src/sys/dev/nvmm/x86/nvmm_x86_svm.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.68 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.69
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.68	Tue Aug 18 17:03:10 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Tue Aug 18 17:08:05 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.68 2020/08/18 17:03:10 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.69 2020/08/18 17:08:05 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.68 2020/08/18 17:03:10 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.69 2020/08/18 17:08:05 maxv Exp $");
 
 #include 
 #include 
@@ -793,7 +793,21 @@ svm_inkernel_advance(struct vmcb *vmcb)
 	vmcb->ctrl.intr &= ~VMCB_CTRL_INTR_SHADOW;
 }
 
+#define SVM_CPUID_MAX_BASIC		0xD
 #define SVM_CPUID_MAX_HYPERVISOR	0x4000
+static uint32_t svm_cpuid_max_basic __read_mostly;
+
+static void
+svm_inkernel_exec_cpuid(struct svm_cpudata *cpudata, uint64_t eax, uint64_t ecx)
+{
+	u_int descs[4];
+
+	x86_cpuid2(eax, ecx, descs);
+	cpudata->vmcb->state.rax = descs[0];
+	cpudata->gprs[NVMM_X64_GPR_RBX] = descs[1];
+	cpudata->gprs[NVMM_X64_GPR_RCX] = descs[2];
+	cpudata->gprs[NVMM_X64_GPR_RDX] = descs[3];
+}
 
 static void
 svm_inkernel_handle_cpuid(struct nvmm_cpu *vcpu, uint64_t eax, uint64_t ecx)
@@ -801,7 +815,22 @@ svm_inkernel_handle_cpuid(struct nvmm_cp
 	struct svm_cpudata *cpudata = vcpu->cpudata;
 	uint64_t cr4;
 
+	if (eax < 0x4000) {
+		if (__predict_false(eax > svm_cpuid_max_basic)) {
+			eax = svm_cpuid_max_basic;
+			svm_inkernel_exec_cpuid(cpudata, eax, ecx);
+		}
+	} else if (eax < 0x8000) {
+		if (__predict_false(eax > SVM_CPUID_MAX_HYPERVISOR)) {
+			eax = svm_cpuid_max_basic;
+			svm_inkernel_exec_cpuid(cpudata, eax, ecx);
+		}
+	}
+
 	switch (eax) {
+	case 0x:
+		cpudata->vmcb->state.rax = svm_cpuid_max_basic;
+		break;
 	case 0x0001:
 		cpudata->vmcb->state.rax &= nvmm_cpuid_0001.eax;
 
@@ -831,10 +860,20 @@ svm_inkernel_handle_cpuid(struct nvmm_cp
 		cpudata->gprs[NVMM_X64_GPR_RDX] = 0;
 		break;
 	case 0x0007: /* Structured Extended Features */
-		cpudata->vmcb->state.rax &= nvmm_cpuid_0007.eax;
-		cpudata->gprs[NVMM_X64_GPR_RBX] &= nvmm_cpuid_0007.ebx;
-		cpudata->gprs[NVMM_X64_GPR_RCX] &= nvmm_cpuid_0007.ecx;
-		cpudata->gprs[NVMM_X64_GPR_RDX] &= nvmm_cpuid_0007.edx;
+		switch (ecx) {
+		case 0:
+			cpudata->vmcb->state.rax = 0;
+			cpudata->gprs[NVMM_X64_GPR_RBX] &= nvmm_cpuid_0007.ebx;
+			cpudata->gprs[NVMM_X64_GPR_RCX] &= nvmm_cpuid_0007.ecx;
+			cpudata->gprs[NVMM_X64_GPR_RDX] &= nvmm_cpuid_0007.edx;
+			break;
+		default:
+			cpudata->vmcb->state.rax = 0;
+			cpudata->gprs[NVMM_X64_GPR_RBX] = 0;
+			cpudata->gprs[NVMM_X64_GPR_RCX] = 0;
+			cpudata->gprs[NVMM_X64_GPR_RDX] = 0;
+			break;
+		}
 		break;
 	case 0x0008: /* Empty */
 	case 0x0009: /* Empty */
@@ -2418,6 +2457,9 @@ svm_init(void)
 	/* Init the XCR0 mask. */
 	svm_xcr0_mask = SVM_XCR0_MASK_DEFAULT & x86_xsave_features;
 
+	/* Init the max basic CPUID leaf. */
+	svm_cpuid_max_basic = uimin(cpuid_level, SVM_CPUID_MAX_BASIC);
+
 	memset(hsave, 0, sizeof(hsave));
 	for (CPU_INFO_FOREACH(cii, ci)) {
 		pg = uvm_pagealloc(NULL, 0, NULL, UVM_PGA_ZERO);



CVS commit: src/sys/dev/nvmm

2020-08-18 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Tue Aug 18 17:04:38 UTC 2020

Modified Files:
src/sys/dev/nvmm: nvmm.c

Log Message:
nvmm: use relaxed atomics to read nmachines


To generate a diff of this commit:
cvs rdiff -u -r1.34 -r1.35 src/sys/dev/nvmm/nvmm.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/nvmm.c
diff -u src/sys/dev/nvmm/nvmm.c:1.34 src/sys/dev/nvmm/nvmm.c:1.35
--- src/sys/dev/nvmm/nvmm.c:1.34	Tue Aug 18 17:03:58 2020
+++ src/sys/dev/nvmm/nvmm.c	Tue Aug 18 17:04:37 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm.c,v 1.34 2020/08/18 17:03:58 maxv Exp $	*/
+/*	$NetBSD: nvmm.c,v 1.35 2020/08/18 17:04:37 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.34 2020/08/18 17:03:58 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.35 2020/08/18 17:04:37 maxv Exp $");
 
 #include 
 #include 
@@ -1218,7 +1218,7 @@ nvmm_attach(device_t parent, device_t se
 static int
 nvmm_detach(device_t self, int flags)
 {
-	if (nmachines > 0)
+	if (atomic_load_relaxed() > 0)
 		return EBUSY;
 	nvmm_fini();
 	return 0;



CVS commit: src/sys/dev/nvmm

2020-08-18 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Tue Aug 18 17:03:58 UTC 2020

Modified Files:
src/sys/dev/nvmm: nvmm.c

Log Message:
nvmm: localify a variable that doesn't need to be global


To generate a diff of this commit:
cvs rdiff -u -r1.33 -r1.34 src/sys/dev/nvmm/nvmm.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/nvmm.c
diff -u src/sys/dev/nvmm/nvmm.c:1.33 src/sys/dev/nvmm/nvmm.c:1.34
--- src/sys/dev/nvmm/nvmm.c:1.33	Sat Aug  1 08:18:36 2020
+++ src/sys/dev/nvmm/nvmm.c	Tue Aug 18 17:03:58 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm.c,v 1.33 2020/08/01 08:18:36 maxv Exp $	*/
+/*	$NetBSD: nvmm.c,v 1.34 2020/08/18 17:03:58 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.33 2020/08/01 08:18:36 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.34 2020/08/18 17:03:58 maxv Exp $");
 
 #include 
 #include 
@@ -1040,7 +1040,7 @@ static int nvmm_close(file_t *);
 static int nvmm_mmap(file_t *, off_t *, size_t, int, int *, int *,
 struct uvm_object **, int *);
 
-const struct fileops nvmm_fileops = {
+static const struct fileops nvmm_fileops = {
 	.fo_read = fbadop_read,
 	.fo_write = fbadop_write,
 	.fo_ioctl = nvmm_ioctl,



CVS commit: src/sys/dev/nvmm/x86

2020-08-18 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Tue Aug 18 17:03:10 UTC 2020

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_svm.c nvmm_x86_vmx.c

Log Message:
nvmm-x86: also flush the guest TLB when CR4.{PCIDE,SMEP} changes


To generate a diff of this commit:
cvs rdiff -u -r1.67 -r1.68 src/sys/dev/nvmm/x86/nvmm_x86_svm.c
cvs rdiff -u -r1.69 -r1.70 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.67 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.68
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.67	Wed Aug  5 15:22:25 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Tue Aug 18 17:03:10 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.67 2020/08/05 15:22:25 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.68 2020/08/18 17:03:10 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.67 2020/08/05 15:22:25 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.68 2020/08/18 17:03:10 maxv Exp $");
 
 #include 
 #include 
@@ -521,7 +521,7 @@ static uint64_t svm_xcr0_mask __read_mos
 #define CR0_TLB_FLUSH \
 	(CR0_PG|CR0_WP|CR0_CD|CR0_NW)
 #define CR4_TLB_FLUSH \
-	(CR4_PGE|CR4_PAE|CR4_PSE)
+	(CR4_PSE|CR4_PAE|CR4_PGE|CR4_PCIDE|CR4_SMEP)
 
 /* -- */
 

Index: src/sys/dev/nvmm/x86/nvmm_x86_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.69 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.70
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.69	Tue Aug 11 15:31:51 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Tue Aug 18 17:03:10 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.69 2020/08/11 15:31:51 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.70 2020/08/18 17:03:10 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.69 2020/08/11 15:31:51 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.70 2020/08/18 17:03:10 maxv Exp $");
 
 #include 
 #include 
@@ -734,7 +734,7 @@ static uint64_t vmx_xcr0_mask __read_mos
 #define CR0_TLB_FLUSH \
 	(CR0_PG|CR0_WP|CR0_CD|CR0_NW)
 #define CR4_TLB_FLUSH \
-	(CR4_PGE|CR4_PAE|CR4_PSE)
+	(CR4_PSE|CR4_PAE|CR4_PGE|CR4_PCIDE|CR4_SMEP)
 
 /* -- */
 



CVS commit: src/sys/dev/nvmm/x86

2020-08-11 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Tue Aug 11 15:48:42 UTC 2020

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_svmfunc.S nvmm_x86_vmxfunc.S

Log Message:
Micro-optimize: use pushq instead of pushw. To avoid LCP stalls and
unaligned stack accesses.


To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 src/sys/dev/nvmm/x86/nvmm_x86_svmfunc.S \
src/sys/dev/nvmm/x86/nvmm_x86_vmxfunc.S

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_svmfunc.S
diff -u src/sys/dev/nvmm/x86/nvmm_x86_svmfunc.S:1.4 src/sys/dev/nvmm/x86/nvmm_x86_svmfunc.S:1.5
--- src/sys/dev/nvmm/x86/nvmm_x86_svmfunc.S:1.4	Sun Jul 19 06:36:37 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_svmfunc.S	Tue Aug 11 15:48:42 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svmfunc.S,v 1.4 2020/07/19 06:36:37 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svmfunc.S,v 1.5 2020/08/11 15:48:42 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -75,10 +75,10 @@
 
 #define HOST_SAVE_TR		\
 	strw	%ax		;\
-	pushw	%ax
+	pushq	%rax
 
 #define HOST_RESTORE_TR\
-	popw	%ax;\
+	popq	%rax;\
 	movzwq	%ax,%rdx			;\
 	movq	CPUVAR(GDT),%rax		;\
 	andq	$~0x0200,4(%rax,%rdx, 1)	;\
@@ -86,10 +86,10 @@
 
 #define HOST_SAVE_LDT		\
 	sldtw	%ax		;\
-	pushw	%ax
+	pushq	%rax
 
 #define HOST_RESTORE_LDT	\
-	popw	%ax		;\
+	popq	%rax		;\
 	lldtw	%ax
 
 /*
Index: src/sys/dev/nvmm/x86/nvmm_x86_vmxfunc.S
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmxfunc.S:1.4 src/sys/dev/nvmm/x86/nvmm_x86_vmxfunc.S:1.5
--- src/sys/dev/nvmm/x86/nvmm_x86_vmxfunc.S:1.4	Sun Jul 19 06:36:37 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmxfunc.S	Tue Aug 11 15:48:42 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmxfunc.S,v 1.4 2020/07/19 06:36:37 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_vmxfunc.S,v 1.5 2020/08/11 15:48:42 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -100,10 +100,10 @@ END(_vmx_vmxoff)
 
 #define HOST_SAVE_LDT		\
 	sldtw	%ax		;\
-	pushw	%ax
+	pushq	%rax
 
 #define HOST_RESTORE_LDT	\
-	popw	%ax		;\
+	popq	%rax		;\
 	lldtw	%ax
 
 /*



CVS commit: src/sys/dev/nvmm/x86

2020-08-11 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Tue Aug 11 15:31:52 UTC 2020

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_vmx.c

Log Message:
Improve the CPUID emulation on nvmm-intel:

 - Limit the highest extended leaf.
 - Limit 0x0007 to ECX=0, for future-proofness.


To generate a diff of this commit:
cvs rdiff -u -r1.68 -r1.69 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_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.68 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.69
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.68	Tue Aug 11 15:27:46 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Tue Aug 11 15:31:51 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.68 2020/08/11 15:27:46 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.69 2020/08/11 15:31:51 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.68 2020/08/11 15:27:46 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.69 2020/08/11 15:31:51 maxv Exp $");
 
 #include 
 #include 
@@ -1172,6 +1172,7 @@ error:
 #define VMX_CPUID_MAX_HYPERVISOR	0x4000
 #define VMX_CPUID_MAX_EXTENDED		0x8008
 static uint32_t vmx_cpuid_max_basic __read_mostly;
+static uint32_t vmx_cpuid_max_extended __read_mostly;
 
 static void
 vmx_inkernel_exec_cpuid(struct vmx_cpudata *cpudata, uint64_t eax, uint64_t ecx)
@@ -1203,6 +1204,11 @@ vmx_inkernel_handle_cpuid(struct nvmm_ma
 			eax = vmx_cpuid_max_basic;
 			vmx_inkernel_exec_cpuid(cpudata, eax, ecx);
 		}
+	} else {
+		if (__predict_false(eax > vmx_cpuid_max_extended)) {
+			eax = vmx_cpuid_max_basic;
+			vmx_inkernel_exec_cpuid(cpudata, eax, ecx);
+		}
 	}
 
 	switch (eax) {
@@ -1248,12 +1254,22 @@ vmx_inkernel_handle_cpuid(struct nvmm_ma
 		cpudata->gprs[NVMM_X64_GPR_RDX] = 0;
 		break;
 	case 0x0007: /* Structured Extended Feature Flags Enumeration */
-		cpudata->gprs[NVMM_X64_GPR_RAX] &= nvmm_cpuid_0007.eax;
-		cpudata->gprs[NVMM_X64_GPR_RBX] &= nvmm_cpuid_0007.ebx;
-		cpudata->gprs[NVMM_X64_GPR_RCX] &= nvmm_cpuid_0007.ecx;
-		cpudata->gprs[NVMM_X64_GPR_RDX] &= nvmm_cpuid_0007.edx;
-		if (vmx_procbased_ctls2 & PROC_CTLS2_INVPCID_ENABLE) {
-			cpudata->gprs[NVMM_X64_GPR_RBX] |= CPUID_SEF_INVPCID;
+		switch (ecx) {
+		case 0:
+			cpudata->gprs[NVMM_X64_GPR_RAX] = 0;
+			cpudata->gprs[NVMM_X64_GPR_RBX] &= nvmm_cpuid_0007.ebx;
+			cpudata->gprs[NVMM_X64_GPR_RCX] &= nvmm_cpuid_0007.ecx;
+			cpudata->gprs[NVMM_X64_GPR_RDX] &= nvmm_cpuid_0007.edx;
+			if (vmx_procbased_ctls2 & PROC_CTLS2_INVPCID_ENABLE) {
+cpudata->gprs[NVMM_X64_GPR_RBX] |= CPUID_SEF_INVPCID;
+			}
+			break;
+		default:
+			cpudata->gprs[NVMM_X64_GPR_RAX] = 0;
+			cpudata->gprs[NVMM_X64_GPR_RBX] = 0;
+			cpudata->gprs[NVMM_X64_GPR_RCX] = 0;
+			cpudata->gprs[NVMM_X64_GPR_RDX] = 0;
+			break;
 		}
 		break;
 	case 0x0008: /* Empty */
@@ -1365,6 +1381,9 @@ vmx_inkernel_handle_cpuid(struct nvmm_ma
 		memcpy(>gprs[NVMM_X64_GPR_RDX], " ___", 4);
 		break;
 
+	case 0x8000:
+		cpudata->gprs[NVMM_X64_GPR_RAX] = vmx_cpuid_max_extended;
+		break;
 	case 0x8001:
 		cpudata->gprs[NVMM_X64_GPR_RAX] &= nvmm_cpuid_8001.eax;
 		cpudata->gprs[NVMM_X64_GPR_RBX] &= nvmm_cpuid_8001.ebx;
@@ -3346,6 +3365,7 @@ vmx_init(void)
 	uint64_t xc, msr;
 	struct vmxon *vmxon;
 	uint32_t revision;
+	u_int descs[4];
 	paddr_t pa;
 	vaddr_t va;
 	int error;
@@ -3356,9 +3376,13 @@ vmx_init(void)
 	/* Init the XCR0 mask. */
 	vmx_xcr0_mask = VMX_XCR0_MASK_DEFAULT & x86_xsave_features;
 
-	/* Init the max CPUID leaves. */
+	/* Init the max basic CPUID leaf. */
 	vmx_cpuid_max_basic = uimin(cpuid_level, VMX_CPUID_MAX_BASIC);
 
+	/* Init the max extended CPUID leaf. */
+	x86_cpuid(0x8000, descs);
+	vmx_cpuid_max_extended = uimin(descs[0], VMX_CPUID_MAX_EXTENDED);
+
 	/* Init the TLB flush op, the EPT flush op and the EPTP type. */
 	msr = rdmsr(MSR_IA32_VMX_EPT_VPID_CAP);
 	if ((msr & IA32_VMX_EPT_VPID_INVVPID_CONTEXT) != 0) {



CVS commit: src/sys/dev/nvmm/x86

2020-08-11 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Tue Aug 11 15:27:46 UTC 2020

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_vmx.c

Log Message:
Improve emulation of MSR_IA32_ARCH_CAPABILITIES: publish only the *_NO
bits. Initially they were the only ones there, but Intel then added other
bits we aren't interested in, and they must be filtered out.


To generate a diff of this commit:
cvs rdiff -u -r1.67 -r1.68 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_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.67 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.68
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.67	Wed Aug  5 15:20:09 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Tue Aug 11 15:27:46 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.67 2020/08/05 15:20:09 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.68 2020/08/11 15:27:46 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.67 2020/08/05 15:20:09 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.68 2020/08/11 15:27:46 maxv Exp $");
 
 #include 
 #include 
@@ -1734,6 +1734,24 @@ vmx_inkernel_handle_msr(struct nvmm_mach
 			cpudata->gprs[NVMM_X64_GPR_RDX] = (val >> 32);
 			goto handled;
 		}
+		if (exit->u.rdmsr.msr == MSR_IA32_ARCH_CAPABILITIES) {
+			u_int descs[4];
+			if (cpuid_level < 7) {
+goto error;
+			}
+			x86_cpuid(7, descs);
+			if (!(descs[3] & CPUID_SEF_ARCH_CAP)) {
+goto error;
+			}
+			val = rdmsr(MSR_IA32_ARCH_CAPABILITIES);
+			val &= (IA32_ARCH_RDCL_NO |
+			IA32_ARCH_SSB_NO |
+			IA32_ARCH_MDS_NO |
+			IA32_ARCH_TAA_NO);
+			cpudata->gprs[NVMM_X64_GPR_RAX] = (val & 0x);
+			cpudata->gprs[NVMM_X64_GPR_RDX] = (val >> 32);
+			goto handled;
+		}
 		for (i = 0; i < __arraycount(msr_ignore_list); i++) {
 			if (msr_ignore_list[i] != exit->u.rdmsr.msr)
 continue;
@@ -2765,8 +2783,6 @@ vmx_vcpu_init(struct nvmm_machine *mach,
 	vmx_vcpu_msr_allow(cpudata->msrbm, MSR_FSBASE, true, true);
 	vmx_vcpu_msr_allow(cpudata->msrbm, MSR_GSBASE, true, true);
 	vmx_vcpu_msr_allow(cpudata->msrbm, MSR_TSC, true, false);
-	vmx_vcpu_msr_allow(cpudata->msrbm, MSR_IA32_ARCH_CAPABILITIES,
-	true, false);
 	vmx_vmwrite(VMCS_MSR_BITMAP, (uint64_t)cpudata->msrbm_pa);
 
 	/*



CVS commit: src/sys/dev/nvmm/x86

2020-08-11 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Tue Aug 11 15:23:10 UTC 2020

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86.c

Log Message:
Hide OSPKE. NFC since the host never uses PKU, but still.


To generate a diff of this commit:
cvs rdiff -u -r1.11 -r1.12 src/sys/dev/nvmm/x86/nvmm_x86.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.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86.c:1.11 src/sys/dev/nvmm/x86/nvmm_x86.c:1.12
--- src/sys/dev/nvmm/x86/nvmm_x86.c:1.11	Wed Aug  5 15:38:28 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86.c	Tue Aug 11 15:23:10 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86.c,v 1.11 2020/08/05 15:38:28 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86.c,v 1.12 2020/08/11 15:23:10 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86.c,v 1.11 2020/08/05 15:38:28 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86.c,v 1.12 2020/08/11 15:23:10 maxv Exp $");
 
 #include 
 #include 
@@ -338,7 +338,7 @@ const struct nvmm_x86_cpuid_mask nvmm_cp
 	/* CPUID_SEF_AVX512_VBMI excluded */
 	CPUID_SEF_UMIP |
 	/* CPUID_SEF_PKU excluded */
-	CPUID_SEF_OSPKE |
+	/* CPUID_SEF_OSPKE excluded */
 	/* CPUID_SEF_WAITPKG excluded */
 	/* CPUID_SEF_AVX512_VBMI2 excluded */
 	/* CPUID_SEF_CET_SS excluded */



CVS commit: src/sys/dev/nvmm

2020-08-05 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Wed Aug  5 16:36:34 UTC 2020

Modified Files:
src/sys/dev/nvmm: nvmm.h

Log Message:
Add CTASSERT.


To generate a diff of this commit:
cvs rdiff -u -r1.13 -r1.14 src/sys/dev/nvmm/nvmm.h

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/nvmm.h
diff -u src/sys/dev/nvmm/nvmm.h:1.13 src/sys/dev/nvmm/nvmm.h:1.14
--- src/sys/dev/nvmm/nvmm.h:1.13	Sat Aug  1 08:18:36 2020
+++ src/sys/dev/nvmm/nvmm.h	Wed Aug  5 16:36:33 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm.h,v 1.13 2020/08/01 08:18:36 maxv Exp $	*/
+/*	$NetBSD: nvmm.h,v 1.14 2020/08/05 16:36:33 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -96,4 +96,9 @@ struct nvmm_comm_page {
 #define NVMM_COMM_CPUID(off)		\
 	((off >> 12) & 0xFF)
 
+#ifdef _KERNEL
+/* At most one page, for the NVMM_COMM_* macros. */
+CTASSERT(sizeof(struct nvmm_comm_page) <= PAGE_SIZE);
+#endif
+
 #endif



CVS commit: src/sys/dev/nvmm/x86

2020-08-05 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Wed Aug  5 15:38:28 UTC 2020

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86.c

Log Message:
Improve the CPUID emulation:

 - Hide SGX*, PKU, WAITPKG, and SKINIT, because they are not supported.
 - Hide HLE and RTM, part of TSX. Because TSX is just too buggy and we
   cannot guarantee that it remains enabled in the guest (if for example
   the host disables TSX while the guest is running). Nobody wants this
   crap anyway, so bye-bye.
 - Advertise FSREP_MOV, because no reason to hide it.


To generate a diff of this commit:
cvs rdiff -u -r1.10 -r1.11 src/sys/dev/nvmm/x86/nvmm_x86.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.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86.c:1.10 src/sys/dev/nvmm/x86/nvmm_x86.c:1.11
--- src/sys/dev/nvmm/x86/nvmm_x86.c:1.10	Wed Aug  5 15:16:50 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86.c	Wed Aug  5 15:38:28 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86.c,v 1.10 2020/08/05 15:16:50 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86.c,v 1.11 2020/08/05 15:38:28 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86.c,v 1.10 2020/08/05 15:16:50 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86.c,v 1.11 2020/08/05 15:38:28 maxv Exp $");
 
 #include 
 #include 
@@ -304,16 +304,16 @@ const struct nvmm_x86_cpuid_mask nvmm_cp
 	.ebx =
 	CPUID_SEF_FSGSBASE |
 	/* CPUID_SEF_TSC_ADJUST excluded */
-	CPUID_SEF_SGX |
+	/* CPUID_SEF_SGX excluded */
 	CPUID_SEF_BMI1 |
-	CPUID_SEF_HLE |
+	/* CPUID_SEF_HLE excluded */
 	/* CPUID_SEF_AVX2 excluded */
 	CPUID_SEF_FDPEXONLY |
 	CPUID_SEF_SMEP |
 	CPUID_SEF_BMI2 |
 	CPUID_SEF_ERMS |
 	/* CPUID_SEF_INVPCID excluded, but re-included in VMX */
-	CPUID_SEF_RTM |
+	/* CPUID_SEF_RTM excluded */
 	/* CPUID_SEF_QM excluded */
 	CPUID_SEF_FPUCSDS |
 	/* CPUID_SEF_MPX excluded */
@@ -337,9 +337,9 @@ const struct nvmm_x86_cpuid_mask nvmm_cp
 	CPUID_SEF_PREFETCHWT1 |
 	/* CPUID_SEF_AVX512_VBMI excluded */
 	CPUID_SEF_UMIP |
-	CPUID_SEF_PKU |
+	/* CPUID_SEF_PKU excluded */
 	CPUID_SEF_OSPKE |
-	CPUID_SEF_WAITPKG |
+	/* CPUID_SEF_WAITPKG excluded */
 	/* CPUID_SEF_AVX512_VBMI2 excluded */
 	/* CPUID_SEF_CET_SS excluded */
 	CPUID_SEF_GFNI |
@@ -352,13 +352,13 @@ const struct nvmm_x86_cpuid_mask nvmm_cp
 	/* CPUID_SEF_RDPID excluded */
 	CPUID_SEF_CLDEMOTE |
 	CPUID_SEF_MOVDIRI |
-	CPUID_SEF_MOVDIR64B |
-	CPUID_SEF_SGXLC,
+	CPUID_SEF_MOVDIR64B,
+	/* CPUID_SEF_SGXLC excluded */
 	/* CPUID_SEF_PKS excluded */
 	.edx =
 	/* CPUID_SEF_AVX512_4VNNIW excluded */
 	/* CPUID_SEF_AVX512_4FMAPS excluded */
-	/* CPUID_SEF_FSREP_MOV excluded */
+	CPUID_SEF_FSREP_MOV |
 	/* CPUID_SEF_AVX512_VP2INTERSECT excluded */
 	/* CPUID_SEF_SRBDS_CTRL excluded */
 	CPUID_SEF_MD_CLEAR |
@@ -391,7 +391,7 @@ const struct nvmm_x86_cpuid_mask nvmm_cp
 	/* CPUID_OSVW excluded */
 	CPUID_IBS |
 	CPUID_XOP |
-	CPUID_SKINIT |
+	/* CPUID_SKINIT excluded */
 	CPUID_WDT |
 	CPUID_LWP |
 	CPUID_FMA4 |



CVS commit: src/sys/dev/nvmm/x86

2020-08-05 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Wed Aug  5 15:22:25 UTC 2020

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_svm.c

Log Message:
Add new field definitions, and intercept everything, for future-proofness.


To generate a diff of this commit:
cvs rdiff -u -r1.66 -r1.67 src/sys/dev/nvmm/x86/nvmm_x86_svm.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.66 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.67
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.66	Wed Aug  5 10:31:37 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Wed Aug  5 15:22:25 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.66 2020/08/05 10:31:37 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.67 2020/08/05 15:22:25 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.66 2020/08/05 10:31:37 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.67 2020/08/05 15:22:25 maxv Exp $");
 
 #include 
 #include 
@@ -232,11 +232,16 @@ svm_stgi(void)
 #define VMCB_EXITCODE_CR13_WRITE_TRAP	0x009D
 #define VMCB_EXITCODE_CR14_WRITE_TRAP	0x009E
 #define VMCB_EXITCODE_CR15_WRITE_TRAP	0x009F
+#define VMCB_EXITCODE_INVLPGB		0x00A0
+#define VMCB_EXITCODE_INVLPGB_ILLEGAL	0x00A1
+#define VMCB_EXITCODE_INVPCID		0x00A2
 #define VMCB_EXITCODE_MCOMMIT		0x00A3
+#define VMCB_EXITCODE_TLBSYNC		0x00A4
 #define VMCB_EXITCODE_NPF		0x0400
 #define VMCB_EXITCODE_AVIC_INCOMP_IPI	0x0401
 #define VMCB_EXITCODE_AVIC_NOACCEL	0x0402
 #define VMCB_EXITCODE_VMGEXIT		0x0403
+#define VMCB_EXITCODE_BUSY		-2ULL
 #define VMCB_EXITCODE_INVALID		-1ULL
 
 /* -- */
@@ -307,7 +312,11 @@ struct vmcb_ctrl {
 #define VMCB_CTRL_INTERCEPT_WCR_SPEC(x)	__BIT(16 + x)
 
 	uint32_t intercept_misc3;
+#define VMCB_CTRL_INTERCEPT_INVLPGB_ALL	__BIT(0)
+#define VMCB_CTRL_INTERCEPT_INVLPGB_ILL	__BIT(1)
+#define VMCB_CTRL_INTERCEPT_PCID	__BIT(2)
 #define VMCB_CTRL_INTERCEPT_MCOMMIT	__BIT(3)
+#define VMCB_CTRL_INTERCEPT_TLBSYNC	__BIT(4)
 
 	uint8_t  rsvd1[36];
 	uint16_t pause_filt_thresh;
@@ -335,6 +344,7 @@ struct vmcb_ctrl {
 
 	uint64_t intr;
 #define VMCB_CTRL_INTR_SHADOW		__BIT(0)
+#define VMCB_CTRL_INTR_MASK		__BIT(1)
 
 	uint64_t exitcode;
 	uint64_t exitinfo1;
@@ -399,7 +409,7 @@ struct vmcb_ctrl {
 #define VMCB_CTRL_AVIC_PHYS_MAX_INDEX	__BITS(7,0)
 
 	uint64_t rsvd4;
-	uint64_t vmcb_ptr;
+	uint64_t vmsa_ptr;
 
 	uint8_t	pad[752];
 } __packed;
@@ -1449,6 +1459,11 @@ svm_vcpu_run(struct nvmm_machine *mach, 
 		case VMCB_EXITCODE_CLGI:
 		case VMCB_EXITCODE_SKINIT:
 		case VMCB_EXITCODE_RDTSCP:
+		case VMCB_EXITCODE_RDPRU:
+		case VMCB_EXITCODE_INVLPGB:
+		case VMCB_EXITCODE_INVPCID:
+		case VMCB_EXITCODE_MCOMMIT:
+		case VMCB_EXITCODE_TLBSYNC:
 			svm_inject_ud(vcpu);
 			exit->reason = NVMM_VCPU_EXIT_NONE;
 			break;
@@ -2042,7 +2057,17 @@ svm_vcpu_init(struct nvmm_machine *mach,
 	VMCB_CTRL_INTERCEPT_RDTSCP |
 	VMCB_CTRL_INTERCEPT_MONITOR |
 	VMCB_CTRL_INTERCEPT_MWAIT |
-	VMCB_CTRL_INTERCEPT_XSETBV;
+	VMCB_CTRL_INTERCEPT_XSETBV |
+	VMCB_CTRL_INTERCEPT_RDPRU;
+
+	/*
+	 * Intercept everything.
+	 */
+	vmcb->ctrl.intercept_misc3 =
+	VMCB_CTRL_INTERCEPT_INVLPGB_ALL |
+	VMCB_CTRL_INTERCEPT_PCID |
+	VMCB_CTRL_INTERCEPT_MCOMMIT |
+	VMCB_CTRL_INTERCEPT_TLBSYNC;
 
 	/* Intercept all I/O accesses. */
 	memset(cpudata->iobm, 0xFF, IOBM_SIZE);



CVS commit: src/sys/dev/nvmm/x86

2020-08-05 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Wed Aug  5 15:20:09 UTC 2020

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_vmx.c

Log Message:
Add new field definitions.


To generate a diff of this commit:
cvs rdiff -u -r1.66 -r1.67 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_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.66 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.67
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.66	Wed Aug  5 10:20:50 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Wed Aug  5 15:20:09 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.66 2020/08/05 10:20:50 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.67 2020/08/05 15:20:09 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.66 2020/08/05 10:20:50 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.67 2020/08/05 15:20:09 maxv Exp $");
 
 #include 
 #include 
@@ -223,11 +223,16 @@ vmx_sti(void)
 #define MSR_IA32_VMX_CR4_FIXED1			0x0489
 
 #define MSR_IA32_VMX_EPT_VPID_CAP	0x048C
+#define		IA32_VMX_EPT_VPID_XO			__BIT(0)
 #define		IA32_VMX_EPT_VPID_WALKLENGTH_4		__BIT(6)
 #define		IA32_VMX_EPT_VPID_UC			__BIT(8)
 #define		IA32_VMX_EPT_VPID_WB			__BIT(14)
+#define		IA32_VMX_EPT_VPID_2MB			__BIT(16)
+#define		IA32_VMX_EPT_VPID_1GB			__BIT(17)
 #define		IA32_VMX_EPT_VPID_INVEPT		__BIT(20)
 #define		IA32_VMX_EPT_VPID_FLAGS_AD		__BIT(21)
+#define		IA32_VMX_EPT_VPID_ADVANCED_VMEXIT_INFO	__BIT(22)
+#define		IA32_VMX_EPT_VPID_SHSTK			__BIT(23)
 #define		IA32_VMX_EPT_VPID_INVEPT_CONTEXT	__BIT(25)
 #define		IA32_VMX_EPT_VPID_INVEPT_ALL		__BIT(26)
 #define		IA32_VMX_EPT_VPID_INVVPID		__BIT(32)
@@ -281,6 +286,7 @@ vmx_sti(void)
 #define			EPTP_TYPE_WB		6
 #define		EPTP_WALKLEN			__BITS(5,3)
 #define		EPTP_FLAGS_AD			__BIT(6)
+#define		EPTP_SSS			__BIT(7)
 #define		EPTP_PHYSADDR			__BITS(63,12)
 #define VMCS_EOI_EXIT00x201C
 #define VMCS_EOI_EXIT10x201E
@@ -294,6 +300,7 @@ vmx_sti(void)
 #define VMCS_ENCLS_EXIT_BITMAP			0x202E
 #define VMCS_SUBPAGE_PERM_TABLE_PTR		0x2030
 #define VMCS_TSC_MULTIPLIER			0x2032
+#define VMCS_ENCLV_EXIT_BITMAP			0x2036
 /* 64-bit read-only fields */
 #define VMCS_GUEST_PHYSICAL_ADDRESS		0x2400
 /* 64-bit guest-state fields */
@@ -307,10 +314,13 @@ vmx_sti(void)
 #define VMCS_GUEST_PDPTE2			0x280E
 #define VMCS_GUEST_PDPTE3			0x2810
 #define VMCS_GUEST_BNDCFGS			0x2812
+#define VMCS_GUEST_RTIT_CTL			0x2814
+#define VMCS_GUEST_PKRS0x2818
 /* 64-bit host-state fields */
 #define VMCS_HOST_IA32_PAT			0x2C00
 #define VMCS_HOST_IA32_EFER			0x2C02
 #define VMCS_HOST_IA32_PERF_GLOBAL_CTRL		0x2C04
+#define VMCS_HOST_IA32_PKRS			0x2C06
 /* 32-bit control fields */
 #define VMCS_PINBASED_CTLS			0x4000
 #define		PIN_CTLS_INT_EXITING		__BIT(0)
@@ -356,6 +366,9 @@ vmx_sti(void)
 #define		EXIT_CTLS_SAVE_PREEMPT_TIMER	__BIT(22)
 #define		EXIT_CTLS_CLEAR_BNDCFGS		__BIT(23)
 #define		EXIT_CTLS_CONCEAL_PT		__BIT(24)
+#define		EXIT_CTLS_CLEAR_RTIT_CTL	__BIT(25)
+#define		EXIT_CTLS_LOAD_CET		__BIT(28)
+#define		EXIT_CTLS_LOAD_PKRS		__BIT(29)
 #define VMCS_EXIT_MSR_STORE_COUNT		0x400E
 #define VMCS_EXIT_MSR_LOAD_COUNT		0x4010
 #define VMCS_ENTRY_CTLS0x4012
@@ -368,6 +381,9 @@ vmx_sti(void)
 #define		ENTRY_CTLS_LOAD_EFER		__BIT(15)
 #define		ENTRY_CTLS_LOAD_BNDCFGS		__BIT(16)
 #define		ENTRY_CTLS_CONCEAL_PT		__BIT(17)
+#define		ENTRY_CTLS_LOAD_RTIT_CTL	__BIT(18)
+#define		ENTRY_CTLS_LOAD_CET		__BIT(20)
+#define		ENTRY_CTLS_LOAD_PKRS		__BIT(22)
 #define VMCS_ENTRY_MSR_LOAD_COUNT		0x4014
 #define VMCS_ENTRY_INTR_INFO			0x4016
 #define		INTR_INFO_VECTOR		__BITS(7,0)
@@ -408,7 +424,9 @@ vmx_sti(void)
 #define		PROC_CTLS2_XSAVES_ENABLE	__BIT(20)
 #define		PROC_CTLS2_MODE_BASED_EXEC_EPT	__BIT(22)
 #define		PROC_CTLS2_SUBPAGE_PERMISSIONS	__BIT(23)
+#define		PROC_CTLS2_PT_USES_GPA		__BIT(24)
 #define		PROC_CTLS2_USE_TSC_SCALING	__BIT(25)
+#define		PROC_CTLS2_WAIT_PAUSE_ENABLE	__BIT(26)
 #define		PROC_CTLS2_ENCLV_EXITING	__BIT(28)
 #define VMCS_PLE_GAP0x4020
 #define VMCS_PLE_WINDOW0x4022
@@ -489,6 +507,9 @@ vmx_sti(void)
 #define VMCS_GUEST_PENDING_DBG_EXCEPTIONS	0x6822
 #define VMCS_GUEST_IA32_SYSENTER_ESP		0x6824
 #define VMCS_GUEST_IA32_SYSENTER_EIP		0x6826
+#define VMCS_GUEST_IA32_S_CET			0x6828
+#define VMCS_GUEST_SSP0x682A
+#define VMCS_GUEST_IA32_INTR_SSP_TABLE		0x682C
 /* Natural-Width host-state fields */
 #define VMCS_HOST_CR00x6C00
 #define VMCS_HOST_CR30x6C02
@@ -502,6 +523,9 @@ vmx_sti(void)
 #define VMCS_HOST_IA32_SYSENTER_EIP		0x6C12
 #define VMCS_HOST_RSP0x6C14
 #define VMCS_HOST_RIP0x6C16
+#define VMCS_HOST_IA32_S_CET			0x6C18
+#define VMCS_HOST_SSP0x6C1A

CVS commit: src/sys/dev/nvmm/x86

2020-08-05 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Wed Aug  5 15:16:51 UTC 2020

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86.c

Log Message:
Make it easier to understand what's going on, no functional change.


To generate a diff of this commit:
cvs rdiff -u -r1.9 -r1.10 src/sys/dev/nvmm/x86/nvmm_x86.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.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86.c:1.9 src/sys/dev/nvmm/x86/nvmm_x86.c:1.10
--- src/sys/dev/nvmm/x86/nvmm_x86.c:1.9	Sat May  9 16:18:57 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86.c	Wed Aug  5 15:16:50 2020
@@ -1,7 +1,7 @@
-/*	$NetBSD: nvmm_x86.c,v 1.9 2020/05/09 16:18:57 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86.c,v 1.10 2020/08/05 15:16:50 maxv Exp $	*/
 
 /*
- * Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
+ * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86.c,v 1.9 2020/05/09 16:18:57 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86.c,v 1.10 2020/08/05 15:16:50 maxv Exp $");
 
 #include 
 #include 
@@ -233,85 +233,191 @@ const struct nvmm_x86_cpuid_mask nvmm_cp
 	.eax = ~0,
 	.ebx = ~0,
 	.ecx =
-	/* Excluded: MONITOR, VMX, SMX, EST, TM2, PDCM, PCID, DCA, X2APIC,
-	 * DEADLINE, RAZ. */
-	CPUID2_SSE3 | CPUID2_PCLMUL |
-	CPUID2_DTES64 | CPUID2_DS_CPL |
-	CPUID2_SSSE3 | CPUID2_CID |
-	CPUID2_SDBG | CPUID2_FMA |
-	CPUID2_CX16 | CPUID2_xTPR |
-	CPUID2_SSE41 | CPUID2_SSE42 |
-	CPUID2_MOVBE | CPUID2_POPCNT |
-	CPUID2_AES | CPUID2_XSAVE |
-	CPUID2_OSXSAVE | CPUID2_F16C |
+	CPUID2_SSE3 |
+	CPUID2_PCLMUL |
+	CPUID2_DTES64 |
+	/* CPUID2_MONITOR excluded */
+	CPUID2_DS_CPL |
+	/* CPUID2_VMX excluded */
+	/* CPUID2_SMX excluded */
+	/* CPUID2_EST excluded */
+	/* CPUID2_TM2 excluded */
+	CPUID2_SSSE3 |
+	CPUID2_CID |
+	CPUID2_SDBG |
+	CPUID2_FMA |
+	CPUID2_CX16 |
+	CPUID2_xTPR |
+	/* CPUID2_PDCM excluded */
+	/* CPUID2_PCID excluded, but re-included in VMX */
+	/* CPUID2_DCA excluded */
+	CPUID2_SSE41 |
+	CPUID2_SSE42 |
+	/* CPUID2_X2APIC excluded */
+	CPUID2_MOVBE |
+	CPUID2_POPCNT |
+	/* CPUID2_DEADLINE excluded */
+	CPUID2_AES |
+	CPUID2_XSAVE |
+	CPUID2_OSXSAVE |
+	/* CPUID2_AVX excluded */
+	CPUID2_F16C |
 	CPUID2_RDRAND,
+	/* CPUID2_RAZ excluded */
 	.edx =
-	/* Excluded: MCE, MTRR, MCA, DS, ACPI, TM. */
-	CPUID_FPU | CPUID_VME |
-	CPUID_DE | CPUID_PSE |
-	CPUID_TSC | CPUID_MSR |
-	CPUID_PAE | CPUID_CX8 |
-	CPUID_APIC | CPUID_B10 |	
-	CPUID_SEP | CPUID_PGE |
-	CPUID_CMOV | CPUID_PAT |
-	CPUID_PSE36 | CPUID_PN |
-	CPUID_CFLUSH | CPUID_B20 |
-	CPUID_MMX | CPUID_FXSR |
-	CPUID_SSE | CPUID_SSE2 |
-	CPUID_SS | CPUID_HTT |
-	CPUID_IA64 | CPUID_SBF
+	CPUID_FPU |
+	CPUID_VME |
+	CPUID_DE |
+	CPUID_PSE |
+	CPUID_TSC |
+	CPUID_MSR |
+	CPUID_PAE |
+	/* CPUID_MCE excluded */
+	CPUID_CX8 |
+	CPUID_APIC |
+	CPUID_B10 |	
+	CPUID_SEP |
+	/* CPUID_MTRR excluded */
+	CPUID_PGE |
+	/* CPUID_MCA excluded */
+	CPUID_CMOV |
+	CPUID_PAT |
+	CPUID_PSE36 |
+	CPUID_PN |
+	CPUID_CFLUSH |
+	CPUID_B20 |
+	/* CPUID_DS excluded */
+	/* CPUID_ACPI excluded */
+	CPUID_MMX |
+	CPUID_FXSR |
+	CPUID_SSE |
+	CPUID_SSE2 |
+	CPUID_SS |
+	CPUID_HTT |
+	/* CPUID_TM excluded */
+	CPUID_IA64 |
+	CPUID_SBF
 };
 
 const struct nvmm_x86_cpuid_mask nvmm_cpuid_0007 = {
 	.eax = ~0,
 	.ebx =
-	/* Excluded: TSC_ADJUST, AVX2, INVPCID, QM, AVX512*, PT, SHA. */
 	CPUID_SEF_FSGSBASE |
-	CPUID_SEF_SGX | CPUID_SEF_BMI1 |
-	CPUID_SEF_HLE | CPUID_SEF_FDPEXONLY |
-	CPUID_SEF_SMEP | CPUID_SEF_BMI2 |
-	CPUID_SEF_ERMS | CPUID_SEF_RTM |
-	CPUID_SEF_FPUCSDS | CPUID_SEF_PQE |
-	CPUID_SEF_RDSEED | CPUID_SEF_ADX |
-	CPUID_SEF_SMAP | CPUID_SEF_CLFLUSHOPT |
+	/* CPUID_SEF_TSC_ADJUST excluded */
+	CPUID_SEF_SGX |
+	CPUID_SEF_BMI1 |
+	CPUID_SEF_HLE |
+	/* CPUID_SEF_AVX2 excluded */
+	CPUID_SEF_FDPEXONLY |
+	CPUID_SEF_SMEP |
+	CPUID_SEF_BMI2 |
+	CPUID_SEF_ERMS |
+	/* CPUID_SEF_INVPCID excluded, but re-included in VMX */
+	CPUID_SEF_RTM |
+	/* CPUID_SEF_QM excluded */
+	CPUID_SEF_FPUCSDS |
+	/* CPUID_SEF_MPX excluded */
+	CPUID_SEF_PQE |
+	/* CPUID_SEF_AVX512F excluded */
+	/* CPUID_SEF_AVX512DQ excluded */
+	CPUID_SEF_RDSEED |
+	CPUID_SEF_ADX |
+	CPUID_SEF_SMAP |
+	/* CPUID_SEF_AVX512_IFMA excluded */
+	CPUID_SEF_CLFLUSHOPT |
 	CPUID_SEF_CLWB,
+	/* CPUID_SEF_PT excluded */
+	/* CPUID_SEF_AVX512PF excluded */
+	/* 

CVS commit: src/sys/dev/nvmm/x86

2020-08-05 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Wed Aug  5 10:31:37 UTC 2020

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_svm.c

Log Message:
Use ULL, to make it clear we are unsigned.


To generate a diff of this commit:
cvs rdiff -u -r1.65 -r1.66 src/sys/dev/nvmm/x86/nvmm_x86_svm.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.65 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.66
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.65	Sun Jul 19 06:56:09 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Wed Aug  5 10:31:37 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.65 2020/07/19 06:56:09 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.66 2020/08/05 10:31:37 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.65 2020/07/19 06:56:09 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.66 2020/08/05 10:31:37 maxv Exp $");
 
 #include 
 #include 
@@ -237,7 +237,7 @@ svm_stgi(void)
 #define VMCB_EXITCODE_AVIC_INCOMP_IPI	0x0401
 #define VMCB_EXITCODE_AVIC_NOACCEL	0x0402
 #define VMCB_EXITCODE_VMGEXIT		0x0403
-#define VMCB_EXITCODE_INVALID		-1
+#define VMCB_EXITCODE_INVALID		-1ULL
 
 /* -- */
 



CVS commit: src/sys/dev/nvmm/x86

2020-08-05 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Wed Aug  5 10:20:50 UTC 2020

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_vmx.c

Log Message:
Simplify, remove unnecessary #ifdef DIAGNOSTIC around KASSERTs.


To generate a diff of this commit:
cvs rdiff -u -r1.65 -r1.66 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_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.65 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.66
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.65	Sun Jul 19 06:56:09 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Wed Aug  5 10:20:50 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.65 2020/07/19 06:56:09 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.66 2020/08/05 10:20:50 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.65 2020/07/19 06:56:09 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.66 2020/08/05 10:20:50 maxv Exp $");
 
 #include 
 #include 
@@ -883,15 +883,11 @@ vmx_vmcs_enter(struct nvmm_cpu *vcpu)
 {
 	struct vmx_cpudata *cpudata = vcpu->cpudata;
 	struct cpu_info *vmcs_ci;
-	paddr_t oldpa __diagused;
 
 	cpudata->vmcs_refcnt++;
 	if (cpudata->vmcs_refcnt > 1) {
-#ifdef DIAGNOSTIC
 		KASSERT(kpreempt_disabled());
-		oldpa = vmx_vmptrst();
-		KASSERT(oldpa == cpudata->vmcs_pa);
-#endif
+		KASSERT(vmx_vmptrst() == cpudata->vmcs_pa);
 		return;
 	}
 
@@ -921,9 +917,7 @@ vmx_vmcs_leave(struct nvmm_cpu *vcpu)
 	struct vmx_cpudata *cpudata = vcpu->cpudata;
 
 	KASSERT(kpreempt_disabled());
-#ifdef DIAGNOSTIC
 	KASSERT(vmx_vmptrst() == cpudata->vmcs_pa);
-#endif
 	KASSERT(cpudata->vmcs_refcnt > 0);
 	cpudata->vmcs_refcnt--;
 
@@ -941,9 +935,7 @@ vmx_vmcs_destroy(struct nvmm_cpu *vcpu)
 	struct vmx_cpudata *cpudata = vcpu->cpudata;
 
 	KASSERT(kpreempt_disabled());
-#ifdef DIAGNOSTIC
 	KASSERT(vmx_vmptrst() == cpudata->vmcs_pa);
-#endif
 	KASSERT(cpudata->vmcs_refcnt == 1);
 	cpudata->vmcs_refcnt--;
 



CVS commit: src/sys/dev/nvmm

2020-08-01 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Sat Aug  1 08:18:37 UTC 2020

Modified Files:
src/sys/dev/nvmm: nvmm.c nvmm.h nvmm_internal.h

Log Message:
Put the few x86-specific structures under #ifdef __x86_64__, for clarity.


To generate a diff of this commit:
cvs rdiff -u -r1.32 -r1.33 src/sys/dev/nvmm/nvmm.c
cvs rdiff -u -r1.12 -r1.13 src/sys/dev/nvmm/nvmm.h
cvs rdiff -u -r1.16 -r1.17 src/sys/dev/nvmm/nvmm_internal.h

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/nvmm.c
diff -u src/sys/dev/nvmm/nvmm.c:1.32 src/sys/dev/nvmm/nvmm.c:1.33
--- src/sys/dev/nvmm/nvmm.c:1.32	Fri Jul  3 16:09:54 2020
+++ src/sys/dev/nvmm/nvmm.c	Sat Aug  1 08:18:36 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm.c,v 1.32 2020/07/03 16:09:54 maxv Exp $	*/
+/*	$NetBSD: nvmm.c,v 1.33 2020/08/01 08:18:36 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.32 2020/07/03 16:09:54 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.33 2020/08/01 08:18:36 maxv Exp $");
 
 #include 
 #include 
@@ -59,8 +59,10 @@ static struct nvmm_machine machines[NVMM
 static volatile unsigned int nmachines __cacheline_aligned;
 
 static const struct nvmm_impl *nvmm_impl_list[] = {
+#if defined(__x86_64__)
 	_x86_svm,	/* x86 AMD SVM */
 	_x86_vmx	/* x86 Intel VMX */
+#endif
 };
 
 static const struct nvmm_impl *nvmm_impl = NULL;

Index: src/sys/dev/nvmm/nvmm.h
diff -u src/sys/dev/nvmm/nvmm.h:1.12 src/sys/dev/nvmm/nvmm.h:1.13
--- src/sys/dev/nvmm/nvmm.h:1.12	Mon Oct 28 08:30:49 2019
+++ src/sys/dev/nvmm/nvmm.h	Sat Aug  1 08:18:36 2020
@@ -1,7 +1,7 @@
-/*	$NetBSD: nvmm.h,v 1.12 2019/10/28 08:30:49 maxv Exp $	*/
+/*	$NetBSD: nvmm.h,v 1.13 2020/08/01 08:18:36 maxv Exp $	*/
 
 /*
- * Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
+ * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -44,7 +44,7 @@ typedef uint64_t	gvaddr_t;
 typedef uint32_t	nvmm_machid_t;
 typedef uint32_t	nvmm_cpuid_t;
 
-#ifdef __x86_64__
+#if defined(__x86_64__)
 #include 
 #endif
 

Index: src/sys/dev/nvmm/nvmm_internal.h
diff -u src/sys/dev/nvmm/nvmm_internal.h:1.16 src/sys/dev/nvmm/nvmm_internal.h:1.17
--- src/sys/dev/nvmm/nvmm_internal.h:1.16	Fri Jul  3 16:09:54 2020
+++ src/sys/dev/nvmm/nvmm_internal.h	Sat Aug  1 08:18:36 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_internal.h,v 1.16 2020/07/03 16:09:54 maxv Exp $	*/
+/*	$NetBSD: nvmm_internal.h,v 1.17 2020/08/01 08:18:36 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -119,8 +119,10 @@ struct nvmm_impl {
 	struct nvmm_vcpu_exit *);
 };
 
+#if defined(__x86_64__)
 extern const struct nvmm_impl nvmm_x86_svm;
 extern const struct nvmm_impl nvmm_x86_vmx;
+#endif
 
 static inline bool
 nvmm_return_needed(void)



CVS commit: src/sys/dev/nvmm/x86

2020-07-19 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Sun Jul 19 06:56:10 UTC 2020

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_svm.c nvmm_x86_vmx.c

Log Message:
Switch to fpu_kern_enter/leave, to prevent clobbering, now that the kernel
itself uses the fpu.


To generate a diff of this commit:
cvs rdiff -u -r1.64 -r1.65 src/sys/dev/nvmm/x86/nvmm_x86_svm.c \
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.64 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.65
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.64	Sun Jul 19 06:36:37 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Sun Jul 19 06:56:09 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.64 2020/07/19 06:36:37 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.65 2020/07/19 06:56:09 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.64 2020/07/19 06:36:37 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.65 2020/07/19 06:56:09 maxv Exp $");
 
 #include 
 #include 
@@ -1219,7 +1219,7 @@ svm_vcpu_guest_fpu_enter(struct nvmm_cpu
 {
 	struct svm_cpudata *cpudata = vcpu->cpudata;
 
-	fpu_save();
+	fpu_kern_enter();
 	fpu_area_restore(>gfpu, svm_xcr0_mask);
 
 	if (svm_xcr0_mask != 0) {
@@ -1239,6 +1239,7 @@ svm_vcpu_guest_fpu_leave(struct nvmm_cpu
 	}
 
 	fpu_area_save(>gfpu, svm_xcr0_mask);
+	fpu_kern_leave();
 }
 
 static void
Index: src/sys/dev/nvmm/x86/nvmm_x86_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.64 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.65
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.64	Sun Jul 19 06:36:37 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Sun Jul 19 06:56:09 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.64 2020/07/19 06:36:37 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.65 2020/07/19 06:56:09 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.64 2020/07/19 06:36:37 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.65 2020/07/19 06:56:09 maxv Exp $");
 
 #include 
 #include 
@@ -1875,7 +1875,7 @@ vmx_vcpu_guest_fpu_enter(struct nvmm_cpu
 {
 	struct vmx_cpudata *cpudata = vcpu->cpudata;
 
-	fpu_save();
+	fpu_kern_enter();
 	fpu_area_restore(>gfpu, vmx_xcr0_mask);
 
 	if (vmx_xcr0_mask != 0) {
@@ -1895,6 +1895,7 @@ vmx_vcpu_guest_fpu_leave(struct nvmm_cpu
 	}
 
 	fpu_area_save(>gfpu, vmx_xcr0_mask);
+	fpu_kern_leave();
 }
 
 static void



CVS commit: src/sys/dev/nvmm/x86

2020-07-19 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Sun Jul 19 06:36:38 UTC 2020

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_svm.c nvmm_x86_svmfunc.S nvmm_x86_vmx.c
nvmm_x86_vmxfunc.S

Log Message:
The TLB flush IPIs do not respect the IPL, so enforcing IPL_HIGH has no
effect. Disable interrupts earlier instead. This prevents a possible race
against such IPIs.


To generate a diff of this commit:
cvs rdiff -u -r1.63 -r1.64 src/sys/dev/nvmm/x86/nvmm_x86_svm.c \
src/sys/dev/nvmm/x86/nvmm_x86_vmx.c
cvs rdiff -u -r1.3 -r1.4 src/sys/dev/nvmm/x86/nvmm_x86_svmfunc.S \
src/sys/dev/nvmm/x86/nvmm_x86_vmxfunc.S

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.63 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.64
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.63	Fri Jul  3 16:09:54 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Sun Jul 19 06:36:37 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.63 2020/07/03 16:09:54 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.64 2020/07/19 06:36:37 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.63 2020/07/03 16:09:54 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.64 2020/07/19 06:36:37 maxv Exp $");
 
 #include 
 #include 
@@ -56,6 +56,18 @@ __KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm
 
 int svm_vmrun(paddr_t, uint64_t *);
 
+static inline void
+svm_clgi(void)
+{
+	asm volatile ("clgi" ::: "memory");
+}
+
+static inline void
+svm_stgi(void)
+{
+	asm volatile ("stgi" ::: "memory");
+}
+
 #define	MSR_VM_HSAVE_PA	0xC0010117
 
 /* -- */
@@ -1347,7 +1359,7 @@ svm_vcpu_run(struct nvmm_machine *mach, 
 	struct svm_cpudata *cpudata = vcpu->cpudata;
 	struct vmcb *vmcb = cpudata->vmcb;
 	uint64_t machgen;
-	int hcpu, s;
+	int hcpu;
 
 	if (__predict_false(svm_vcpu_event_commit(vcpu) != 0)) {
 		return EINVAL;
@@ -1382,11 +1394,11 @@ svm_vcpu_run(struct nvmm_machine *mach, 
 			svm_vmcb_cache_flush(vmcb, VMCB_CTRL_VMCB_CLEAN_I);
 		}
 
-		s = splhigh();
+		svm_clgi();
 		machgen = svm_htlb_flush(machdata, cpudata);
 		svm_vmrun(cpudata->vmcb_pa, cpudata->gprs);
 		svm_htlb_flush_ack(cpudata, machgen);
-		splx(s);
+		svm_stgi();
 
 		svm_vmcb_cache_default(vmcb);
 
Index: src/sys/dev/nvmm/x86/nvmm_x86_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.63 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.64
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.63	Sat Jul 18 20:56:53 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Sun Jul 19 06:36:37 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.63 2020/07/18 20:56:53 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.64 2020/07/19 06:36:37 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.63 2020/07/18 20:56:53 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.64 2020/07/19 06:36:37 maxv Exp $");
 
 #include 
 #include 
@@ -178,6 +178,18 @@ vmx_vmclear(paddr_t *pa)
 	);
 }
 
+static inline void
+vmx_cli(void)
+{
+	asm volatile ("cli" ::: "memory");
+}
+
+static inline void
+vmx_sti(void)
+{
+	asm volatile ("sti" ::: "memory");
+}
+
 #define MSR_IA32_FEATURE_CONTROL	0x003A
 #define		IA32_FEATURE_CONTROL_LOCK	__BIT(0)
 #define		IA32_FEATURE_CONTROL_IN_SMX	__BIT(1)
@@ -2043,7 +2055,7 @@ vmx_vcpu_run(struct nvmm_machine *mach, 
 	uint64_t exitcode;
 	uint64_t intstate;
 	uint64_t machgen;
-	int hcpu, s, ret;
+	int hcpu, ret;
 	bool launched;
 
 	vmx_vmcs_enter(vcpu);
@@ -2088,7 +2100,7 @@ vmx_vcpu_run(struct nvmm_machine *mach, 
 			cpudata->gtsc_want_update = false;
 		}
 
-		s = splhigh();
+		vmx_cli();
 		machgen = vmx_htlb_flush(machdata, cpudata);
 		lcr2(cpudata->gcr2);
 		if (launched) {
@@ -2098,7 +2110,7 @@ vmx_vcpu_run(struct nvmm_machine *mach, 
 		}
 		cpudata->gcr2 = rcr2();
 		vmx_htlb_flush_ack(cpudata, machgen);
-		splx(s);
+		vmx_sti();
 
 		if (__predict_false(ret != 0)) {
 			vmx_exit_invalid(exit, -1);

Index: src/sys/dev/nvmm/x86/nvmm_x86_svmfunc.S
diff -u src/sys/dev/nvmm/x86/nvmm_x86_svmfunc.S:1.3 src/sys/dev/nvmm/x86/nvmm_x86_svmfunc.S:1.4
--- src/sys/dev/nvmm/x86/nvmm_x86_svmfunc.S:1.3	Wed Apr 24 18:45:15 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_svmfunc.S	Sun Jul 19 06:36:37 2020
@@ -1,7 +1,7 @@
-/*	$NetBSD: nvmm_x86_svmfunc.S,v 1.3 2019/04/24 18:45:15 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svmfunc.S,v 1.4 2020/07/19 06:36:37 maxv Exp $	*/
 
 /*
- * Copyright (c) 2018 The NetBSD Foundation, Inc.
+ * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -136,9 +136,6 @@ ENTRY(svm_vmrun)
 	/* Save the Host GPRs. */
 	HOST_SAVE_GPRS
 
-	/* 

CVS commit: src/sys/dev/nvmm/x86

2020-07-18 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Sat Jul 18 20:56:53 UTC 2020

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_vmx.c

Log Message:
Now that the IDT is per-CPU, it must be saved/restored on each CPU
independently.


To generate a diff of this commit:
cvs rdiff -u -r1.62 -r1.63 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_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.62 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.63
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.62	Tue Jul 14 00:45:53 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Sat Jul 18 20:56:53 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.62 2020/07/14 00:45:53 yamaguchi Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.63 2020/07/18 20:56:53 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.62 2020/07/14 00:45:53 yamaguchi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.63 2020/07/18 20:56:53 maxv Exp $");
 
 #include 
 #include 
@@ -1921,6 +1921,7 @@ vmx_vcpu_guest_misc_enter(struct nvmm_cp
 	struct vmx_cpudata *cpudata = vcpu->cpudata;
 
 	/* This gets restored automatically by the CPU. */
+	vmx_vmwrite(VMCS_HOST_IDTR_BASE, (uint64_t)curcpu()->ci_idtvec.iv_idt);
 	vmx_vmwrite(VMCS_HOST_FS_BASE, rdmsr(MSR_FSBASE));
 	vmx_vmwrite(VMCS_HOST_CR3, rcr3());
 	vmx_vmwrite(VMCS_HOST_CR4, rcr4());
@@ -2698,8 +2699,7 @@ vmx_vcpu_init(struct nvmm_machine *mach,
 	struct vmcs *vmcs = cpudata->vmcs;
 	struct msr_entry *gmsr = cpudata->gmsr;
 	extern uint8_t vmx_resume_rip;
-	uint64_t rev, eptp, idt;
-	struct cpu_info *ci;
+	uint64_t rev, eptp;
 
 	rev = vmx_get_revision();
 
@@ -2766,9 +2766,6 @@ vmx_vcpu_init(struct nvmm_machine *mach,
 	vmx_vmwrite(VMCS_CR4_MASK, CR4_VMXE);
 
 	/* Set the Host state for resuming. */
-	ci = curcpu();
-	idt = (uint64_t)ci->ci_idtvec.iv_idt;
-
 	vmx_vmwrite(VMCS_HOST_RIP, (uint64_t)_resume_rip);
 	vmx_vmwrite(VMCS_HOST_CS_SELECTOR, GSEL(GCODE_SEL, SEL_KPL));
 	vmx_vmwrite(VMCS_HOST_SS_SELECTOR, GSEL(GDATA_SEL, SEL_KPL));
@@ -2779,7 +2776,6 @@ vmx_vcpu_init(struct nvmm_machine *mach,
 	vmx_vmwrite(VMCS_HOST_IA32_SYSENTER_CS, 0);
 	vmx_vmwrite(VMCS_HOST_IA32_SYSENTER_ESP, 0);
 	vmx_vmwrite(VMCS_HOST_IA32_SYSENTER_EIP, 0);
-	vmx_vmwrite(VMCS_HOST_IDTR_BASE, idt);
 	vmx_vmwrite(VMCS_HOST_IA32_PAT, rdmsr(MSR_CR_PAT));
 	vmx_vmwrite(VMCS_HOST_IA32_EFER, rdmsr(MSR_EFER));
 	vmx_vmwrite(VMCS_HOST_CR0, rcr0() & ~CR0_TS);



CVS commit: src/sys/dev/nvmm

2020-07-03 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Fri Jul  3 16:09:55 UTC 2020

Modified Files:
src/sys/dev/nvmm: nvmm.c nvmm_internal.h
src/sys/dev/nvmm/x86: nvmm_x86_svm.c nvmm_x86_vmx.c

Log Message:
Print the backend name when attaching.


To generate a diff of this commit:
cvs rdiff -u -r1.31 -r1.32 src/sys/dev/nvmm/nvmm.c
cvs rdiff -u -r1.15 -r1.16 src/sys/dev/nvmm/nvmm_internal.h
cvs rdiff -u -r1.62 -r1.63 src/sys/dev/nvmm/x86/nvmm_x86_svm.c
cvs rdiff -u -r1.60 -r1.61 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/nvmm.c
diff -u src/sys/dev/nvmm/nvmm.c:1.31 src/sys/dev/nvmm/nvmm.c:1.32
--- src/sys/dev/nvmm/nvmm.c:1.31	Thu Jun 25 17:01:19 2020
+++ src/sys/dev/nvmm/nvmm.c	Fri Jul  3 16:09:54 2020
@@ -1,7 +1,7 @@
-/*	$NetBSD: nvmm.c,v 1.31 2020/06/25 17:01:19 maxv Exp $	*/
+/*	$NetBSD: nvmm.c,v 1.32 2020/07/03 16:09:54 maxv Exp $	*/
 
 /*
- * Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
+ * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.31 2020/06/25 17:01:19 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.32 2020/07/03 16:09:54 maxv Exp $");
 
 #include 
 #include 
@@ -1209,7 +1209,8 @@ nvmm_attach(device_t parent, device_t se
 	error = nvmm_init();
 	if (error)
 		panic("%s: impossible", __func__);
-	aprint_normal_dev(self, "attached\n");
+	aprint_normal_dev(self, "attached, using backend %s\n",
+	nvmm_impl->name);
 }
 
 static int

Index: src/sys/dev/nvmm/nvmm_internal.h
diff -u src/sys/dev/nvmm/nvmm_internal.h:1.15 src/sys/dev/nvmm/nvmm_internal.h:1.16
--- src/sys/dev/nvmm/nvmm_internal.h:1.15	Sun May 24 08:08:49 2020
+++ src/sys/dev/nvmm/nvmm_internal.h	Fri Jul  3 16:09:54 2020
@@ -1,7 +1,7 @@
-/*	$NetBSD: nvmm_internal.h,v 1.15 2020/05/24 08:08:49 maxv Exp $	*/
+/*	$NetBSD: nvmm_internal.h,v 1.16 2020/07/03 16:09:54 maxv Exp $	*/
 
 /*
- * Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
+ * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -91,6 +91,7 @@ struct nvmm_machine {
 };
 
 struct nvmm_impl {
+	const char *name;
 	bool (*ident)(void);
 	void (*init)(void);
 	void (*fini)(void);

Index: src/sys/dev/nvmm/x86/nvmm_x86_svm.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.62 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.63
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.62	Sun May 24 08:08:49 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Fri Jul  3 16:09:54 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.62 2020/05/24 08:08:49 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.63 2020/07/03 16:09:54 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.62 2020/05/24 08:08:49 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.63 2020/07/03 16:09:54 maxv Exp $");
 
 #include 
 #include 
@@ -2430,6 +2430,7 @@ svm_capability(struct nvmm_capability *c
 }
 
 const struct nvmm_impl nvmm_x86_svm = {
+	.name = "x86-svm",
 	.ident = svm_ident,
 	.init = svm_init,
 	.fini = svm_fini,

Index: src/sys/dev/nvmm/x86/nvmm_x86_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.60 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.61
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.60	Thu Jun 18 16:31:15 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Fri Jul  3 16:09:54 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.60 2020/06/18 16:31:15 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.61 2020/07/03 16:09:54 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.60 2020/06/18 16:31:15 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.61 2020/07/03 16:09:54 maxv Exp $");
 
 #include 
 #include 
@@ -3392,6 +3392,7 @@ vmx_capability(struct nvmm_capability *c
 }
 
 const struct nvmm_impl nvmm_x86_vmx = {
+	.name = "x86-vmx",
 	.ident = vmx_ident,
 	.init = vmx_init,
 	.fini = vmx_fini,



CVS commit: src/sys/dev/nvmm/x86

2020-06-18 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Thu Jun 18 16:31:15 UTC 2020

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_vmx.c

Log Message:
style


To generate a diff of this commit:
cvs rdiff -u -r1.59 -r1.60 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_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.59 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.60
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.59	Sun May 24 08:08:49 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Thu Jun 18 16:31:15 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.59 2020/05/24 08:08:49 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.60 2020/06/18 16:31:15 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.59 2020/05/24 08:08:49 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.60 2020/06/18 16:31:15 maxv Exp $");
 
 #include 
 #include 
@@ -489,7 +489,7 @@ vmx_vmclear(paddr_t *pa)
 #define VMCS_HOST_IA32_SYSENTER_ESP		0x6C10
 #define VMCS_HOST_IA32_SYSENTER_EIP		0x6C12
 #define VMCS_HOST_RSP0x6C14
-#define VMCS_HOST_RIP0x6c16
+#define VMCS_HOST_RIP0x6C16
 
 /* VMX basic exit reasons. */
 #define VMCS_EXITCODE_EXC_NMI			0



CVS commit: src/sys/dev/nvmm

2020-05-24 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Sun May 24 08:08:49 UTC 2020

Modified Files:
src/sys/dev/nvmm: nvmm.c nvmm_internal.h
src/sys/dev/nvmm/x86: nvmm_x86_svm.c nvmm_x86_vmx.c

Log Message:
Gather the conditions to return from the VCPU loops in nvmm_return_needed(),
and use it in nvmm_do_vcpu_run() as well. This fixes two undesired behaviors:

 - When a VM initializes, the many nested page faults that need processing
   could cause the calling thread to occupy the CPU too much if we're unlucky
   and are only getting repeated nested page faults thousands of times in a
   row.

 - When the emulator calls nvmm_vcpu_run() and immediately sends a signal to
   stop the VCPU, it's better to check signals earlier and leave right away,
   rather than doing a round of VCPU run that could increase the time spent
   by the emulator waiting for the return.


To generate a diff of this commit:
cvs rdiff -u -r1.29 -r1.30 src/sys/dev/nvmm/nvmm.c
cvs rdiff -u -r1.14 -r1.15 src/sys/dev/nvmm/nvmm_internal.h
cvs rdiff -u -r1.61 -r1.62 src/sys/dev/nvmm/x86/nvmm_x86_svm.c
cvs rdiff -u -r1.58 -r1.59 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/nvmm.c
diff -u src/sys/dev/nvmm/nvmm.c:1.29 src/sys/dev/nvmm/nvmm.c:1.30
--- src/sys/dev/nvmm/nvmm.c:1.29	Thu May 21 07:43:23 2020
+++ src/sys/dev/nvmm/nvmm.c	Sun May 24 08:08:49 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm.c,v 1.29 2020/05/21 07:43:23 maxv Exp $	*/
+/*	$NetBSD: nvmm.c,v 1.30 2020/05/24 08:08:49 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.29 2020/05/21 07:43:23 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.30 2020/05/24 08:08:49 maxv Exp $");
 
 #include 
 #include 
@@ -570,11 +570,19 @@ nvmm_do_vcpu_run(struct nvmm_machine *ma
 	int ret;
 
 	while (1) {
+		/* Got a signal? Or pending resched? Leave. */
+		if (__predict_false(nvmm_return_needed())) {
+			exit->reason = NVMM_VCPU_EXIT_NONE;
+			return 0;
+		}
+
+		/* Run the VCPU. */
 		ret = (*nvmm_impl->vcpu_run)(mach, vcpu, exit);
 		if (__predict_false(ret != 0)) {
 			return ret;
 		}
 
+		/* Process nested page faults. */
 		if (__predict_true(exit->reason != NVMM_VCPU_EXIT_MEMORY)) {
 			break;
 		}

Index: src/sys/dev/nvmm/nvmm_internal.h
diff -u src/sys/dev/nvmm/nvmm_internal.h:1.14 src/sys/dev/nvmm/nvmm_internal.h:1.15
--- src/sys/dev/nvmm/nvmm_internal.h:1.14	Sat May  9 08:39:07 2020
+++ src/sys/dev/nvmm/nvmm_internal.h	Sun May 24 08:08:49 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_internal.h,v 1.14 2020/05/09 08:39:07 maxv Exp $	*/
+/*	$NetBSD: nvmm_internal.h,v 1.15 2020/05/24 08:08:49 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
@@ -121,4 +121,16 @@ struct nvmm_impl {
 extern const struct nvmm_impl nvmm_x86_svm;
 extern const struct nvmm_impl nvmm_x86_vmx;
 
+static inline bool
+nvmm_return_needed(void)
+{
+	if (preempt_needed()) {
+		return true;
+	}
+	if (curlwp->l_flag & LW_USERRET) {
+		return true;
+	}
+	return false;
+}
+
 #endif /* _NVMM_INTERNAL_H_ */

Index: src/sys/dev/nvmm/x86/nvmm_x86_svm.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.61 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.62
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.61	Sun May 10 06:24:16 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Sun May 24 08:08:49 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.61 2020/05/10 06:24:16 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.62 2020/05/24 08:08:49 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.61 2020/05/10 06:24:16 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.62 2020/05/24 08:08:49 maxv Exp $");
 
 #include 
 #include 
@@ -1459,10 +1459,7 @@ svm_vcpu_run(struct nvmm_machine *mach, 
 		}
 
 		/* If no reason to return to userland, keep rolling. */
-		if (preempt_needed()) {
-			break;
-		}
-		if (curlwp->l_flag & LW_USERRET) {
+		if (nvmm_return_needed()) {
 			break;
 		}
 		if (exit->reason != NVMM_VCPU_EXIT_NONE) {

Index: src/sys/dev/nvmm/x86/nvmm_x86_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.58 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.59
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.58	Thu May 21 07:36:16 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Sun May 24 08:08:49 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.58 2020/05/21 07:36:16 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.59 2020/05/24 08:08:49 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.58 2020/05/21 07:36:16 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.59 2020/05/24 08:08:49 maxv Exp $");
 
 #include 
 #include 
@@ -2181,10 +2181,7 @@ 

CVS commit: src/sys/dev/nvmm

2020-05-21 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Thu May 21 07:43:23 UTC 2020

Modified Files:
src/sys/dev/nvmm: nvmm.c

Log Message:
Complete rev1.26: reset nvmm_impl to NULL in nvmm_fini().


To generate a diff of this commit:
cvs rdiff -u -r1.28 -r1.29 src/sys/dev/nvmm/nvmm.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/nvmm.c
diff -u src/sys/dev/nvmm/nvmm.c:1.28 src/sys/dev/nvmm/nvmm.c:1.29
--- src/sys/dev/nvmm/nvmm.c:1.28	Sat May  9 08:39:07 2020
+++ src/sys/dev/nvmm/nvmm.c	Thu May 21 07:43:23 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm.c,v 1.28 2020/05/09 08:39:07 maxv Exp $	*/
+/*	$NetBSD: nvmm.c,v 1.29 2020/05/21 07:43:23 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.28 2020/05/09 08:39:07 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.29 2020/05/21 07:43:23 maxv Exp $");
 
 #include 
 #include 
@@ -998,6 +998,7 @@ nvmm_fini(void)
 	}
 
 	(*nvmm_impl->fini)();
+	nvmm_impl = NULL;
 }
 
 /* -- */



CVS commit: src/sys/dev/nvmm/x86

2020-05-21 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Thu May 21 07:36:16 UTC 2020

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_vmx.c

Log Message:
Improve the CPUID emulation on nvmm-intel: limit the highest basic and
hypervisor leaves.


To generate a diff of this commit:
cvs rdiff -u -r1.57 -r1.58 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_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.57 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.58
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.57	Sun May 10 06:24:16 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Thu May 21 07:36:16 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.57 2020/05/10 06:24:16 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.58 2020/05/21 07:36:16 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.57 2020/05/10 06:24:16 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.58 2020/05/21 07:36:16 maxv Exp $");
 
 #include 
 #include 
@@ -1137,7 +1137,22 @@ error:
 	vmx_exit_invalid(exit, VMCS_EXITCODE_EXC_NMI);
 }
 
+#define VMX_CPUID_MAX_BASIC		0x16
 #define VMX_CPUID_MAX_HYPERVISOR	0x4000
+#define VMX_CPUID_MAX_EXTENDED		0x8008
+static uint32_t vmx_cpuid_max_basic __read_mostly;
+
+static void
+vmx_inkernel_exec_cpuid(struct vmx_cpudata *cpudata, uint64_t eax, uint64_t ecx)
+{
+	u_int descs[4];
+
+	x86_cpuid2(eax, ecx, descs);
+	cpudata->gprs[NVMM_X64_GPR_RAX] = descs[0];
+	cpudata->gprs[NVMM_X64_GPR_RBX] = descs[1];
+	cpudata->gprs[NVMM_X64_GPR_RCX] = descs[2];
+	cpudata->gprs[NVMM_X64_GPR_RDX] = descs[3];
+}
 
 static void
 vmx_inkernel_handle_cpuid(struct nvmm_machine *mach, struct nvmm_cpu *vcpu,
@@ -1147,7 +1162,22 @@ vmx_inkernel_handle_cpuid(struct nvmm_ma
 	unsigned int ncpus;
 	uint64_t cr4;
 
+	if (eax < 0x4000) {
+		if (__predict_false(eax > vmx_cpuid_max_basic)) {
+			eax = vmx_cpuid_max_basic;
+			vmx_inkernel_exec_cpuid(cpudata, eax, ecx);
+		}
+	} else if (eax < 0x8000) {
+		if (__predict_false(eax > VMX_CPUID_MAX_HYPERVISOR)) {
+			eax = vmx_cpuid_max_basic;
+			vmx_inkernel_exec_cpuid(cpudata, eax, ecx);
+		}
+	}
+
 	switch (eax) {
+	case 0x:
+		cpudata->gprs[NVMM_X64_GPR_RAX] = vmx_cpuid_max_basic;
+		break;
 	case 0x0001:
 		cpudata->gprs[NVMM_X64_GPR_RAX] &= nvmm_cpuid_0001.eax;
 
@@ -1310,6 +1340,15 @@ vmx_inkernel_handle_cpuid(struct nvmm_ma
 		cpudata->gprs[NVMM_X64_GPR_RCX] &= nvmm_cpuid_8001.ecx;
 		cpudata->gprs[NVMM_X64_GPR_RDX] &= nvmm_cpuid_8001.edx;
 		break;
+	case 0x8002: /* Processor Brand String */
+	case 0x8003: /* Processor Brand String */
+	case 0x8004: /* Processor Brand String */
+	case 0x8005: /* Reserved Zero */
+	case 0x8006: /* Cache Information */
+	case 0x8007: /* TSC Information */
+	case 0x8008: /* Address Sizes */
+		break;
+
 	default:
 		break;
 	}
@@ -1333,18 +1372,11 @@ vmx_exit_cpuid(struct nvmm_machine *mach
 	struct vmx_cpudata *cpudata = vcpu->cpudata;
 	struct nvmm_vcpu_conf_cpuid *cpuid;
 	uint64_t eax, ecx;
-	u_int descs[4];
 	size_t i;
 
 	eax = cpudata->gprs[NVMM_X64_GPR_RAX];
 	ecx = cpudata->gprs[NVMM_X64_GPR_RCX];
-	x86_cpuid2(eax, ecx, descs);
-
-	cpudata->gprs[NVMM_X64_GPR_RAX] = descs[0];
-	cpudata->gprs[NVMM_X64_GPR_RBX] = descs[1];
-	cpudata->gprs[NVMM_X64_GPR_RCX] = descs[2];
-	cpudata->gprs[NVMM_X64_GPR_RDX] = descs[3];
-
+	vmx_inkernel_exec_cpuid(cpudata, eax, ecx);
 	vmx_inkernel_handle_cpuid(mach, vcpu, eax, ecx);
 
 	for (i = 0; i < VMX_NCPUIDS; i++) {
@@ -3279,6 +3311,9 @@ vmx_init(void)
 	/* Init the XCR0 mask. */
 	vmx_xcr0_mask = VMX_XCR0_MASK_DEFAULT & x86_xsave_features;
 
+	/* Init the max CPUID leaves. */
+	vmx_cpuid_max_basic = uimin(cpuid_level, VMX_CPUID_MAX_BASIC);
+
 	/* Init the TLB flush op, the EPT flush op and the EPTP type. */
 	msr = rdmsr(MSR_IA32_VMX_EPT_VPID_CAP);
 	if ((msr & IA32_VMX_EPT_VPID_INVVPID_CONTEXT) != 0) {



CVS commit: src/sys/dev/nvmm/x86

2020-05-10 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Sun May 10 06:24:16 UTC 2020

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_svm.c nvmm_x86_vmx.c

Log Message:
Respect the convention for the hypervisor information: return the highest
hypervisor leaf in 0x4000.EAX.


To generate a diff of this commit:
cvs rdiff -u -r1.60 -r1.61 src/sys/dev/nvmm/x86/nvmm_x86_svm.c
cvs rdiff -u -r1.56 -r1.57 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.60 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.61
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.60	Sat May  9 16:18:57 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Sun May 10 06:24:16 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.60 2020/05/09 16:18:57 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.61 2020/05/10 06:24:16 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.60 2020/05/09 16:18:57 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.61 2020/05/10 06:24:16 maxv Exp $");
 
 #include 
 #include 
@@ -771,6 +771,8 @@ svm_inkernel_advance(struct vmcb *vmcb)
 	vmcb->ctrl.intr &= ~VMCB_CTRL_INTR_SHADOW;
 }
 
+#define SVM_CPUID_MAX_HYPERVISOR	0x4000
+
 static void
 svm_inkernel_handle_cpuid(struct nvmm_cpu *vcpu, uint64_t eax, uint64_t ecx)
 {
@@ -856,6 +858,7 @@ svm_inkernel_handle_cpuid(struct nvmm_cp
 		break;
 
 	case 0x4000: /* Hypervisor Information */
+		cpudata->vmcb->state.rax = SVM_CPUID_MAX_HYPERVISOR;
 		cpudata->gprs[NVMM_X64_GPR_RBX] = 0;
 		cpudata->gprs[NVMM_X64_GPR_RCX] = 0;
 		cpudata->gprs[NVMM_X64_GPR_RDX] = 0;

Index: src/sys/dev/nvmm/x86/nvmm_x86_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.56 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.57
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.56	Sat May  9 16:18:57 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Sun May 10 06:24:16 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.56 2020/05/09 16:18:57 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.57 2020/05/10 06:24:16 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.56 2020/05/09 16:18:57 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.57 2020/05/10 06:24:16 maxv Exp $");
 
 #include 
 #include 
@@ -1137,6 +1137,8 @@ error:
 	vmx_exit_invalid(exit, VMCS_EXITCODE_EXC_NMI);
 }
 
+#define VMX_CPUID_MAX_HYPERVISOR	0x4000
+
 static void
 vmx_inkernel_handle_cpuid(struct nvmm_machine *mach, struct nvmm_cpu *vcpu,
 uint64_t eax, uint64_t ecx)
@@ -1293,6 +1295,7 @@ vmx_inkernel_handle_cpuid(struct nvmm_ma
 		break;
 
 	case 0x4000: /* Hypervisor Information */
+		cpudata->gprs[NVMM_X64_GPR_RAX] = VMX_CPUID_MAX_HYPERVISOR;
 		cpudata->gprs[NVMM_X64_GPR_RBX] = 0;
 		cpudata->gprs[NVMM_X64_GPR_RCX] = 0;
 		cpudata->gprs[NVMM_X64_GPR_RDX] = 0;



CVS commit: src/sys/dev/nvmm/x86

2020-05-09 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Sat May  9 16:18:57 UTC 2020

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86.c nvmm_x86_svm.c nvmm_x86_vmx.c

Log Message:
Improve the CPUID emulation of basic leaves:
 - Hide DCA and PQM, they cannot be used in guests.
 - On Intel, explicitly handle each basic leaf until 0x16.
 - On AMD, explicitly handle each basic leaf until 0x0D.


To generate a diff of this commit:
cvs rdiff -u -r1.8 -r1.9 src/sys/dev/nvmm/x86/nvmm_x86.c
cvs rdiff -u -r1.59 -r1.60 src/sys/dev/nvmm/x86/nvmm_x86_svm.c
cvs rdiff -u -r1.55 -r1.56 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.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86.c:1.8 src/sys/dev/nvmm/x86/nvmm_x86.c:1.9
--- src/sys/dev/nvmm/x86/nvmm_x86.c:1.8	Sat Nov 16 17:53:46 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86.c	Sat May  9 16:18:57 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86.c,v 1.8 2019/11/16 17:53:46 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86.c,v 1.9 2020/05/09 16:18:57 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86.c,v 1.8 2019/11/16 17:53:46 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86.c,v 1.9 2020/05/09 16:18:57 maxv Exp $");
 
 #include 
 #include 
@@ -233,18 +233,18 @@ const struct nvmm_x86_cpuid_mask nvmm_cp
 	.eax = ~0,
 	.ebx = ~0,
 	.ecx =
-	/* Excluded: MONITOR, VMX, SMX, EST, TM2, PDCM, PCID, X2APIC,
+	/* Excluded: MONITOR, VMX, SMX, EST, TM2, PDCM, PCID, DCA, X2APIC,
 	 * DEADLINE, RAZ. */
 	CPUID2_SSE3 | CPUID2_PCLMUL |
 	CPUID2_DTES64 | CPUID2_DS_CPL |
 	CPUID2_SSSE3 | CPUID2_CID |
 	CPUID2_SDBG | CPUID2_FMA |
 	CPUID2_CX16 | CPUID2_xTPR |
-	CPUID2_DCA | CPUID2_SSE41 |
-	CPUID2_SSE42 | CPUID2_MOVBE |
-	CPUID2_POPCNT | CPUID2_AES |
-	CPUID2_XSAVE | CPUID2_OSXSAVE |
-	CPUID2_F16C | CPUID2_RDRAND,
+	CPUID2_SSE41 | CPUID2_SSE42 |
+	CPUID2_MOVBE | CPUID2_POPCNT |
+	CPUID2_AES | CPUID2_XSAVE |
+	CPUID2_OSXSAVE | CPUID2_F16C |
+	CPUID2_RDRAND,
 	.edx =
 	/* Excluded: MCE, MTRR, MCA, DS, ACPI, TM. */
 	CPUID_FPU | CPUID_VME |
@@ -265,16 +265,16 @@ const struct nvmm_x86_cpuid_mask nvmm_cp
 const struct nvmm_x86_cpuid_mask nvmm_cpuid_0007 = {
 	.eax = ~0,
 	.ebx =
-	/* Excluded: TSC_ADJUST, AVX2, INVPCID, AVX512*, PT, SHA. */
+	/* Excluded: TSC_ADJUST, AVX2, INVPCID, QM, AVX512*, PT, SHA. */
 	CPUID_SEF_FSGSBASE |
 	CPUID_SEF_SGX | CPUID_SEF_BMI1 |
 	CPUID_SEF_HLE | CPUID_SEF_FDPEXONLY |
 	CPUID_SEF_SMEP | CPUID_SEF_BMI2 |
 	CPUID_SEF_ERMS | CPUID_SEF_RTM |
-	CPUID_SEF_QM | CPUID_SEF_FPUCSDS |
-	CPUID_SEF_PQE | CPUID_SEF_RDSEED |
-	CPUID_SEF_ADX | CPUID_SEF_SMAP |
-	CPUID_SEF_CLFLUSHOPT | CPUID_SEF_CLWB,
+	CPUID_SEF_FPUCSDS | CPUID_SEF_PQE |
+	CPUID_SEF_RDSEED | CPUID_SEF_ADX |
+	CPUID_SEF_SMAP | CPUID_SEF_CLFLUSHOPT |
+	CPUID_SEF_CLWB,
 	.ecx =
 	/* Excluded: AVX512*, MAWAU, RDPID. */
 	CPUID_SEF_PREFETCHWT1 | CPUID_SEF_UMIP |

Index: src/sys/dev/nvmm/x86/nvmm_x86_svm.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.59 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.60
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.59	Thu Apr 30 16:50:17 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Sat May  9 16:18:57 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.59 2020/04/30 16:50:17 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.60 2020/05/09 16:18:57 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.59 2020/04/30 16:50:17 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.60 2020/05/09 16:18:57 maxv Exp $");
 
 #include 
 #include 
@@ -796,20 +796,33 @@ svm_inkernel_handle_cpuid(struct nvmm_cp
 			cpudata->gprs[NVMM_X64_GPR_RCX] &= ~CPUID2_OSXSAVE;
 		}
 		break;
-	case 0x0005:
-	case 0x0006:
+	case 0x0002: /* Empty */
+	case 0x0003: /* Empty */
+	case 0x0004: /* Empty */
+	case 0x0005: /* Monitor/MWait */
+	case 0x0006: /* Power Management Related Features */
 		cpudata->vmcb->state.rax = 0;
 		cpudata->gprs[NVMM_X64_GPR_RBX] = 0;
 		cpudata->gprs[NVMM_X64_GPR_RCX] = 0;
 		cpudata->gprs[NVMM_X64_GPR_RDX] = 0;
 		break;
-	case 0x0007:
+	case 0x0007: /* Structured Extended Features */
 		cpudata->vmcb->state.rax &= nvmm_cpuid_0007.eax;
 		cpudata->gprs[NVMM_X64_GPR_RBX] &= nvmm_cpuid_0007.ebx;
 		cpudata->gprs[NVMM_X64_GPR_RCX] &= nvmm_cpuid_0007.ecx;
 		cpudata->gprs[NVMM_X64_GPR_RDX] &= nvmm_cpuid_0007.edx;
 		break;
-	case 0x000D:
+	case 0x0008: /* Empty */
+	case 0x0009: /* Empty */
+	case 0x000A: /* Empty */
+	case 0x000B: /* Empty */
+	case 0x000C: /* Empty */
+		cpudata->vmcb->state.rax = 0;
+		cpudata->gprs[NVMM_X64_GPR_RBX] = 

CVS commit: src/sys/dev/nvmm

2020-05-09 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Sat May  9 08:39:07 UTC 2020

Modified Files:
src/sys/dev/nvmm: nvmm.c nvmm_internal.h
src/sys/dev/nvmm/x86: nvmm_x86_vmx.c

Log Message:
On Intel CPUs, CPUID leaf 0xB, too, provides topology information, so
filter it correctly, to avoid inconsistencies if the host has SMT.

This fixes HaikuOS which fetches SMT information from there and would
panic because of the inconsistencies.


To generate a diff of this commit:
cvs rdiff -u -r1.27 -r1.28 src/sys/dev/nvmm/nvmm.c
cvs rdiff -u -r1.13 -r1.14 src/sys/dev/nvmm/nvmm_internal.h
cvs rdiff -u -r1.54 -r1.55 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/nvmm.c
diff -u src/sys/dev/nvmm/nvmm.c:1.27 src/sys/dev/nvmm/nvmm.c:1.28
--- src/sys/dev/nvmm/nvmm.c:1.27	Thu Apr 30 16:50:17 2020
+++ src/sys/dev/nvmm/nvmm.c	Sat May  9 08:39:07 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm.c,v 1.27 2020/04/30 16:50:17 maxv Exp $	*/
+/*	$NetBSD: nvmm.c,v 1.28 2020/05/09 08:39:07 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.27 2020/04/30 16:50:17 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.28 2020/05/09 08:39:07 maxv Exp $");
 
 #include 
 #include 
@@ -413,6 +413,8 @@ nvmm_vcpu_create(struct nvmm_owner *owne
 
 	nvmm_vcpu_put(vcpu);
 
+	atomic_inc_uint(>ncpus);
+
 out:
 	nvmm_machine_put(mach);
 	return error;
@@ -437,6 +439,8 @@ nvmm_vcpu_destroy(struct nvmm_owner *own
 	nvmm_vcpu_free(mach, vcpu);
 	nvmm_vcpu_put(vcpu);
 
+	atomic_dec_uint(>ncpus);
+
 out:
 	nvmm_machine_put(mach);
 	return error;

Index: src/sys/dev/nvmm/nvmm_internal.h
diff -u src/sys/dev/nvmm/nvmm_internal.h:1.13 src/sys/dev/nvmm/nvmm_internal.h:1.14
--- src/sys/dev/nvmm/nvmm_internal.h:1.13	Wed Oct 23 07:01:11 2019
+++ src/sys/dev/nvmm/nvmm_internal.h	Sat May  9 08:39:07 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_internal.h,v 1.13 2019/10/23 07:01:11 maxv Exp $	*/
+/*	$NetBSD: nvmm_internal.h,v 1.14 2020/05/09 08:39:07 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
@@ -83,6 +83,7 @@ struct nvmm_machine {
 	struct nvmm_hmapping hmap[NVMM_MAX_HMAPPINGS];
 
 	/* CPU */
+	volatile unsigned int ncpus;
 	struct nvmm_cpu cpus[NVMM_MAX_VCPUS];
 
 	/* Implementation-specific */

Index: src/sys/dev/nvmm/x86/nvmm_x86_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.54 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.55
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.54	Thu Apr 30 16:56:23 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Sat May  9 08:39:07 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.54 2020/04/30 16:56:23 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.55 2020/05/09 08:39:07 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.54 2020/04/30 16:56:23 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.55 2020/05/09 08:39:07 maxv Exp $");
 
 #include 
 #include 
@@ -39,6 +39,7 @@ __KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -1137,9 +1138,11 @@ error:
 }
 
 static void
-vmx_inkernel_handle_cpuid(struct nvmm_cpu *vcpu, uint64_t eax, uint64_t ecx)
+vmx_inkernel_handle_cpuid(struct nvmm_machine *mach, struct nvmm_cpu *vcpu,
+uint64_t eax, uint64_t ecx)
 {
 	struct vmx_cpudata *cpudata = vcpu->cpudata;
+	unsigned int ncpus;
 	uint64_t cr4;
 
 	switch (eax) {
@@ -1186,6 +1189,33 @@ vmx_inkernel_handle_cpuid(struct nvmm_cp
 		cpudata->gprs[NVMM_X64_GPR_RCX] = 0;
 		cpudata->gprs[NVMM_X64_GPR_RDX] = 0;
 		break;
+	case 0x000B:
+		switch (ecx) {
+		case 0: /* Threads */
+			cpudata->gprs[NVMM_X64_GPR_RAX] = 0;
+			cpudata->gprs[NVMM_X64_GPR_RBX] = 0;
+			cpudata->gprs[NVMM_X64_GPR_RCX] =
+			__SHIFTIN(ecx, CPUID_TOP_LVLNUM) |
+			__SHIFTIN(CPUID_TOP_LVLTYPE_SMT, CPUID_TOP_LVLTYPE);
+			cpudata->gprs[NVMM_X64_GPR_RDX] = vcpu->cpuid;
+			break;
+		case 1: /* Cores */
+			ncpus = atomic_load_relaxed(>ncpus);
+			cpudata->gprs[NVMM_X64_GPR_RAX] = ilog2(ncpus);
+			cpudata->gprs[NVMM_X64_GPR_RBX] = ncpus;
+			cpudata->gprs[NVMM_X64_GPR_RCX] =
+			__SHIFTIN(ecx, CPUID_TOP_LVLNUM) |
+			__SHIFTIN(CPUID_TOP_LVLTYPE_CORE, CPUID_TOP_LVLTYPE);
+			cpudata->gprs[NVMM_X64_GPR_RDX] = vcpu->cpuid;
+			break;
+		default:
+			cpudata->gprs[NVMM_X64_GPR_RAX] = 0;
+			cpudata->gprs[NVMM_X64_GPR_RBX] = 0;
+			cpudata->gprs[NVMM_X64_GPR_RCX] = 0; /* LVLTYPE_INVAL */
+			cpudata->gprs[NVMM_X64_GPR_RDX] = 0;
+			break;
+		}
+		break;
 	case 0x000D:
 		if (vmx_xcr0_mask == 0) {
 			break;
@@ -1267,7 +1297,7 @@ vmx_exit_cpuid(struct nvmm_machine *mach
 	cpudata->gprs[NVMM_X64_GPR_RCX] = descs[2];
 	cpudata->gprs[NVMM_X64_GPR_RDX] = descs[3];
 
-	vmx_inkernel_handle_cpuid(vcpu, eax, ecx);
+	

CVS commit: src/sys/dev/nvmm/x86

2020-04-30 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Thu Apr 30 16:56:24 UTC 2020

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_vmx.c

Log Message:
If we were processing a software int/excp, and got a VMEXIT in the middle,
we must also reflect the instruction length, otherwise the next VMENTER
fails and Qemu shuts the guest down.


To generate a diff of this commit:
cvs rdiff -u -r1.53 -r1.54 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_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.53 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.54
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.53	Thu Apr 30 16:50:17 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Thu Apr 30 16:56:23 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.53 2020/04/30 16:50:17 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.54 2020/04/30 16:56:23 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.53 2020/04/30 16:50:17 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.54 2020/04/30 16:56:23 maxv Exp $");
 
 #include 
 #include 
@@ -369,7 +369,7 @@ vmx_vmclear(paddr_t *pa)
 #define		INTR_INFO_ERROR			__BIT(11)
 #define		INTR_INFO_VALID			__BIT(31)
 #define VMCS_ENTRY_EXCEPTION_ERROR		0x4018
-#define VMCS_ENTRY_INST_LENGTH			0x401A
+#define VMCS_ENTRY_INSTRUCTION_LENGTH		0x401A
 #define VMCS_TPR_THRESHOLD			0x401C
 #define VMCS_PROCBASED_CTLS2			0x401E
 #define		PROC_CTLS2_VIRT_APIC_ACCESSES	__BIT(0)
@@ -1896,7 +1896,7 @@ vmx_htlb_flush_ack(struct vmx_cpudata *c
 static inline void
 vmx_exit_evt(struct vmx_cpudata *cpudata)
 {
-	uint64_t info, err;
+	uint64_t info, err, inslen;
 
 	cpudata->evt_pending = false;
 
@@ -1909,6 +1909,14 @@ vmx_exit_evt(struct vmx_cpudata *cpudata
 	vmx_vmwrite(VMCS_ENTRY_INTR_INFO, info);
 	vmx_vmwrite(VMCS_ENTRY_EXCEPTION_ERROR, err);
 
+	switch (__SHIFTOUT(info, INTR_INFO_TYPE)) {
+	case INTR_TYPE_SW_INT:
+	case INTR_TYPE_PRIV_SW_EXC:
+	case INTR_TYPE_SW_EXC:
+		inslen = vmx_vmread(VMCS_EXIT_INSTRUCTION_LENGTH);
+		vmx_vmwrite(VMCS_ENTRY_INSTRUCTION_LENGTH, inslen);
+	}
+
 	cpudata->evt_pending = true;
 }
 



CVS commit: src/sys/dev/nvmm

2020-04-30 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Thu Apr 30 16:50:18 UTC 2020

Modified Files:
src/sys/dev/nvmm: nvmm.c
src/sys/dev/nvmm/x86: nvmm_x86_svm.c nvmm_x86_vmx.c

Log Message:
When the identification fails, print the reason.


To generate a diff of this commit:
cvs rdiff -u -r1.26 -r1.27 src/sys/dev/nvmm/nvmm.c
cvs rdiff -u -r1.58 -r1.59 src/sys/dev/nvmm/x86/nvmm_x86_svm.c
cvs rdiff -u -r1.52 -r1.53 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/nvmm.c
diff -u src/sys/dev/nvmm/nvmm.c:1.26 src/sys/dev/nvmm/nvmm.c:1.27
--- src/sys/dev/nvmm/nvmm.c:1.26	Sun Apr 26 19:31:36 2020
+++ src/sys/dev/nvmm/nvmm.c	Thu Apr 30 16:50:17 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm.c,v 1.26 2020/04/26 19:31:36 maxv Exp $	*/
+/*	$NetBSD: nvmm.c,v 1.27 2020/04/30 16:50:17 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.26 2020/04/26 19:31:36 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.27 2020/04/30 16:50:17 maxv Exp $");
 
 #include 
 #include 
@@ -961,7 +961,7 @@ nvmm_init(void)
 		break;
 	}
 	if (nvmm_impl == NULL) {
-		printf("[!] No implementation found\n");
+		printf("NVMM: CPU not supported\n");
 		return ENOTSUP;
 	}
 

Index: src/sys/dev/nvmm/x86/nvmm_x86_svm.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.58 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.59
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.58	Sun Mar 22 00:16:16 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Thu Apr 30 16:50:17 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.58 2020/03/22 00:16:16 ad Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.59 2020/04/30 16:50:17 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.58 2020/03/22 00:16:16 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.59 2020/04/30 16:50:17 maxv Exp $");
 
 #include 
 #include 
@@ -2257,21 +2257,25 @@ svm_ident(void)
 		return false;
 	}
 	if (!(cpu_feature[3] & CPUID_SVM)) {
+		printf("NVMM: SVM not supported\n");
 		return false;
 	}
 
 	if (curcpu()->ci_max_ext_cpuid < 0x800a) {
+		printf("NVMM: CPUID leaf not available\n");
 		return false;
 	}
 	x86_cpuid(0x800a, descs);
 
 	/* Want Nested Paging. */
 	if (!(descs[3] & CPUID_AMD_SVM_NP)) {
+		printf("NVMM: SVM-NP not supported\n");
 		return false;
 	}
 
 	/* Want nRIP. */
 	if (!(descs[3] & CPUID_AMD_SVM_NRIPS)) {
+		printf("NVMM: SVM-NRIPS not supported\n");
 		return false;
 	}
 
@@ -2279,6 +2283,7 @@ svm_ident(void)
 
 	msr = rdmsr(MSR_VMCR);
 	if ((msr & VMCR_SVMED) && (msr & VMCR_LOCK)) {
+		printf("NVMM: SVM disabled in BIOS\n");
 		return false;
 	}
 

Index: src/sys/dev/nvmm/x86/nvmm_x86_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.52 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.53
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.52	Sun Mar 22 00:16:16 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Thu Apr 30 16:50:17 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.52 2020/03/22 00:16:16 ad Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.53 2020/04/30 16:50:17 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.52 2020/03/22 00:16:16 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.53 2020/04/30 16:50:17 maxv Exp $");
 
 #include 
 #include 
@@ -3001,17 +3001,21 @@ vmx_ident(void)
 
 	msr = rdmsr(MSR_IA32_FEATURE_CONTROL);
 	if ((msr & IA32_FEATURE_CONTROL_LOCK) == 0) {
+		printf("NVMM: VMX disabled in BIOS\n");
 		return false;
 	}
 	if ((msr & IA32_FEATURE_CONTROL_OUT_SMX) == 0) {
+		printf("NVMM: VMX disabled in BIOS\n");
 		return false;
 	}
 
 	msr = rdmsr(MSR_IA32_VMX_BASIC);
 	if ((msr & IA32_VMX_BASIC_IO_REPORT) == 0) {
+		printf("NVMM: I/O reporting not supported\n");
 		return false;
 	}
 	if (__SHIFTOUT(msr, IA32_VMX_BASIC_MEM_TYPE) != MEM_TYPE_WB) {
+		printf("NVMM: WB memory not supported\n");
 		return false;
 	}
 
@@ -3020,6 +3024,7 @@ vmx_ident(void)
 	vmx_cr0_fixed1 = rdmsr(MSR_IA32_VMX_CR0_FIXED1) | (CR0_PG|CR0_PE);
 	ret = vmx_check_cr(rcr0(), vmx_cr0_fixed0, vmx_cr0_fixed1);
 	if (ret == -1) {
+		printf("NVMM: CR0 requirements not satisfied\n");
 		return false;
 	}
 
@@ -3027,6 +3032,7 @@ vmx_ident(void)
 	vmx_cr4_fixed1 = rdmsr(MSR_IA32_VMX_CR4_FIXED1);
 	ret = vmx_check_cr(rcr4() | CR4_VMXE, vmx_cr4_fixed0, vmx_cr4_fixed1);
 	if (ret == -1) {
+		printf("NVMM: CR4 requirements not satisfied\n");
 		return false;
 	}
 
@@ -3036,6 +3042,7 @@ vmx_ident(void)
 	VMX_PINBASED_CTLS_ONE, VMX_PINBASED_CTLS_ZERO,
 	_pinbased_ctls);
 	if (ret == -1) {
+		printf("NVMM: pin-based-ctls requirements not satisfied\n");
 		return false;
 	}
 	ret = vmx_init_ctls(
@@ -3043,6 +3050,7 @@ vmx_ident(void)
 	

CVS commit: src/sys/dev/nvmm

2020-04-26 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Sun Apr 26 19:31:36 UTC 2020

Modified Files:
src/sys/dev/nvmm: nvmm.c

Log Message:
In nvmm_open(), make sure an implementation was found. This fixes an
initialization bug triggerable in certain conditions.

If you build nvmm inside the kernel, AND have a cpu that is not supported,
AND run nvmmctl (or qemu-nvmm, both being the only binaries in the "nvmm"
group), you get a page fault.

This is because when nvmm is built inside the kernel, the kernel registers
nvmm_cdevsw behind nvmm's back. The ioctl is therefore always accessible,
and will hit NULL pointers if nvmm_init() failed.

Problem reported by Andrei M. on netbsd-users@, thanks.


To generate a diff of this commit:
cvs rdiff -u -r1.25 -r1.26 src/sys/dev/nvmm/nvmm.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/nvmm.c
diff -u src/sys/dev/nvmm/nvmm.c:1.25 src/sys/dev/nvmm/nvmm.c:1.26
--- src/sys/dev/nvmm/nvmm.c:1.25	Mon Oct 28 09:00:08 2019
+++ src/sys/dev/nvmm/nvmm.c	Sun Apr 26 19:31:36 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm.c,v 1.25 2019/10/28 09:00:08 maxv Exp $	*/
+/*	$NetBSD: nvmm.c,v 1.26 2020/04/26 19:31:36 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.25 2019/10/28 09:00:08 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.26 2020/04/26 19:31:36 maxv Exp $");
 
 #include 
 #include 
@@ -1040,6 +1040,8 @@ nvmm_open(dev_t dev, int flags, int type
 	struct file *fp;
 	int error, fd;
 
+	if (__predict_false(nvmm_impl == NULL))
+		return ENXIO;
 	if (minor(dev) != 0)
 		return EXDEV;
 	if (!(flags & O_CLOEXEC))



CVS commit: src/sys/dev/nvmm/x86

2020-03-12 Thread Tobias Nygren
Module Name:src
Committed By:   tnn
Date:   Thu Mar 12 13:01:59 UTC 2020

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_vmx.c

Log Message:
vmx_vmptrst(): only used when DIAGNOSTIC


To generate a diff of this commit:
cvs rdiff -u -r1.49 -r1.50 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_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.49 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.50
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.49	Fri Feb 21 00:26:22 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Thu Mar 12 13:01:59 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.49 2020/02/21 00:26:22 joerg Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.50 2020/03/12 13:01:59 tnn Exp $	*/
 
 /*
  * Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.49 2020/02/21 00:26:22 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.50 2020/03/12 13:01:59 tnn Exp $");
 
 #include 
 #include 
@@ -134,6 +134,7 @@ vmx_vmwrite(uint64_t field, uint64_t val
 	);
 }
 
+#ifdef DIAGNOSTIC
 static inline paddr_t
 vmx_vmptrst(void)
 {
@@ -148,6 +149,7 @@ vmx_vmptrst(void)
 
 	return pa;
 }
+#endif
 
 static inline void
 vmx_vmptrld(paddr_t *pa)



CVS commit: src/sys/dev/nvmm/x86

2020-01-09 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Thu Jan  9 16:27:57 UTC 2020

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_vmx.c

Log Message:
Registering the host's CR0 is done outside of the VCPU loop, so it must be
cleared because it is also cleared inside the loop.

Not clearing it could trigger DNAs on VMEXITs, because STTS/CLTS are still
here as part of debugging since my FPU overhaul.


To generate a diff of this commit:
cvs rdiff -u -r1.47 -r1.48 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_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.47 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.48
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.47	Thu Jan  9 16:20:12 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Thu Jan  9 16:27:57 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.47 2020/01/09 16:20:12 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.48 2020/01/09 16:27:57 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.47 2020/01/09 16:20:12 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.48 2020/01/09 16:27:57 maxv Exp $");
 
 #include 
 #include 
@@ -2664,7 +2664,7 @@ vmx_vcpu_init(struct nvmm_machine *mach,
 	vmx_vmwrite(VMCS_HOST_IDTR_BASE, (uint64_t)idt);
 	vmx_vmwrite(VMCS_HOST_IA32_PAT, rdmsr(MSR_CR_PAT));
 	vmx_vmwrite(VMCS_HOST_IA32_EFER, rdmsr(MSR_EFER));
-	vmx_vmwrite(VMCS_HOST_CR0, rcr0());
+	vmx_vmwrite(VMCS_HOST_CR0, rcr0() & ~CR0_TS);
 
 	/* Generate ASID. */
 	vmx_asid_alloc(vcpu);



CVS commit: src/sys/dev/nvmm/x86

2020-01-09 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Thu Jan  9 16:20:12 UTC 2020

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_vmx.c

Log Message:
Mmh, as noted in PR/54847, this should be uint64_t, not uint16_t. Harmless
because we use only the two lowest bits anyway.

I believe this could be caught by KUBSAN; time to do another round of
NVMM+K_SAN testing.


To generate a diff of this commit:
cvs rdiff -u -r1.46 -r1.47 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_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.46 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.47
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.46	Tue Dec 10 18:06:50 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Thu Jan  9 16:20:12 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.46 2019/12/10 18:06:50 ad Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.47 2020/01/09 16:20:12 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.46 2019/12/10 18:06:50 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.47 2020/01/09 16:20:12 maxv Exp $");
 
 #include 
 #include 
@@ -1688,7 +1688,7 @@ vmx_exit_xsetbv(struct nvmm_machine *mac
 struct nvmm_vcpu_exit *exit)
 {
 	struct vmx_cpudata *cpudata = vcpu->cpudata;
-	uint16_t val;
+	uint64_t val;
 
 	exit->reason = NVMM_VCPU_EXIT_NONE;
 



CVS commit: src/sys/dev/nvmm/x86

2019-12-10 Thread Andrew Doran
Module Name:src
Committed By:   ad
Date:   Tue Dec 10 18:06:50 UTC 2019

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_svm.c nvmm_x86_vmx.c

Log Message:
pg->phys_addr > VM_PAGE_TO_PHYS(pg)


To generate a diff of this commit:
cvs rdiff -u -r1.54 -r1.55 src/sys/dev/nvmm/x86/nvmm_x86_svm.c
cvs rdiff -u -r1.45 -r1.46 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.54 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.55
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.54	Wed Nov 20 10:26:56 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Tue Dec 10 18:06:50 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.54 2019/11/20 10:26:56 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.55 2019/12/10 18:06:50 ad Exp $	*/
 
 /*
  * Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.54 2019/11/20 10:26:56 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.55 2019/12/10 18:06:50 ad Exp $");
 
 #include 
 #include 
@@ -1489,7 +1489,7 @@ svm_memalloc(paddr_t *pa, vaddr_t *va, s
 	, 1, 0);
 	if (ret != 0)
 		return ENOMEM;
-	_pa = TAILQ_FIRST()->phys_addr;
+	_pa = VM_PAGE_TO_PHYS(TAILQ_FIRST());
 	_va = uvm_km_alloc(kernel_map, npages * PAGE_SIZE, 0,
 	UVM_KMF_VAONLY | UVM_KMF_NOWAIT);
 	if (_va == 0)

Index: src/sys/dev/nvmm/x86/nvmm_x86_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.45 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.46
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.45	Wed Nov 20 10:26:56 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Tue Dec 10 18:06:50 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.45 2019/11/20 10:26:56 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.46 2019/12/10 18:06:50 ad Exp $	*/
 
 /*
  * Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.45 2019/11/20 10:26:56 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.46 2019/12/10 18:06:50 ad Exp $");
 
 #include 
 #include 
@@ -2112,7 +2112,7 @@ vmx_memalloc(paddr_t *pa, vaddr_t *va, s
 	, 1, 0);
 	if (ret != 0)
 		return ENOMEM;
-	_pa = TAILQ_FIRST()->phys_addr;
+	_pa = VM_PAGE_TO_PHYS(TAILQ_FIRST());
 	_va = uvm_km_alloc(kernel_map, npages * PAGE_SIZE, 0,
 	UVM_KMF_VAONLY | UVM_KMF_NOWAIT);
 	if (_va == 0)



CVS commit: src/sys/dev/nvmm

2019-04-27 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Sat Apr 27 17:30:38 UTC 2019

Modified Files:
src/sys/dev/nvmm: nvmm.c

Log Message:
Mmh, fix nvmm_vcpu_create(), the cpuid is given, and must not be chosen
from the free map. Looks like I forgot this after all my design rounds.
While here reorder the initialization.


To generate a diff of this commit:
cvs rdiff -u -r1.17 -r1.18 src/sys/dev/nvmm/nvmm.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/nvmm.c
diff -u src/sys/dev/nvmm/nvmm.c:1.17 src/sys/dev/nvmm/nvmm.c:1.18
--- src/sys/dev/nvmm/nvmm.c:1.17	Wed Apr 10 18:49:04 2019
+++ src/sys/dev/nvmm/nvmm.c	Sat Apr 27 17:30:38 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm.c,v 1.17 2019/04/10 18:49:04 maxv Exp $	*/
+/*	$NetBSD: nvmm.c,v 1.18 2019/04/27 17:30:38 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.17 2019/04/10 18:49:04 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.18 2019/04/27 17:30:38 maxv Exp $");
 
 #include 
 #include 
@@ -138,28 +138,27 @@ nvmm_machine_put(struct nvmm_machine *ma
 /* -- */
 
 static int
-nvmm_vcpu_alloc(struct nvmm_machine *mach, struct nvmm_cpu **ret)
+nvmm_vcpu_alloc(struct nvmm_machine *mach, nvmm_cpuid_t cpuid,
+struct nvmm_cpu **ret)
 {
 	struct nvmm_cpu *vcpu;
-	size_t i;
 
-	for (i = 0; i < NVMM_MAX_VCPUS; i++) {
-		vcpu = >cpus[i];
-
-		mutex_enter(>lock);
-		if (vcpu->present) {
-			mutex_exit(>lock);
-			continue;
-		}
+	if (cpuid >= NVMM_MAX_VCPUS) {
+		return EINVAL;
+	}
+	vcpu = >cpus[cpuid];
 
-		vcpu->present = true;
-		vcpu->cpuid = i;
-		vcpu->state = kmem_zalloc(nvmm_impl->state_size, KM_SLEEP);
-		*ret = vcpu;
-		return 0;
+	mutex_enter(>lock);
+	if (vcpu->present) {
+		mutex_exit(>lock);
+		return EBUSY;
 	}
 
-	return ENOBUFS;
+	vcpu->present = true;
+	vcpu->state = kmem_zalloc(nvmm_impl->state_size, KM_SLEEP);
+	vcpu->hcpu_last = -1;
+	*ret = vcpu;
+	return 0;
 }
 
 static void
@@ -168,7 +167,6 @@ nvmm_vcpu_free(struct nvmm_machine *mach
 	KASSERT(mutex_owned(>lock));
 	vcpu->present = false;
 	kmem_free(vcpu->state, nvmm_impl->state_size);
-	vcpu->hcpu_last = -1;
 }
 
 int
@@ -375,7 +373,7 @@ nvmm_vcpu_create(struct nvmm_owner *owne
 	if (error)
 		return error;
 
-	error = nvmm_vcpu_alloc(mach, );
+	error = nvmm_vcpu_alloc(mach, args->cpuid, );
 	if (error)
 		goto out;
 
@@ -899,9 +897,10 @@ nvmm_init(void)
 		machines[i].machid = i;
 		rw_init([i].lock);
 		for (n = 0; n < NVMM_MAX_VCPUS; n++) {
+			machines[i].cpus[n].present = false;
+			machines[i].cpus[n].cpuid = n;
 			mutex_init([i].cpus[n].lock, MUTEX_DEFAULT,
 			IPL_NONE);
-			machines[i].cpus[n].hcpu_last = -1;
 		}
 	}
 



CVS commit: src/sys/dev/nvmm/x86

2019-04-27 Thread Maxime Villard
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 
-__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 
 #include 
@@ -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 
-__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 
 #include 
@@ -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;
 



CVS commit: src/sys/dev/nvmm/x86

2019-04-27 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Sat Apr 27 08:16:19 UTC 2019

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_vmx.c nvmm_x86_vmxfunc.S

Log Message:
Optimize nvmm-intel, use inlined GCC assembly rather than function calls.


To generate a diff of this commit:
cvs rdiff -u -r1.27 -r1.28 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c
cvs rdiff -u -r1.2 -r1.3 src/sys/dev/nvmm/x86/nvmm_x86_vmxfunc.S

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_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.27 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.28
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.27	Wed Apr 24 18:19:28 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Sat Apr 27 08:16:19 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.27 2019/04/24 18:19:28 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.28 2019/04/27 08:16:19 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.27 2019/04/24 18:19:28 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.28 2019/04/27 08:16:19 maxv Exp $");
 
 #include 
 #include 
@@ -56,13 +56,6 @@ __KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx
 
 int _vmx_vmxon(paddr_t *pa);
 int _vmx_vmxoff(void);
-int _vmx_invept(uint64_t op, void *desc);
-int _vmx_invvpid(uint64_t op, void *desc);
-int _vmx_vmread(uint64_t op, uint64_t *val);
-int _vmx_vmwrite(uint64_t op, uint64_t val);
-int _vmx_vmptrld(paddr_t *pa);
-int _vmx_vmptrst(paddr_t *pa);
-int _vmx_vmclear(paddr_t *pa);
 int vmx_vmlaunch(uint64_t *gprs);
 int vmx_vmresume(uint64_t *gprs);
 
@@ -74,34 +67,113 @@ int vmx_vmresume(uint64_t *gprs);
 	if (__predict_false(_vmx_vmxoff() != 0)) { \
 		panic("%s: VMXOFF failed", __func__); \
 	}
-#define vmx_invept(a, b) \
-	if (__predict_false(_vmx_invept(a, b) != 0)) { \
-		panic("%s: INVEPT failed", __func__); \
-	}
-#define vmx_invvpid(a, b) \
-	if (__predict_false(_vmx_invvpid(a, b) != 0)) { \
-		panic("%s: INVVPID failed", __func__); \
-	}
-#define vmx_vmread(a, b) \
-	if (__predict_false(_vmx_vmread(a, b) != 0)) { \
-		panic("%s: VMREAD failed", __func__); \
-	}
-#define vmx_vmwrite(a, b) \
-	if (__predict_false(_vmx_vmwrite(a, b) != 0)) { \
-		panic("%s: VMWRITE failed", __func__); \
-	}
-#define vmx_vmptrld(a) \
-	if (__predict_false(_vmx_vmptrld(a) != 0)) { \
-		panic("%s: VMPTRLD failed", __func__); \
-	}
-#define vmx_vmptrst(a) \
-	if (__predict_false(_vmx_vmptrst(a) != 0)) { \
-		panic("%s: VMPTRST failed", __func__); \
-	}
-#define vmx_vmclear(a) \
-	if (__predict_false(_vmx_vmclear(a) != 0)) { \
-		panic("%s: VMCLEAR failed", __func__); \
-	}
+
+struct ept_desc {
+	uint64_t eptp;
+	uint64_t mbz;
+} __packed;
+
+struct vpid_desc {
+	uint64_t vpid;
+	uint64_t addr;
+} __packed;
+
+static inline void
+vmx_invept(uint64_t op, struct ept_desc *desc)
+{
+	asm volatile (
+		"invept		%[desc],%[op];"
+		"jz		vmx_insn_failvalid;"
+		"jc		vmx_insn_failinvalid;"
+		:
+		: [desc] "m" (*desc), [op] "r" (op)
+		: "memory", "cc"
+	);
+}
+
+static inline void
+vmx_invvpid(uint64_t op, struct vpid_desc *desc)
+{
+	asm volatile (
+		"invvpid	%[desc],%[op];"
+		"jz		vmx_insn_failvalid;"
+		"jc		vmx_insn_failinvalid;"
+		:
+		: [desc] "m" (*desc), [op] "r" (op)
+		: "memory", "cc"
+	);
+}
+
+static inline uint64_t
+vmx_vmread(uint64_t field)
+{
+	uint64_t value;
+
+	asm volatile (
+		"vmread		%[field],%[value];"
+		"jz		vmx_insn_failvalid;"
+		"jc		vmx_insn_failinvalid;"
+		: [value] "=r" (value)
+		: [field] "r" (field)
+		: "cc"
+	);
+
+	return value;
+}
+
+static inline void
+vmx_vmwrite(uint64_t field, uint64_t value)
+{
+	asm volatile (
+		"vmwrite	%[value],%[field];"
+		"jz		vmx_insn_failvalid;"
+		"jc		vmx_insn_failinvalid;"
+		:
+		: [field] "r" (field), [value] "r" (value)
+		: "cc"
+	);
+}
+
+static inline paddr_t
+vmx_vmptrst(void)
+{
+	paddr_t pa;
+
+	asm volatile (
+		"vmptrst	%[pa];"
+		:
+		: [pa] "m" (*(paddr_t *))
+		: "memory"
+	);
+
+	return pa;
+}
+
+static inline void
+vmx_vmptrld(paddr_t *pa)
+{
+	asm volatile (
+		"vmptrld	%[pa];"
+		"jz		vmx_insn_failvalid;"
+		"jc		vmx_insn_failinvalid;"
+		:
+		: [pa] "m" (*pa)
+		: "memory", "cc"
+	);
+}
+
+static inline void
+vmx_vmclear(paddr_t *pa)
+{
+	asm volatile (
+		"vmclear	%[pa];"
+		"jz		vmx_insn_failvalid;"
+		"jc		vmx_insn_failinvalid;"
+		:
+		: [pa] "m" (*pa)
+		: "memory", "cc"
+	);
+}
 
 #define MSR_IA32_FEATURE_CONTROL	0x003A
 #define		IA32_FEATURE_CONTROL_LOCK	__BIT(0)
@@ -526,16 +598,6 @@ struct msr_entry {
 	uint64_t val;
 } __packed;
 
-struct ept_desc {
-	uint64_t eptp;
-	uint64_t mbz;
-} __packed;
-
-struct vpid_desc {
-	uint64_t vpid;
-	uint64_t addr;
-} __packed;
-
 #define VPID_MAX	0x
 
 /* Make sure we never run out of VPIDs. */
@@ -805,7 +867,7 @@ vmx_vmcs_enter(struct nvmm_cpu *vcpu)
 	if (cpudata->vmcs_refcnt > 1) {
 #ifdef DIAGNOSTIC
 		KASSERT(kpreempt_disabled());
-		

CVS commit: src/sys/dev/nvmm/x86

2019-04-24 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Wed Apr 24 18:45:15 UTC 2019

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_svmfunc.S nvmm_x86_vmxfunc.S

Log Message:
Match the structure order, for better cache utilization.


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/sys/dev/nvmm/x86/nvmm_x86_svmfunc.S
cvs rdiff -u -r1.1 -r1.2 src/sys/dev/nvmm/x86/nvmm_x86_vmxfunc.S

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_svmfunc.S
diff -u src/sys/dev/nvmm/x86/nvmm_x86_svmfunc.S:1.2 src/sys/dev/nvmm/x86/nvmm_x86_svmfunc.S:1.3
--- src/sys/dev/nvmm/x86/nvmm_x86_svmfunc.S:1.2	Thu Jan 10 06:58:36 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_svmfunc.S	Wed Apr 24 18:45:15 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svmfunc.S,v 1.2 2019/01/10 06:58:36 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svmfunc.S,v 1.3 2019/04/24 18:45:15 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -97,9 +97,12 @@
  */
 
 #define GUEST_SAVE_GPRS(reg)\
-	movq	%rbx,(NVMM_X64_GPR_RBX * 8)(reg)	;\
 	movq	%rcx,(NVMM_X64_GPR_RCX * 8)(reg)	;\
 	movq	%rdx,(NVMM_X64_GPR_RDX * 8)(reg)	;\
+	movq	%rbx,(NVMM_X64_GPR_RBX * 8)(reg)	;\
+	movq	%rbp,(NVMM_X64_GPR_RBP * 8)(reg)	;\
+	movq	%rsi,(NVMM_X64_GPR_RSI * 8)(reg)	;\
+	movq	%rdi,(NVMM_X64_GPR_RDI * 8)(reg)	;\
 	movq	%r8,(NVMM_X64_GPR_R8 * 8)(reg)		;\
 	movq	%r9,(NVMM_X64_GPR_R9 * 8)(reg)		;\
 	movq	%r10,(NVMM_X64_GPR_R10 * 8)(reg)	;\
@@ -107,15 +110,15 @@
 	movq	%r12,(NVMM_X64_GPR_R12 * 8)(reg)	;\
 	movq	%r13,(NVMM_X64_GPR_R13 * 8)(reg)	;\
 	movq	%r14,(NVMM_X64_GPR_R14 * 8)(reg)	;\
-	movq	%r15,(NVMM_X64_GPR_R15 * 8)(reg)	;\
-	movq	%rbp,(NVMM_X64_GPR_RBP * 8)(reg)	;\
-	movq	%rdi,(NVMM_X64_GPR_RDI * 8)(reg)	;\
-	movq	%rsi,(NVMM_X64_GPR_RSI * 8)(reg)
+	movq	%r15,(NVMM_X64_GPR_R15 * 8)(reg)
 
 #define GUEST_RESTORE_GPRS(reg)\
-	movq	(NVMM_X64_GPR_RBX * 8)(reg),%rbx	;\
 	movq	(NVMM_X64_GPR_RCX * 8)(reg),%rcx	;\
 	movq	(NVMM_X64_GPR_RDX * 8)(reg),%rdx	;\
+	movq	(NVMM_X64_GPR_RBX * 8)(reg),%rbx	;\
+	movq	(NVMM_X64_GPR_RBP * 8)(reg),%rbp	;\
+	movq	(NVMM_X64_GPR_RSI * 8)(reg),%rsi	;\
+	movq	(NVMM_X64_GPR_RDI * 8)(reg),%rdi	;\
 	movq	(NVMM_X64_GPR_R8 * 8)(reg),%r8		;\
 	movq	(NVMM_X64_GPR_R9 * 8)(reg),%r9		;\
 	movq	(NVMM_X64_GPR_R10 * 8)(reg),%r10	;\
@@ -123,10 +126,7 @@
 	movq	(NVMM_X64_GPR_R12 * 8)(reg),%r12	;\
 	movq	(NVMM_X64_GPR_R13 * 8)(reg),%r13	;\
 	movq	(NVMM_X64_GPR_R14 * 8)(reg),%r14	;\
-	movq	(NVMM_X64_GPR_R15 * 8)(reg),%r15	;\
-	movq	(NVMM_X64_GPR_RBP * 8)(reg),%rbp	;\
-	movq	(NVMM_X64_GPR_RDI * 8)(reg),%rdi	;\
-	movq	(NVMM_X64_GPR_RSI * 8)(reg),%rsi
+	movq	(NVMM_X64_GPR_R15 * 8)(reg),%r15
 
 /*
  * %rdi = PA of VMCB

Index: src/sys/dev/nvmm/x86/nvmm_x86_vmxfunc.S
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmxfunc.S:1.1 src/sys/dev/nvmm/x86/nvmm_x86_vmxfunc.S:1.2
--- src/sys/dev/nvmm/x86/nvmm_x86_vmxfunc.S:1.1	Wed Feb 13 16:03:16 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmxfunc.S	Wed Apr 24 18:45:15 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmxfunc.S,v 1.1 2019/02/13 16:03:16 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_vmxfunc.S,v 1.2 2019/04/24 18:45:15 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -225,9 +225,12 @@ END(_vmx_vmclear)
  */
 
 #define GUEST_SAVE_GPRS(reg)\
-	movq	%rbx,(NVMM_X64_GPR_RBX * 8)(reg)	;\
 	movq	%rcx,(NVMM_X64_GPR_RCX * 8)(reg)	;\
 	movq	%rdx,(NVMM_X64_GPR_RDX * 8)(reg)	;\
+	movq	%rbx,(NVMM_X64_GPR_RBX * 8)(reg)	;\
+	movq	%rbp,(NVMM_X64_GPR_RBP * 8)(reg)	;\
+	movq	%rsi,(NVMM_X64_GPR_RSI * 8)(reg)	;\
+	movq	%rdi,(NVMM_X64_GPR_RDI * 8)(reg)	;\
 	movq	%r8,(NVMM_X64_GPR_R8 * 8)(reg)		;\
 	movq	%r9,(NVMM_X64_GPR_R9 * 8)(reg)		;\
 	movq	%r10,(NVMM_X64_GPR_R10 * 8)(reg)	;\
@@ -235,15 +238,15 @@ END(_vmx_vmclear)
 	movq	%r12,(NVMM_X64_GPR_R12 * 8)(reg)	;\
 	movq	%r13,(NVMM_X64_GPR_R13 * 8)(reg)	;\
 	movq	%r14,(NVMM_X64_GPR_R14 * 8)(reg)	;\
-	movq	%r15,(NVMM_X64_GPR_R15 * 8)(reg)	;\
-	movq	%rbp,(NVMM_X64_GPR_RBP * 8)(reg)	;\
-	movq	%rdi,(NVMM_X64_GPR_RDI * 8)(reg)	;\
-	movq	%rsi,(NVMM_X64_GPR_RSI * 8)(reg)
+	movq	%r15,(NVMM_X64_GPR_R15 * 8)(reg)
 
 #define GUEST_RESTORE_GPRS(reg)\
-	movq	(NVMM_X64_GPR_RBX * 8)(reg),%rbx	;\
 	movq	(NVMM_X64_GPR_RCX * 8)(reg),%rcx	;\
 	movq	(NVMM_X64_GPR_RDX * 8)(reg),%rdx	;\
+	movq	(NVMM_X64_GPR_RBX * 8)(reg),%rbx	;\
+	movq	(NVMM_X64_GPR_RBP * 8)(reg),%rbp	;\
+	movq	(NVMM_X64_GPR_RSI * 8)(reg),%rsi	;\
+	movq	(NVMM_X64_GPR_RDI * 8)(reg),%rdi	;\
 	movq	(NVMM_X64_GPR_R8 * 8)(reg),%r8		;\
 	movq	(NVMM_X64_GPR_R9 * 8)(reg),%r9		;\
 	movq	(NVMM_X64_GPR_R10 * 8)(reg),%r10	;\
@@ -252,9 +255,6 @@ END(_vmx_vmclear)
 	movq	(NVMM_X64_GPR_R13 * 8)(reg),%r13	;\
 	movq	(NVMM_X64_GPR_R14 * 8)(reg),%r14	;\
 	movq	(NVMM_X64_GPR_R15 * 8)(reg),%r15	;\
-	movq	(NVMM_X64_GPR_RBP * 8)(reg),%rbp	;\
-	movq	(NVMM_X64_GPR_RDI * 8)(reg),%rdi	;\
-	movq	(NVMM_X64_GPR_RSI * 8)(reg),%rsi	;\
 	movq	(NVMM_X64_GPR_RAX * 8)(reg),%rax
 
 /*



CVS commit: src/sys/dev/nvmm

2019-04-24 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Wed Apr 24 18:19:28 UTC 2019

Modified Files:
src/sys/dev/nvmm: nvmm.h
src/sys/dev/nvmm/x86: nvmm_x86_svm.c nvmm_x86_vmx.c

Log Message:
Provide the hardware error code for NVMM_EXIT_INVALID, useful when
debugging.


To generate a diff of this commit:
cvs rdiff -u -r1.5 -r1.6 src/sys/dev/nvmm/nvmm.h
cvs rdiff -u -r1.39 -r1.40 src/sys/dev/nvmm/x86/nvmm_x86_svm.c
cvs rdiff -u -r1.26 -r1.27 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/nvmm.h
diff -u src/sys/dev/nvmm/nvmm.h:1.5 src/sys/dev/nvmm/nvmm.h:1.6
--- src/sys/dev/nvmm/nvmm.h:1.5	Thu Mar 21 20:21:40 2019
+++ src/sys/dev/nvmm/nvmm.h	Wed Apr 24 18:19:28 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm.h,v 1.5 2019/03/21 20:21:40 maxv Exp $	*/
+/*	$NetBSD: nvmm.h,v 1.6 2019/04/24 18:19:28 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -103,6 +103,10 @@ struct nvmm_exit_insn {
 	uint64_t npc;
 };
 
+struct nvmm_exit_invalid {
+	uint64_t hwcode;
+};
+
 struct nvmm_exit {
 	enum nvmm_exit_reason reason;
 	union {
@@ -110,6 +114,7 @@ struct nvmm_exit {
 		struct nvmm_exit_io io;
 		struct nvmm_exit_msr msr;
 		struct nvmm_exit_insn insn;
+		struct nvmm_exit_invalid inv;
 	} u;
 	uint64_t exitstate[8];
 };

Index: src/sys/dev/nvmm/x86/nvmm_x86_svm.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.39 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.40
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.39	Sat Apr 20 08:45:30 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Wed Apr 24 18:19:28 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.39 2019/04/20 08:45:30 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.40 2019/04/24 18:19:28 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.39 2019/04/20 08:45:30 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.40 2019/04/24 18:19:28 maxv Exp $");
 
 #include 
 #include 
@@ -1118,6 +1118,13 @@ error:
 	svm_inject_gp(mach, vcpu);
 }
 
+static void
+svm_exit_invalid(struct nvmm_exit *exit, uint64_t code)
+{
+	exit->u.inv.hwcode = code;
+	exit->reason = NVMM_EXIT_INVALID;
+}
+
 /* -- */
 
 static void
@@ -1364,7 +1371,7 @@ svm_vcpu_run(struct nvmm_machine *mach, 
 			break;
 		case VMCB_EXITCODE_FERR_FREEZE: /* ? */
 		default:
-			exit->reason = NVMM_EXIT_INVALID;
+			svm_exit_invalid(exit, vmcb->ctrl.exitcode);
 			break;
 		}
 

Index: src/sys/dev/nvmm/x86/nvmm_x86_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.26 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.27
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.26	Sat Apr 20 08:45:30 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Wed Apr 24 18:19:28 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.26 2019/04/20 08:45:30 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.27 2019/04/24 18:19:28 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.26 2019/04/20 08:45:30 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.27 2019/04/24 18:19:28 maxv Exp $");
 
 #include 
 #include 
@@ -1623,6 +1623,13 @@ vmx_exit_epf(struct nvmm_machine *mach, 
 	exit->u.mem.inst_len = 0;
 }
 
+static void
+vmx_exit_invalid(struct nvmm_exit *exit, uint64_t code)
+{
+	exit->u.inv.hwcode = code;
+	exit->reason = NVMM_EXIT_INVALID;
+}
+
 /* -- */
 
 static void
@@ -1917,7 +1924,7 @@ vmx_vcpu_run(struct nvmm_machine *mach, 
 			exit->reason = NVMM_EXIT_NMI_READY;
 			break;
 		default:
-			exit->reason = NVMM_EXIT_INVALID;
+			vmx_exit_invalid(exit, exitcode);
 			break;
 		}
 



CVS commit: src/sys/dev/nvmm/x86

2019-04-20 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Sat Apr 20 08:45:30 UTC 2019

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_svm.c nvmm_x86_vmx.c

Log Message:
Ah, take XSAVE into account in ECX too, not just in EBX. Otherwise if the
guest relies only on ECX to initialize/copy the FPU state (like NetBSD
does), spurious #GPs can be encountered because the bitmap is clobbered.


To generate a diff of this commit:
cvs rdiff -u -r1.38 -r1.39 src/sys/dev/nvmm/x86/nvmm_x86_svm.c
cvs rdiff -u -r1.25 -r1.26 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.38 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.39
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.38	Sun Apr  7 14:28:50 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Sat Apr 20 08:45:30 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.38 2019/04/07 14:28:50 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.39 2019/04/20 08:45:30 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.38 2019/04/07 14:28:50 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.39 2019/04/20 08:45:30 maxv Exp $");
 
 #include 
 #include 
@@ -806,7 +806,7 @@ svm_inkernel_handle_cpuid(struct nvmm_cp
 cpudata->gprs[NVMM_X64_GPR_RBX] = sizeof(struct save87);
 			}
 			cpudata->gprs[NVMM_X64_GPR_RBX] += 64; /* XSAVE header */
-			cpudata->gprs[NVMM_X64_GPR_RCX] = sizeof(struct fxsave);
+			cpudata->gprs[NVMM_X64_GPR_RCX] = sizeof(struct fxsave) + 64;
 			cpudata->gprs[NVMM_X64_GPR_RDX] = svm_xcr0_mask >> 32;
 			break;
 		case 1:

Index: src/sys/dev/nvmm/x86/nvmm_x86_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.25 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.26
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.25	Sun Apr  7 14:28:50 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Sat Apr 20 08:45:30 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.25 2019/04/07 14:28:50 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.26 2019/04/20 08:45:30 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.25 2019/04/07 14:28:50 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.26 2019/04/20 08:45:30 maxv Exp $");
 
 #include 
 #include 
@@ -1122,7 +1122,7 @@ vmx_inkernel_handle_cpuid(struct nvmm_cp
 cpudata->gprs[NVMM_X64_GPR_RBX] = sizeof(struct save87);
 			}
 			cpudata->gprs[NVMM_X64_GPR_RBX] += 64; /* XSAVE header */
-			cpudata->gprs[NVMM_X64_GPR_RCX] = sizeof(struct fxsave);
+			cpudata->gprs[NVMM_X64_GPR_RCX] = sizeof(struct fxsave) + 64;
 			cpudata->gprs[NVMM_X64_GPR_RDX] = vmx_xcr0_mask >> 32;
 			break;
 		case 1:



CVS commit: src/sys/dev/nvmm

2019-04-08 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Mon Apr  8 18:30:55 UTC 2019

Modified Files:
src/sys/dev/nvmm: nvmm.c

Log Message:
Switch to MODULE_CLASS_MISC, from pgoyette@.


To generate a diff of this commit:
cvs rdiff -u -r1.15 -r1.16 src/sys/dev/nvmm/nvmm.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/nvmm.c
diff -u src/sys/dev/nvmm/nvmm.c:1.15 src/sys/dev/nvmm/nvmm.c:1.16
--- src/sys/dev/nvmm/nvmm.c:1.15	Mon Apr  8 18:23:46 2019
+++ src/sys/dev/nvmm/nvmm.c	Mon Apr  8 18:30:54 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm.c,v 1.15 2019/04/08 18:23:46 maxv Exp $	*/
+/*	$NetBSD: nvmm.c,v 1.16 2019/04/08 18:30:54 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.15 2019/04/08 18:23:46 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.16 2019/04/08 18:30:54 maxv Exp $");
 
 #include 
 #include 
@@ -978,7 +978,7 @@ nvmmattach(int nunits)
 	/* nothing */
 }
 
-MODULE(MODULE_CLASS_ANY, nvmm, NULL);
+MODULE(MODULE_CLASS_MISC, nvmm, NULL);
 
 static int
 nvmm_modcmd(modcmd_t cmd, void *arg)



CVS commit: src/sys/dev/nvmm

2019-04-08 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Mon Apr  8 18:23:47 UTC 2019

Modified Files:
src/sys/dev/nvmm: nvmm.c

Log Message:
Don't forget to call (*machine_destroy) when killing VMs.


To generate a diff of this commit:
cvs rdiff -u -r1.14 -r1.15 src/sys/dev/nvmm/nvmm.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/nvmm.c
diff -u src/sys/dev/nvmm/nvmm.c:1.14 src/sys/dev/nvmm/nvmm.c:1.15
--- src/sys/dev/nvmm/nvmm.c:1.14	Mon Apr  8 18:21:42 2019
+++ src/sys/dev/nvmm/nvmm.c	Mon Apr  8 18:23:46 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm.c,v 1.14 2019/04/08 18:21:42 maxv Exp $	*/
+/*	$NetBSD: nvmm.c,v 1.15 2019/04/08 18:23:46 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.14 2019/04/08 18:21:42 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.15 2019/04/08 18:23:46 maxv Exp $");
 
 #include 
 #include 
@@ -222,6 +222,7 @@ nvmm_kill_machines(struct nvmm_owner *ow
 			nvmm_vcpu_free(mach, vcpu);
 			nvmm_vcpu_put(vcpu);
 		}
+		(*nvmm_impl->machine_destroy)(mach);
 		uvmspace_free(mach->vm);
 
 		/* Drop the kernel UOBJ refs. */



CVS commit: src/sys/dev/nvmm

2019-04-08 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Mon Apr  8 18:21:42 UTC 2019

Modified Files:
src/sys/dev/nvmm: nvmm.c nvmm_internal.h

Log Message:
Use the fd_clone approach, to avoid losing references to the registered
VMs during fork(). We attach an nvmm_owner struct to the fd, reference it
in each VM, and identify the process' VMs by just comparing the pointer.


To generate a diff of this commit:
cvs rdiff -u -r1.13 -r1.14 src/sys/dev/nvmm/nvmm.c
cvs rdiff -u -r1.7 -r1.8 src/sys/dev/nvmm/nvmm_internal.h

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/nvmm.c
diff -u src/sys/dev/nvmm/nvmm.c:1.13 src/sys/dev/nvmm/nvmm.c:1.14
--- src/sys/dev/nvmm/nvmm.c:1.13	Sun Apr  7 14:05:15 2019
+++ src/sys/dev/nvmm/nvmm.c	Mon Apr  8 18:21:42 2019
@@ -1,7 +1,7 @@
-/*	$NetBSD: nvmm.c,v 1.13 2019/04/07 14:05:15 maxv Exp $	*/
+/*	$NetBSD: nvmm.c,v 1.14 2019/04/08 18:21:42 maxv Exp $	*/
 
 /*
- * Copyright (c) 2018 The NetBSD Foundation, Inc.
+ * Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.13 2019/04/07 14:05:15 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.14 2019/04/08 18:21:42 maxv Exp $");
 
 #include 
 #include 
@@ -42,6 +42,8 @@ __KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.1
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #include 
 #include 
@@ -98,7 +100,8 @@ nvmm_machine_free(struct nvmm_machine *m
 }
 
 static int
-nvmm_machine_get(nvmm_machid_t machid, struct nvmm_machine **ret, bool writer)
+nvmm_machine_get(struct nvmm_owner *owner, nvmm_machid_t machid,
+struct nvmm_machine **ret, bool writer)
 {
 	struct nvmm_machine *mach;
 	krw_t op = writer ? RW_WRITER : RW_READER;
@@ -113,7 +116,7 @@ nvmm_machine_get(nvmm_machid_t machid, s
 		rw_exit(>lock);
 		return ENOENT;
 	}
-	if (mach->procid != curproc->p_pid) {
+	if (mach->owner != owner) {
 		rw_exit(>lock);
 		return EPERM;
 	}
@@ -194,7 +197,7 @@ nvmm_vcpu_put(struct nvmm_cpu *vcpu)
 /* -- */
 
 static void
-nvmm_kill_machines(pid_t pid)
+nvmm_kill_machines(struct nvmm_owner *owner)
 {
 	struct nvmm_machine *mach;
 	struct nvmm_cpu *vcpu;
@@ -205,7 +208,7 @@ nvmm_kill_machines(pid_t pid)
 		mach = [i];
 
 		rw_enter(>lock, RW_WRITER);
-		if (!mach->present || mach->procid != pid) {
+		if (!mach->present || mach->owner != owner) {
 			rw_exit(>lock);
 			continue;
 		}
@@ -237,7 +240,7 @@ nvmm_kill_machines(pid_t pid)
 /* -- */
 
 static int
-nvmm_capability(struct nvmm_ioc_capability *args)
+nvmm_capability(struct nvmm_owner *owner, struct nvmm_ioc_capability *args)
 {
 	args->cap.version = NVMM_CAPABILITY_VERSION;
 	args->cap.state_size = nvmm_impl->state_size;
@@ -251,7 +254,8 @@ nvmm_capability(struct nvmm_ioc_capabili
 }
 
 static int
-nvmm_machine_create(struct nvmm_ioc_machine_create *args)
+nvmm_machine_create(struct nvmm_owner *owner,
+struct nvmm_ioc_machine_create *args)
 {
 	struct nvmm_machine *mach;
 	int error;
@@ -261,7 +265,7 @@ nvmm_machine_create(struct nvmm_ioc_mach
 		return error;
 
 	/* Curproc owns the machine. */
-	mach->procid = curproc->p_pid;
+	mach->owner = owner;
 
 	/* Zero out the host mappings. */
 	memset(>hmap, 0, sizeof(mach->hmap));
@@ -280,14 +284,15 @@ nvmm_machine_create(struct nvmm_ioc_mach
 }
 
 static int
-nvmm_machine_destroy(struct nvmm_ioc_machine_destroy *args)
+nvmm_machine_destroy(struct nvmm_owner *owner,
+struct nvmm_ioc_machine_destroy *args)
 {
 	struct nvmm_machine *mach;
 	struct nvmm_cpu *vcpu;
 	int error;
 	size_t i;
 
-	error = nvmm_machine_get(args->machid, , true);
+	error = nvmm_machine_get(owner, args->machid, , true);
 	if (error)
 		return error;
 
@@ -320,7 +325,8 @@ nvmm_machine_destroy(struct nvmm_ioc_mac
 }
 
 static int
-nvmm_machine_configure(struct nvmm_ioc_machine_configure *args)
+nvmm_machine_configure(struct nvmm_owner *owner,
+struct nvmm_ioc_machine_configure *args)
 {
 	struct nvmm_machine *mach;
 	size_t allocsz;
@@ -334,7 +340,7 @@ nvmm_machine_configure(struct nvmm_ioc_m
 	allocsz = nvmm_impl->conf_sizes[args->op];
 	data = kmem_alloc(allocsz, KM_SLEEP);
 
-	error = nvmm_machine_get(args->machid, , true);
+	error = nvmm_machine_get(owner, args->machid, , true);
 	if (error) {
 		kmem_free(data, allocsz);
 		return error;
@@ -354,13 +360,13 @@ out:
 }
 
 static int
-nvmm_vcpu_create(struct nvmm_ioc_vcpu_create *args)
+nvmm_vcpu_create(struct nvmm_owner *owner, struct nvmm_ioc_vcpu_create *args)
 {
 	struct nvmm_machine *mach;
 	struct nvmm_cpu *vcpu;
 	int error;
 
-	error = nvmm_machine_get(args->machid, , false);
+	error = nvmm_machine_get(owner, args->machid, , false);
 	if (error)
 		return error;
 

CVS commit: src/sys/dev/nvmm/x86

2019-04-07 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Sun Apr  7 14:28:50 UTC 2019

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_svm.c nvmm_x86_vmx.c

Log Message:
Invert the filtering priority: now the kernel-managed cpuid leaves are
overwritable by the virtualizer. This is useful to virtualizers that want
to 100% control every leaf.


To generate a diff of this commit:
cvs rdiff -u -r1.37 -r1.38 src/sys/dev/nvmm/x86/nvmm_x86_svm.c
cvs rdiff -u -r1.24 -r1.25 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.37 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.38
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.37	Sat Apr  6 11:49:53 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Sun Apr  7 14:28:50 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.37 2019/04/06 11:49:53 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.38 2019/04/07 14:28:50 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.37 2019/04/06 11:49:53 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.38 2019/04/07 14:28:50 maxv Exp $");
 
 #include 
 #include 
@@ -853,6 +853,8 @@ svm_exit_cpuid(struct nvmm_machine *mach
 	cpudata->gprs[NVMM_X64_GPR_RCX] = descs[2];
 	cpudata->gprs[NVMM_X64_GPR_RDX] = descs[3];
 
+	svm_inkernel_handle_cpuid(vcpu, eax, ecx);
+
 	for (i = 0; i < SVM_NCPUIDS; i++) {
 		cpuid = >cpuid[i];
 		if (!machdata->cpuidpresent[i]) {
@@ -877,9 +879,6 @@ svm_exit_cpuid(struct nvmm_machine *mach
 		break;
 	}
 
-	/* Overwrite non-tunable leaves. */
-	svm_inkernel_handle_cpuid(vcpu, eax, ecx);
-
 	svm_inkernel_advance(cpudata->vmcb);
 	exit->reason = NVMM_EXIT_NONE;
 }

Index: src/sys/dev/nvmm/x86/nvmm_x86_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.24 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.25
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.24	Sat Apr  6 11:49:53 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Sun Apr  7 14:28:50 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.24 2019/04/06 11:49:53 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.25 2019/04/07 14:28:50 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.24 2019/04/06 11:49:53 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.25 2019/04/07 14:28:50 maxv Exp $");
 
 #include 
 #include 
@@ -1169,6 +1169,8 @@ vmx_exit_cpuid(struct nvmm_machine *mach
 	cpudata->gprs[NVMM_X64_GPR_RCX] = descs[2];
 	cpudata->gprs[NVMM_X64_GPR_RDX] = descs[3];
 
+	vmx_inkernel_handle_cpuid(vcpu, eax, ecx);
+
 	for (i = 0; i < VMX_NCPUIDS; i++) {
 		cpuid = >cpuid[i];
 		if (!machdata->cpuidpresent[i]) {
@@ -1193,9 +1195,6 @@ vmx_exit_cpuid(struct nvmm_machine *mach
 		break;
 	}
 
-	/* Overwrite non-tunable leaves. */
-	vmx_inkernel_handle_cpuid(vcpu, eax, ecx);
-
 	vmx_inkernel_advance();
 	exit->reason = NVMM_EXIT_NONE;
 }



CVS commit: src/sys/dev/nvmm

2019-04-07 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Sun Apr  7 14:05:15 UTC 2019

Modified Files:
src/sys/dev/nvmm: nvmm.c

Log Message:
Don't allow unloading when there are still VMs registered, and don't allow
auto-unloading at all. Not a big problem actually, because since I changed
the module class it's not auto-loadable anymore.


To generate a diff of this commit:
cvs rdiff -u -r1.12 -r1.13 src/sys/dev/nvmm/nvmm.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/nvmm.c
diff -u src/sys/dev/nvmm/nvmm.c:1.12 src/sys/dev/nvmm/nvmm.c:1.13
--- src/sys/dev/nvmm/nvmm.c:1.12	Thu Mar 28 19:00:40 2019
+++ src/sys/dev/nvmm/nvmm.c	Sun Apr  7 14:05:15 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm.c,v 1.12 2019/03/28 19:00:40 maxv Exp $	*/
+/*	$NetBSD: nvmm.c,v 1.13 2019/04/07 14:05:15 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.12 2019/03/28 19:00:40 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.13 2019/04/07 14:05:15 maxv Exp $");
 
 #include 
 #include 
@@ -53,6 +53,7 @@ __KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.1
 #include 
 
 static struct nvmm_machine machines[NVMM_MAX_MACHINES];
+static volatile unsigned int nmachines __cacheline_aligned;
 
 static const struct nvmm_impl *nvmm_impl_list[] = {
 	_x86_svm,	/* x86 AMD SVM */
@@ -80,6 +81,7 @@ nvmm_machine_alloc(struct nvmm_machine *
 
 		mach->present = true;
 		*ret = mach;
+		atomic_inc_uint();
 		return 0;
 	}
 
@@ -92,6 +94,7 @@ nvmm_machine_free(struct nvmm_machine *m
 	KASSERT(rw_write_held(>lock));
 	KASSERT(mach->present);
 	mach->present = false;
+	atomic_dec_uint();
 }
 
 static int
@@ -845,7 +848,6 @@ nvmm_fini(void)
 		for (n = 0; n < NVMM_MAX_VCPUS; n++) {
 			mutex_destroy([i].cpus[n].lock);
 		}
-		/* TODO need to free stuff, etc */
 	}
 
 	(*nvmm_impl->fini)();
@@ -963,6 +965,9 @@ nvmm_modcmd(modcmd_t cmd, void *arg)
 		return 0;
 
 	case MODULE_CMD_FINI:
+		if (nmachines > 0) {
+			return EBUSY;
+		}
 #if defined(_MODULE)
 		{
 			error = devsw_detach(NULL, _cdevsw);
@@ -974,6 +979,9 @@ nvmm_modcmd(modcmd_t cmd, void *arg)
 		nvmm_fini();
 		return 0;
 
+	case MODULE_CMD_AUTOUNLOAD:
+		return EBUSY;
+
 	default:
 		return ENOTTY;
 	}



CVS commit: src/sys/dev/nvmm/x86

2019-04-06 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Sat Apr  6 11:49:53 UTC 2019

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86.c nvmm_x86.h nvmm_x86_svm.c
nvmm_x86_vmx.c

Log Message:
Replace the misc[] state by a new compressed nvmm_x64_state_intr structure,
which describes the interruptibility state of the guest.

Add evt_pending, read-only, that allows the virtualizer to know if an event
is pending.


To generate a diff of this commit:
cvs rdiff -u -r1.5 -r1.6 src/sys/dev/nvmm/x86/nvmm_x86.c
cvs rdiff -u -r1.10 -r1.11 src/sys/dev/nvmm/x86/nvmm_x86.h
cvs rdiff -u -r1.36 -r1.37 src/sys/dev/nvmm/x86/nvmm_x86_svm.c
cvs rdiff -u -r1.23 -r1.24 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.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86.c:1.5 src/sys/dev/nvmm/x86/nvmm_x86.c:1.6
--- src/sys/dev/nvmm/x86/nvmm_x86.c:1.5	Wed Apr  3 19:10:58 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86.c	Sat Apr  6 11:49:53 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86.c,v 1.5 2019/04/03 19:10:58 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86.c,v 1.6 2019/04/06 11:49:53 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86.c,v 1.5 2019/04/03 19:10:58 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86.c,v 1.6 2019/04/06 11:49:53 maxv Exp $");
 
 #include 
 #include 
@@ -213,10 +213,11 @@ const struct nvmm_x64_state nvmm_x86_res
 		[NVMM_X64_MSR_TSC] = 0,
 	},
 
-	.misc = {
-		[NVMM_X64_MISC_INT_SHADOW] = 0,
-		[NVMM_X64_MISC_INT_WINDOW_EXIT] = 0,
-		[NVMM_X64_MISC_NMI_WINDOW_EXIT] = 0,
+	.intr = {
+		.int_shadow = 0,
+		.int_window_exiting = 0,
+		.nmi_window_exiting = 0,
+		.evt_pending = 0,
 	},
 
 	.fpu = {

Index: src/sys/dev/nvmm/x86/nvmm_x86.h
diff -u src/sys/dev/nvmm/x86/nvmm_x86.h:1.10 src/sys/dev/nvmm/x86/nvmm_x86.h:1.11
--- src/sys/dev/nvmm/x86/nvmm_x86.h:1.10	Wed Apr  3 19:10:58 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86.h	Sat Apr  6 11:49:53 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86.h,v 1.10 2019/04/03 19:10:58 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86.h,v 1.11 2019/04/06 11:49:53 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -98,12 +98,6 @@
 #define NVMM_X64_MSR_TSC		10
 #define NVMM_X64_NMSR			11
 
-/* Misc. */
-#define NVMM_X64_MISC_INT_SHADOW	0
-#define NVMM_X64_MISC_INT_WINDOW_EXIT	1
-#define NVMM_X64_MISC_NMI_WINDOW_EXIT	2
-#define NVMM_X64_NMISC			3
-
 #ifndef ASM_NVMM
 
 #include 
@@ -126,12 +120,21 @@ struct nvmm_x64_state_seg {
 	uint64_t base;		/* hidden */
 };
 
+struct nvmm_x64_state_intr {
+	uint64_t int_shadow:1;
+	uint64_t int_window_exiting:1;
+	uint64_t nmi_window_exiting:1;
+	uint64_t evt_pending:1;
+	uint64_t rsvd:60;
+};
+
 /* VM exit state indexes. */
 #define NVMM_X64_EXITSTATE_CR8			0
 #define NVMM_X64_EXITSTATE_RFLAGS		1
 #define NVMM_X64_EXITSTATE_INT_SHADOW		2
 #define NVMM_X64_EXITSTATE_INT_WINDOW_EXIT	3
 #define NVMM_X64_EXITSTATE_NMI_WINDOW_EXIT	4
+#define NVMM_X64_EXITSTATE_EVT_PENDING		5
 
 /* Flags. */
 #define NVMM_X64_STATE_SEGS	0x01
@@ -139,11 +142,11 @@ struct nvmm_x64_state_seg {
 #define NVMM_X64_STATE_CRS	0x04
 #define NVMM_X64_STATE_DRS	0x08
 #define NVMM_X64_STATE_MSRS	0x10
-#define NVMM_X64_STATE_MISC	0x20
+#define NVMM_X64_STATE_INTR	0x20
 #define NVMM_X64_STATE_FPU	0x40
 #define NVMM_X64_STATE_ALL	\
 	(NVMM_X64_STATE_SEGS | NVMM_X64_STATE_GPRS | NVMM_X64_STATE_CRS | \
-	 NVMM_X64_STATE_DRS | NVMM_X64_STATE_MSRS | NVMM_X64_STATE_MISC | \
+	 NVMM_X64_STATE_DRS | NVMM_X64_STATE_MSRS | NVMM_X64_STATE_INTR | \
 	 NVMM_X64_STATE_FPU)
 
 struct nvmm_x64_state {
@@ -152,7 +155,7 @@ struct nvmm_x64_state {
 	uint64_t crs[NVMM_X64_NCR];
 	uint64_t drs[NVMM_X64_NDR];
 	uint64_t msrs[NVMM_X64_NMSR];
-	uint64_t misc[NVMM_X64_NMISC];
+	struct nvmm_x64_state_intr intr;
 	struct fxsave fpu;
 };
 

Index: src/sys/dev/nvmm/x86/nvmm_x86_svm.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.36 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.37
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.36	Wed Apr  3 17:32:58 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Sat Apr  6 11:49:53 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.36 2019/04/03 17:32:58 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.37 2019/04/06 11:49:53 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.36 2019/04/03 17:32:58 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.37 2019/04/06 11:49:53 maxv Exp $");
 
 #include 
 #include 
@@ -531,9 +531,10 @@ struct svm_cpudata {
 	bool ts_set;
 	struct xsave_header hfpu __aligned(64);
 
-	/* Event state */
+	/* Intr state */
 	bool int_window_exit;
 	bool nmi_window_exit;
+	bool evt_pending;
 
 	/* Guest state */
 	uint64_t gxcr0;
@@ -709,6 +710,8 @@ svm_vcpu_inject(struct nvmm_machine *mac
 	__SHIFTIN(1, 

CVS commit: src/sys/dev/nvmm/x86

2019-04-03 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Wed Apr  3 19:10:58 UTC 2019

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86.c nvmm_x86.h nvmm_x86_vmx.c

Log Message:
VMX: if PAT is not valid, #GP on WRMSR, rather than crashing the guest.


To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 src/sys/dev/nvmm/x86/nvmm_x86.c
cvs rdiff -u -r1.9 -r1.10 src/sys/dev/nvmm/x86/nvmm_x86.h
cvs rdiff -u -r1.22 -r1.23 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.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86.c:1.4 src/sys/dev/nvmm/x86/nvmm_x86.c:1.5
--- src/sys/dev/nvmm/x86/nvmm_x86.c:1.4	Wed Apr  3 17:32:58 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86.c	Wed Apr  3 19:10:58 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86.c,v 1.4 2019/04/03 17:32:58 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86.c,v 1.5 2019/04/03 19:10:58 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86.c,v 1.4 2019/04/03 17:32:58 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86.c,v 1.5 2019/04/03 19:10:58 maxv Exp $");
 
 #include 
 #include 
@@ -313,3 +313,19 @@ const struct nvmm_x86_cpuid_mask nvmm_cp
 	CPUID_EM64T | CPUID_3DNOW2 |
 	CPUID_3DNOW
 };
+
+bool
+nvmm_x86_pat_validate(uint64_t val)
+{
+	uint8_t *pat = (uint8_t *)
+	size_t i;
+
+	for (i = 0; i < 8; i++) {
+		if (__predict_false(pat[i] & ~__BITS(2,0)))
+			return false;
+		if (__predict_false(pat[i] == 2 || pat[i] == 3))
+			return false;
+	}
+
+	return true;
+}

Index: src/sys/dev/nvmm/x86/nvmm_x86.h
diff -u src/sys/dev/nvmm/x86/nvmm_x86.h:1.9 src/sys/dev/nvmm/x86/nvmm_x86.h:1.10
--- src/sys/dev/nvmm/x86/nvmm_x86.h:1.9	Wed Apr  3 17:32:58 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86.h	Wed Apr  3 19:10:58 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86.h,v 1.9 2019/04/03 17:32:58 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86.h,v 1.10 2019/04/03 19:10:58 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -186,6 +186,7 @@ extern const struct nvmm_x64_state nvmm_
 extern const struct nvmm_x86_cpuid_mask nvmm_cpuid_0001;
 extern const struct nvmm_x86_cpuid_mask nvmm_cpuid_0007;
 extern const struct nvmm_x86_cpuid_mask nvmm_cpuid_8001;
+bool nvmm_x86_pat_validate(uint64_t);
 #endif
 
 #endif /* ASM_NVMM */

Index: src/sys/dev/nvmm/x86/nvmm_x86_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.22 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.23
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.22	Wed Apr  3 18:05:55 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Wed Apr  3 19:10:58 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.22 2019/04/03 18:05:55 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.23 2019/04/03 19:10:58 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.22 2019/04/03 18:05:55 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.23 2019/04/03 19:10:58 maxv Exp $");
 
 #include 
 #include 
@@ -1502,7 +1502,11 @@ vmx_inkernel_handle_msr(struct nvmm_mach
 			goto handled;
 		}
 		if (exit->u.msr.msr == MSR_CR_PAT) {
-			vmx_vmwrite(VMCS_GUEST_IA32_PAT, exit->u.msr.val);
+			val = exit->u.msr.val;
+			if (__predict_false(!nvmm_x86_pat_validate(val))) {
+goto error;
+			}
+			vmx_vmwrite(VMCS_GUEST_IA32_PAT, val);
 			goto handled;
 		}
 		if (exit->u.msr.msr == MSR_MISC_ENABLE) {
@@ -1522,6 +1526,10 @@ vmx_inkernel_handle_msr(struct nvmm_mach
 handled:
 	vmx_inkernel_advance();
 	return true;
+
+error:
+	vmx_inject_gp(mach, vcpu);
+	return true;
 }
 
 static void



CVS commit: src/sys/dev/nvmm/x86

2019-04-03 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Wed Apr  3 18:05:55 UTC 2019

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_vmx.c

Log Message:
Add new VMCS bits.


To generate a diff of this commit:
cvs rdiff -u -r1.21 -r1.22 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_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.21 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.22
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.21	Wed Apr  3 17:32:58 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Wed Apr  3 18:05:55 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.21 2019/04/03 17:32:58 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.22 2019/04/03 18:05:55 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.21 2019/04/03 17:32:58 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.22 2019/04/03 18:05:55 maxv Exp $");
 
 #include 
 #include 
@@ -205,6 +205,7 @@ int vmx_vmresume(uint64_t *gprs);
 #define VMCS_VIRTUAL_EXCEPTION			0x202A
 #define VMCS_XSS_EXIT_BITMAP			0x202C
 #define VMCS_ENCLS_EXIT_BITMAP			0x202E
+#define VMCS_SUBPAGE_PERM_TABLE_PTR		0x2030
 #define VMCS_TSC_MULTIPLIER			0x2032
 /* 64-bit read-only fields */
 #define VMCS_GUEST_PHYSICAL_ADDRESS		0x2400
@@ -229,7 +230,7 @@ int vmx_vmresume(uint64_t *gprs);
 #define		PIN_CTLS_NMI_EXITING		__BIT(3)
 #define		PIN_CTLS_VIRTUAL_NMIS		__BIT(5)
 #define		PIN_CTLS_ACTIVATE_PREEMPT_TIMER	__BIT(6)
-#define		PIN_CTLS_PROCESS_POSTEd_INTS	__BIT(7)
+#define		PIN_CTLS_PROCESS_POSTED_INTS	__BIT(7)
 #define VMCS_PROCBASED_CTLS			0x4002
 #define		PROC_CTLS_INT_WINDOW_EXITING	__BIT(2)
 #define		PROC_CTLS_USE_TSC_OFFSETTING	__BIT(3)
@@ -319,7 +320,9 @@ int vmx_vmresume(uint64_t *gprs);
 #define		PROC_CTLS2_CONCEAL_VMX_FROM_PT	__BIT(19)
 #define		PROC_CTLS2_XSAVES_ENABLE	__BIT(20)
 #define		PROC_CTLS2_MODE_BASED_EXEC_EPT	__BIT(22)
+#define		PROC_CTLS2_SUBPAGE_PERMISSIONS	__BIT(23)
 #define		PROC_CTLS2_USE_TSC_SCALING	__BIT(25)
+#define		PROC_CTLS2_ENCLV_EXITING	__BIT(28)
 #define VMCS_PLE_GAP0x4020
 #define VMCS_PLE_WINDOW0x4022
 /* 32-bit read-only data fields */



CVS commit: src/sys/dev/nvmm/x86

2019-04-03 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Wed Apr  3 17:32:58 UTC 2019

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86.c nvmm_x86.h nvmm_x86_svm.c
nvmm_x86_vmx.c

Log Message:
Add MSR_TSC.


To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/sys/dev/nvmm/x86/nvmm_x86.c
cvs rdiff -u -r1.8 -r1.9 src/sys/dev/nvmm/x86/nvmm_x86.h
cvs rdiff -u -r1.35 -r1.36 src/sys/dev/nvmm/x86/nvmm_x86_svm.c
cvs rdiff -u -r1.20 -r1.21 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.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86.c:1.3 src/sys/dev/nvmm/x86/nvmm_x86.c:1.4
--- src/sys/dev/nvmm/x86/nvmm_x86.c:1.3	Sun Mar  3 07:01:09 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86.c	Wed Apr  3 17:32:58 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86.c,v 1.3 2019/03/03 07:01:09 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86.c,v 1.4 2019/04/03 17:32:58 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86.c,v 1.3 2019/03/03 07:01:09 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86.c,v 1.4 2019/04/03 17:32:58 maxv Exp $");
 
 #include 
 #include 
@@ -210,6 +210,7 @@ const struct nvmm_x64_state nvmm_x86_res
 		PATENTRY(2, PAT_UCMINUS) | PATENTRY(3, PAT_UC) |
 		PATENTRY(4, PAT_WB) | PATENTRY(5, PAT_WT) |
 		PATENTRY(6, PAT_UCMINUS) | PATENTRY(7, PAT_UC),
+		[NVMM_X64_MSR_TSC] = 0,
 	},
 
 	.misc = {

Index: src/sys/dev/nvmm/x86/nvmm_x86.h
diff -u src/sys/dev/nvmm/x86/nvmm_x86.h:1.8 src/sys/dev/nvmm/x86/nvmm_x86.h:1.9
--- src/sys/dev/nvmm/x86/nvmm_x86.h:1.8	Sun Mar  3 07:01:09 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86.h	Wed Apr  3 17:32:58 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86.h,v 1.8 2019/03/03 07:01:09 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86.h,v 1.9 2019/04/03 17:32:58 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -95,7 +95,8 @@
 #define NVMM_X64_MSR_SYSENTER_ESP	7
 #define NVMM_X64_MSR_SYSENTER_EIP	8
 #define NVMM_X64_MSR_PAT		9
-#define NVMM_X64_NMSR			10
+#define NVMM_X64_MSR_TSC		10
+#define NVMM_X64_NMSR			11
 
 /* Misc. */
 #define NVMM_X64_MISC_INT_SHADOW	0

Index: src/sys/dev/nvmm/x86/nvmm_x86_svm.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.35 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.36
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.35	Thu Mar 21 20:21:41 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Wed Apr  3 17:32:58 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.35 2019/03/21 20:21:41 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.36 2019/04/03 17:32:58 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.35 2019/03/21 20:21:41 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.36 2019/04/03 17:32:58 maxv Exp $");
 
 #include 
 #include 
@@ -505,6 +505,7 @@ struct svm_cpudata {
 	/* General */
 	bool shared_asid;
 	bool gtlb_want_flush;
+	bool gtsc_want_update;
 	uint64_t vcpu_htlb_gen;
 
 	/* VMCB */
@@ -538,7 +539,7 @@ struct svm_cpudata {
 	uint64_t gxcr0;
 	uint64_t gprs[NVMM_X64_NGPR];
 	uint64_t drs[NVMM_X64_NDR];
-	uint64_t tsc_offset;
+	uint64_t gtsc;
 	struct xsave_header gfpu __aligned(64);
 };
 
@@ -1000,10 +1001,8 @@ svm_inkernel_handle_msr(struct nvmm_mach
 			goto handled;
 		}
 		if (exit->u.msr.msr == MSR_TSC) {
-			cpudata->tsc_offset = exit->u.msr.val - cpu_counter();
-			vmcb->ctrl.tsc_offset = cpudata->tsc_offset +
-			curcpu()->ci_data.cpu_cc_skew;
-			svm_vmcb_cache_flush(vmcb, VMCB_CTRL_VMCB_CLEAN_I);
+			cpudata->gtsc = exit->u.msr.val;
+			cpudata->gtsc_want_update = true;
 			goto handled;
 		}
 		for (i = 0; i < __arraycount(msr_ignore_list); i++) {
@@ -1268,9 +1267,8 @@ svm_vcpu_run(struct nvmm_machine *mach, 
 	svm_htlb_catchup(vcpu, hcpu);
 
 	if (vcpu->hcpu_last != hcpu) {
-		vmcb->ctrl.tsc_offset = cpudata->tsc_offset +
-		curcpu()->ci_data.cpu_cc_skew;
 		svm_vmcb_cache_flush_all(vmcb);
+		cpudata->gtsc_want_update = true;
 	}
 
 	svm_vcpu_guest_dbregs_enter(vcpu);
@@ -1283,6 +1281,11 @@ svm_vcpu_run(struct nvmm_machine *mach, 
 			vmcb->ctrl.tlb_ctrl = 0;
 		}
 
+		if (__predict_false(cpudata->gtsc_want_update)) {
+			vmcb->ctrl.tsc_offset = cpudata->gtsc - rdtsc();
+			svm_vmcb_cache_flush(vmcb, VMCB_CTRL_VMCB_CLEAN_I);
+		}
+
 		s = splhigh();
 		machgen = svm_htlb_flush(machdata, cpudata);
 		svm_vcpu_guest_fpu_enter(vcpu);
@@ -1295,6 +1298,7 @@ svm_vcpu_run(struct nvmm_machine *mach, 
 
 		if (vmcb->ctrl.exitcode != VMCB_EXITCODE_INVALID) {
 			cpudata->gtlb_want_flush = false;
+			cpudata->gtsc_want_update = false;
 			vcpu->hcpu_last = hcpu;
 		}
 
@@ -1376,6 +1380,8 @@ svm_vcpu_run(struct nvmm_machine *mach, 
 		}
 	}
 
+	cpudata->gtsc = rdtsc() + vmcb->ctrl.tsc_offset;
+
 	svm_vcpu_guest_misc_leave(vcpu);
 	svm_vcpu_guest_dbregs_leave(vcpu);
 
@@ -1644,6 +1650,9 

CVS commit: src/sys/dev/nvmm/x86

2019-03-14 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Thu Mar 14 20:29:53 UTC 2019

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_vmx.c

Log Message:
Optimize NVMM-Intel: keep the VMCS active on the host CPU, and lazy-switch
it on demand only when needed. This allows the CPU to use the cached
version of the guest state, rather than the in-memory copy of it. This is
much more performant.

A VMCS must be active on only one CPU, but one CPU can have several active
VMCSs at the same time.

We keep track of which CPU each VMCS is active on. When we want to execute
a VCPU, we determine whether its VMCS is loaded on another CPU, and if so
send an IPI to ask it to unbusy that VMCS. In most cases the VMCS is
already active on the current CPU, so we don't have to do anything and can
proceed with a fast VMRESUME.

We send IPIs with kpreemption enabled but with a bound LWP, because we
don't want to get context-switched to the CPU we just sent an IPI to.

Overall, with this in place, I see a ~15% performance increase in the
guests on NVMM-Intel.


To generate a diff of this commit:
cvs rdiff -u -r1.18 -r1.19 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_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.18 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.19
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.18	Thu Mar 14 19:26:44 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Thu Mar 14 20:29:53 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.18 2019/03/14 19:26:44 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.19 2019/03/14 20:29:53 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.18 2019/03/14 19:26:44 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.19 2019/03/14 20:29:53 maxv Exp $");
 
 #include 
 #include 
@@ -648,6 +648,8 @@ struct vmx_cpudata {
 	struct vmcs *vmcs;
 	paddr_t vmcs_pa;
 	size_t vmcs_refcnt;
+	struct cpu_info *vmcs_ci;
+	bool vmcs_launched;
 
 	/* MSR bitmap */
 	uint8_t *msrbm;
@@ -762,9 +764,35 @@ vmx_get_revision(void)
 }
 
 static void
+vmx_vmclear_ipi(void *arg1, void *arg2)
+{
+	paddr_t vmcs_pa = (paddr_t)arg1;
+	vmx_vmclear(_pa);
+}
+
+static void
+vmx_vmclear_remote(struct cpu_info *ci, paddr_t vmcs_pa)
+{
+	uint64_t xc;
+	int bound;
+
+	KASSERT(kpreempt_disabled());
+
+	bound = curlwp_bind();
+	kpreempt_enable();
+
+	xc = xc_unicast(XC_HIGHPRI, vmx_vmclear_ipi, (void *)vmcs_pa, NULL, ci);
+	xc_wait(xc);
+
+	kpreempt_disable();
+	curlwp_bindx(bound);
+}
+
+static void
 vmx_vmcs_enter(struct nvmm_cpu *vcpu)
 {
 	struct vmx_cpudata *cpudata = vcpu->cpudata;
+	struct cpu_info *vmcs_ci;
 	paddr_t oldpa __diagused;
 
 	cpudata->vmcs_refcnt++;
@@ -777,12 +805,22 @@ vmx_vmcs_enter(struct nvmm_cpu *vcpu)
 		return;
 	}
 
+	vmcs_ci = cpudata->vmcs_ci;
+	cpudata->vmcs_ci = (void *)0x00FF; /* clobber */
+
 	kpreempt_disable();
 
-#ifdef DIAGNOSTIC
-	vmx_vmptrst();
-	KASSERT(oldpa == 0x);
-#endif
+	if (vmcs_ci == NULL) {
+		/* This VMCS is loaded for the first time. */
+		vmx_vmclear(>vmcs_pa);
+		cpudata->vmcs_launched = false;
+	} else if (vmcs_ci != curcpu()) {
+		/* This VMCS is active on a remote CPU. */
+		vmx_vmclear_remote(vmcs_ci, cpudata->vmcs_pa);
+		cpudata->vmcs_launched = false;
+	} else {
+		/* This VMCS is active on curcpu, nothing to do. */
+	}
 
 	vmx_vmptrld(>vmcs_pa);
 }
@@ -805,6 +843,24 @@ vmx_vmcs_leave(struct nvmm_cpu *vcpu)
 		return;
 	}
 
+	cpudata->vmcs_ci = curcpu();
+	kpreempt_enable();
+}
+
+static void
+vmx_vmcs_destroy(struct nvmm_cpu *vcpu)
+{
+	struct vmx_cpudata *cpudata = vcpu->cpudata;
+	paddr_t oldpa __diagused;
+
+	KASSERT(kpreempt_disabled());
+#ifdef DIAGNOSTIC
+	vmx_vmptrst();
+	KASSERT(oldpa == cpudata->vmcs_pa);
+#endif
+	KASSERT(cpudata->vmcs_refcnt == 1);
+	cpudata->vmcs_refcnt--;
+
 	vmx_vmclear(>vmcs_pa);
 	kpreempt_enable();
 }
@@ -1721,11 +1777,12 @@ vmx_vcpu_run(struct nvmm_machine *mach, 
 	uint64_t intstate;
 	uint64_t machgen;
 	int hcpu, s, ret;
-	bool launched = false;
+	bool launched;
 
 	vmx_vmcs_enter(vcpu);
 	ci = curcpu();
 	hcpu = cpu_number();
+	launched = cpudata->vmcs_launched;
 
 	vmx_gtlb_catchup(vcpu, hcpu);
 	vmx_htlb_catchup(vcpu, hcpu);
@@ -1860,6 +1917,8 @@ vmx_vcpu_run(struct nvmm_machine *mach, 
 		}
 	}
 
+	cpudata->vmcs_launched = launched;
+
 	vmx_vcpu_guest_misc_leave(vcpu);
 	vmx_vcpu_guest_dbregs_leave(vcpu);
 
@@ -2515,7 +2574,7 @@ vmx_vcpu_destroy(struct nvmm_machine *ma
 
 	vmx_vmcs_enter(vcpu);
 	vmx_asid_free(vcpu);
-	vmx_vmcs_leave(vcpu);
+	vmx_vmcs_destroy(vcpu);
 
 	kcpuset_destroy(cpudata->htlb_want_flush);
 



CVS commit: src/sys/dev/nvmm/x86

2019-03-14 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Thu Mar 14 19:26:44 UTC 2019

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_vmx.c

Log Message:
Move a KASSERT, applies to all branches.


To generate a diff of this commit:
cvs rdiff -u -r1.17 -r1.18 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_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.17 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.18
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.17	Thu Mar  7 15:06:37 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Thu Mar 14 19:26:44 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.17 2019/03/07 15:06:37 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.18 2019/03/14 19:26:44 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.17 2019/03/07 15:06:37 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.18 2019/03/14 19:26:44 maxv Exp $");
 
 #include 
 #include 
@@ -794,14 +794,14 @@ vmx_vmcs_leave(struct nvmm_cpu *vcpu)
 	paddr_t oldpa __diagused;
 
 	KASSERT(kpreempt_disabled());
+#ifdef DIAGNOSTIC
+	vmx_vmptrst();
+	KASSERT(oldpa == cpudata->vmcs_pa);
+#endif
 	KASSERT(cpudata->vmcs_refcnt > 0);
 	cpudata->vmcs_refcnt--;
 
 	if (cpudata->vmcs_refcnt > 0) {
-#ifdef DIAGNOSTIC
-		vmx_vmptrst();
-		KASSERT(oldpa == cpudata->vmcs_pa);
-#endif
 		return;
 	}
 



CVS commit: src/sys/dev/nvmm/x86

2019-03-14 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Thu Mar 14 19:15:26 UTC 2019

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_svm.c

Log Message:
Reduce the mask of the VTPR, only the first four bits matter.


To generate a diff of this commit:
cvs rdiff -u -r1.33 -r1.34 src/sys/dev/nvmm/x86/nvmm_x86_svm.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.33 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.34
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.33	Sun Mar  3 07:01:09 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Thu Mar 14 19:15:26 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.33 2019/03/03 07:01:09 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.34 2019/03/14 19:15:26 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.33 2019/03/03 07:01:09 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.34 2019/03/14 19:15:26 maxv Exp $");
 
 #include 
 #include 
@@ -303,7 +303,7 @@ struct vmcb_ctrl {
 #define VMCB_CTRL_TLB_CTRL_FLUSH_GUEST_NONGLOBAL	0x07
 
 	uint64_t v;
-#define VMCB_CTRL_V_TPR			__BITS(7,0)
+#define VMCB_CTRL_V_TPR			__BITS(3,0)
 #define VMCB_CTRL_V_IRQ			__BIT(8)
 #define VMCB_CTRL_V_VGIF		__BIT(9)
 #define VMCB_CTRL_V_INTR_PRIO		__BITS(19,16)



CVS commit: src/sys/dev/nvmm

2019-03-14 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Thu Mar 14 19:10:28 UTC 2019

Modified Files:
src/sys/dev/nvmm: nvmm.c

Log Message:
Fail early if we're beyond the guest max ram.


To generate a diff of this commit:
cvs rdiff -u -r1.9 -r1.10 src/sys/dev/nvmm/nvmm.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/nvmm.c
diff -u src/sys/dev/nvmm/nvmm.c:1.9 src/sys/dev/nvmm/nvmm.c:1.10
--- src/sys/dev/nvmm/nvmm.c:1.9	Thu Mar  7 15:22:21 2019
+++ src/sys/dev/nvmm/nvmm.c	Thu Mar 14 19:10:27 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm.c,v 1.9 2019/03/07 15:22:21 maxv Exp $	*/
+/*	$NetBSD: nvmm.c,v 1.10 2019/03/14 19:10:27 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.9 2019/03/07 15:22:21 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.10 2019/03/14 19:10:27 maxv Exp $");
 
 #include 
 #include 
@@ -490,6 +490,9 @@ nvmm_do_vcpu_run(struct nvmm_machine *ma
 		if (__predict_true(exit->reason != NVMM_EXIT_MEMORY)) {
 			break;
 		}
+		if (exit->u.mem.gpa >= mach->gpa_end) {
+			break;
+		}
 		if (uvm_fault(>vm_map, exit->u.mem.gpa, VM_PROT_ALL)) {
 			break;
 		}



CVS commit: src/sys/dev/nvmm

2019-03-07 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Thu Mar  7 15:22:22 UTC 2019

Modified Files:
src/sys/dev/nvmm: nvmm.c nvmm_internal.h

Log Message:
Rename the internal NVMM HVA table entries from "segment" to "hmapping",
less confusing. Also fix the error handling in nvmm_hva_unmap().


To generate a diff of this commit:
cvs rdiff -u -r1.8 -r1.9 src/sys/dev/nvmm/nvmm.c
cvs rdiff -u -r1.6 -r1.7 src/sys/dev/nvmm/nvmm_internal.h

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/nvmm.c
diff -u src/sys/dev/nvmm/nvmm.c:1.8 src/sys/dev/nvmm/nvmm.c:1.9
--- src/sys/dev/nvmm/nvmm.c:1.8	Mon Feb 18 12:17:45 2019
+++ src/sys/dev/nvmm/nvmm.c	Thu Mar  7 15:22:21 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm.c,v 1.8 2019/02/18 12:17:45 maxv Exp $	*/
+/*	$NetBSD: nvmm.c,v 1.9 2019/03/07 15:22:21 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.8 2019/02/18 12:17:45 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.9 2019/03/07 15:22:21 maxv Exp $");
 
 #include 
 #include 
@@ -218,10 +218,10 @@ nvmm_kill_machines(pid_t pid)
 		uvmspace_free(mach->vm);
 
 		/* Drop the kernel UOBJ refs. */
-		for (j = 0; j < NVMM_MAX_SEGS; j++) {
-			if (!mach->segs[j].present)
+		for (j = 0; j < NVMM_MAX_HMAPPINGS; j++) {
+			if (!mach->hmap[j].present)
 continue;
-			uao_detach(mach->segs[j].uobj);
+			uao_detach(mach->hmap[j].uobj);
 		}
 
 		nvmm_machine_free(mach);
@@ -259,8 +259,8 @@ nvmm_machine_create(struct nvmm_ioc_mach
 	/* Curproc owns the machine. */
 	mach->procid = curproc->p_pid;
 
-	/* Zero out the segments. */
-	memset(>segs, 0, sizeof(mach->segs));
+	/* Zero out the host mappings. */
+	memset(>hmap, 0, sizeof(mach->hmap));
 
 	/* Create the machine vmspace. */
 	mach->gpa_begin = 0;
@@ -303,10 +303,10 @@ nvmm_machine_destroy(struct nvmm_ioc_mac
 	uvmspace_free(mach->vm);
 
 	/* Drop the kernel UOBJ refs. */
-	for (i = 0; i < NVMM_MAX_SEGS; i++) {
-		if (!mach->segs[i].present)
+	for (i = 0; i < NVMM_MAX_HMAPPINGS; i++) {
+		if (!mach->hmap[i].present)
 			continue;
-		uao_detach(mach->segs[i].uobj);
+		uao_detach(mach->hmap[i].uobj);
 	}
 
 	nvmm_machine_free(mach);
@@ -522,36 +522,21 @@ out:
 /* -- */
 
 static struct uvm_object *
-nvmm_seg_getuobj(struct nvmm_machine *mach, uintptr_t hva, size_t size,
+nvmm_hmapping_getuobj(struct nvmm_machine *mach, uintptr_t hva, size_t size,
size_t *off)
 {
-	struct nvmm_seg *seg;
+	struct nvmm_hmapping *hmapping;
 	size_t i;
 
-	for (i = 0; i < NVMM_MAX_SEGS; i++) {
-		seg = >segs[i];
-		if (!seg->present) {
+	for (i = 0; i < NVMM_MAX_HMAPPINGS; i++) {
+		hmapping = >hmap[i];
+		if (!hmapping->present) {
 			continue;
 		}
-		if (hva >= seg->hva && hva + size <= seg->hva + seg->size) {
-			*off = hva - seg->hva;
-			return seg->uobj;
-		}
-	}
-
-	return NULL;
-}
-
-static struct nvmm_seg *
-nvmm_seg_find(struct nvmm_machine *mach, uintptr_t hva, size_t size)
-{
-	struct nvmm_seg *seg;
-	size_t i;
-
-	for (i = 0; i < NVMM_MAX_SEGS; i++) {
-		seg = >segs[i];
-		if (seg->present && seg->hva == hva && seg->size == size) {
-			return seg;
+		if (hva >= hmapping->hva &&
+		hva + size <= hmapping->hva + hmapping->size) {
+			*off = hva - hmapping->hva;
+			return hmapping->uobj;
 		}
 	}
 
@@ -559,9 +544,9 @@ nvmm_seg_find(struct nvmm_machine *mach,
 }
 
 static int
-nvmm_seg_validate(struct nvmm_machine *mach, uintptr_t hva, size_t size)
+nvmm_hmapping_validate(struct nvmm_machine *mach, uintptr_t hva, size_t size)
 {
-	struct nvmm_seg *seg;
+	struct nvmm_hmapping *hmapping;
 	size_t i;
 
 	if ((hva % PAGE_SIZE) != 0 || (size % PAGE_SIZE) != 0) {
@@ -571,24 +556,27 @@ nvmm_seg_validate(struct nvmm_machine *m
 		return EINVAL;
 	}
 
-	for (i = 0; i < NVMM_MAX_SEGS; i++) {
-		seg = >segs[i];
-		if (!seg->present) {
+	for (i = 0; i < NVMM_MAX_HMAPPINGS; i++) {
+		hmapping = >hmap[i];
+		if (!hmapping->present) {
 			continue;
 		}
 
-		if (hva >= seg->hva && hva + size <= seg->hva + seg->size) {
+		if (hva >= hmapping->hva &&
+		hva + size <= hmapping->hva + hmapping->size) {
 			break;
 		}
 
-		if (hva >= seg->hva && hva < seg->hva + seg->size) {
+		if (hva >= hmapping->hva &&
+		hva < hmapping->hva + hmapping->size) {
 			return EEXIST;
 		}
-		if (hva + size > seg->hva &&
-		hva + size <= seg->hva + seg->size) {
+		if (hva + size > hmapping->hva &&
+		hva + size <= hmapping->hva + hmapping->size) {
 			return EEXIST;
 		}
-		if (hva <= seg->hva && hva + size >= seg->hva + seg->size) {
+		if (hva <= hmapping->hva &&
+		hva + size >= hmapping->hva + hmapping->size) {
 			return EEXIST;
 		}
 	}
@@ -596,33 +584,48 @@ nvmm_seg_validate(struct nvmm_machine *m
 	return 0;
 }
 
-static struct nvmm_seg *
-nvmm_seg_alloc(struct nvmm_machine *mach)
+static struct nvmm_hmapping *

CVS commit: src/sys/dev/nvmm/x86

2019-03-07 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Thu Mar  7 15:06:37 UTC 2019

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_vmx.c

Log Message:
Parse EXC_NMI on nvmm-intel, and don't return NVMM_EXIT_INVALID if we
received a host NMI, otherwise the guest could get killed if an NMI comes
in, typically when the host runs tprof at the same time.

Already handled on nvmm-amd.


To generate a diff of this commit:
cvs rdiff -u -r1.16 -r1.17 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_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.16 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.17
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.16	Sun Mar  3 07:01:09 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Thu Mar  7 15:06:37 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.16 2019/03/03 07:01:09 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.17 2019/03/07 15:06:37 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.16 2019/03/03 07:01:09 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.17 2019/03/07 15:06:37 maxv Exp $");
 
 #include 
 #include 
@@ -282,13 +282,14 @@ int vmx_vmresume(uint64_t *gprs);
 #define VMCS_ENTRY_MSR_LOAD_COUNT		0x4014
 #define VMCS_ENTRY_INTR_INFO			0x4016
 #define		INTR_INFO_VECTOR		__BITS(7,0)
-#define		INTR_INFO_TYPE_EXT_INT		(0 << 8)
-#define		INTR_INFO_TYPE_NMI		(2 << 8)
-#define		INTR_INFO_TYPE_HW_EXC		(3 << 8)
-#define		INTR_INFO_TYPE_SW_INT		(4 << 8)
-#define		INTR_INFO_TYPE_PRIV_SW_EXC	(5 << 8)
-#define		INTR_INFO_TYPE_SW_EXC		(6 << 8)
-#define		INTR_INFO_TYPE_OTHER		(7 << 8)
+#define		INTR_INFO_TYPE			__BITS(10,8)
+#define			INTR_TYPE_EXT_INT	0
+#define			INTR_TYPE_NMI		2
+#define			INTR_TYPE_HW_EXC	3
+#define			INTR_TYPE_SW_INT	4
+#define			INTR_TYPE_PRIV_SW_EXC	5
+#define			INTR_TYPE_SW_EXC	6
+#define			INTR_TYPE_OTHER		7
 #define		INTR_INFO_ERROR			__BIT(11)
 #define		INTR_INFO_VALID			__BIT(31)
 #define VMCS_ENTRY_EXCEPTION_ERROR		0x4018
@@ -883,12 +884,12 @@ vmx_vcpu_inject(struct nvmm_machine *mac
 
 	switch (event->type) {
 	case NVMM_EVENT_INTERRUPT_HW:
-		type = INTR_INFO_TYPE_EXT_INT;
+		type = INTR_TYPE_EXT_INT;
 		if (event->vector == 2) {
-			type = INTR_INFO_TYPE_NMI;
+			type = INTR_TYPE_NMI;
 		}
 		vmx_vmread(VMCS_GUEST_INTERRUPTIBILITY, );
-		if (type == INTR_INFO_TYPE_NMI) {
+		if (type == INTR_TYPE_NMI) {
 			if (cpudata->nmi_window_exit) {
 ret = EAGAIN;
 goto out;
@@ -917,7 +918,7 @@ vmx_vcpu_inject(struct nvmm_machine *mac
 			ret = EINVAL;
 			goto out;
 		}
-		type = INTR_INFO_TYPE_HW_EXC;
+		type = INTR_TYPE_HW_EXC;
 		err = vmx_event_has_error(event->vector);
 		break;
 	default:
@@ -927,7 +928,7 @@ vmx_vcpu_inject(struct nvmm_machine *mac
 
 	info =
 	__SHIFTIN(event->vector, INTR_INFO_VECTOR) |
-	type |
+	__SHIFTIN(type, INTR_INFO_TYPE) |
 	__SHIFTIN(err, INTR_INFO_ERROR) |
 	__SHIFTIN(1, INTR_INFO_VALID);
 	vmx_vmwrite(VMCS_ENTRY_INTR_INFO, info);
@@ -985,6 +986,28 @@ vmx_inkernel_advance(void)
 }
 
 static void
+vmx_exit_exc_nmi(struct nvmm_machine *mach, struct nvmm_cpu *vcpu,
+struct nvmm_exit *exit)
+{
+	uint64_t qual;
+
+	vmx_vmread(VMCS_EXIT_INTR_INFO, );
+
+	if ((qual & INTR_INFO_VALID) == 0) {
+		goto error;
+	}
+	if (__SHIFTOUT(qual, INTR_INFO_TYPE) != INTR_TYPE_NMI) {
+		goto error;
+	}
+
+	exit->reason = NVMM_EXIT_NONE;
+	return;
+
+error:
+	exit->reason = NVMM_EXIT_INVALID;
+}
+
+static void
 vmx_inkernel_handle_cpuid(struct nvmm_cpu *vcpu, uint64_t eax, uint64_t ecx)
 {
 	struct vmx_cpudata *cpudata = vcpu->cpudata;
@@ -1753,6 +1776,9 @@ vmx_vcpu_run(struct nvmm_machine *mach, 
 		exitcode &= __BITS(15,0);
 
 		switch (exitcode) {
+		case VMCS_EXITCODE_EXC_NMI:
+			vmx_exit_exc_nmi(mach, vcpu, exit);
+			break;
 		case VMCS_EXITCODE_EXT_INT:
 			exit->reason = NVMM_EXIT_NONE;
 			break;



CVS commit: src/sys/dev/nvmm/x86

2019-03-02 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Sun Mar  3 07:01:09 UTC 2019

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86.c nvmm_x86.h nvmm_x86_svm.c
nvmm_x86_vmx.c

Log Message:
Choose which CPUID bits to allow, rather than which bits to disallow. This
is clearer, and also forward compatible with future CPUs.

While here be more consistent when allowing the bits, and sync between
nvmm-amd and nvmm-intel. Also make sure to disallow AVX, because the guest
state we provide is only x86+SSE. Fixes a CentOS panic when booting on
NVMM, reported by Jared McNeill, thanks.


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/sys/dev/nvmm/x86/nvmm_x86.c
cvs rdiff -u -r1.7 -r1.8 src/sys/dev/nvmm/x86/nvmm_x86.h
cvs rdiff -u -r1.32 -r1.33 src/sys/dev/nvmm/x86/nvmm_x86_svm.c
cvs rdiff -u -r1.15 -r1.16 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.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86.c:1.2 src/sys/dev/nvmm/x86/nvmm_x86.c:1.3
--- src/sys/dev/nvmm/x86/nvmm_x86.c:1.2	Tue Feb 26 12:23:12 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86.c	Sun Mar  3 07:01:09 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86.c,v 1.2 2019/02/26 12:23:12 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86.c,v 1.3 2019/03/03 07:01:09 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86.c,v 1.2 2019/02/26 12:23:12 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86.c,v 1.3 2019/03/03 07:01:09 maxv Exp $");
 
 #include 
 #include 
@@ -226,3 +226,89 @@ const struct nvmm_x64_state nvmm_x86_res
 		.fx_mxcsr = 0x1F80,
 	}
 };
+
+const struct nvmm_x86_cpuid_mask nvmm_cpuid_0001 = {
+	.eax = ~0,
+	.ebx = ~0,
+	.ecx =
+	/* Excluded: MONITOR, VMX, SMX, EST, TM2, PDCM, PCID, X2APIC,
+	 * DEADLINE, RAZ. */
+	CPUID2_SSE3 | CPUID2_PCLMUL |
+	CPUID2_DTES64 | CPUID2_DS_CPL |
+	CPUID2_SSSE3 | CPUID2_CID |
+	CPUID2_SDBG | CPUID2_FMA |
+	CPUID2_CX16 | CPUID2_xTPR |
+	CPUID2_DCA | CPUID2_SSE41 |
+	CPUID2_SSE42 | CPUID2_MOVBE |
+	CPUID2_POPCNT | CPUID2_AES |
+	CPUID2_XSAVE | CPUID2_OSXSAVE |
+	CPUID2_F16C | CPUID2_RDRAND,
+	.edx =
+	/* Excluded: MCE, MTRR, MCA, DS, ACPI, TM. */
+	CPUID_FPU | CPUID_VME |
+	CPUID_DE | CPUID_PSE |
+	CPUID_TSC | CPUID_MSR |
+	CPUID_PAE | CPUID_CX8 |
+	CPUID_APIC | CPUID_B10 |	
+	CPUID_SEP | CPUID_PGE |
+	CPUID_CMOV | CPUID_PAT |
+	CPUID_PSE36 | CPUID_PN |
+	CPUID_CFLUSH | CPUID_B20 |
+	CPUID_MMX | CPUID_FXSR |
+	CPUID_SSE | CPUID_SSE2 |
+	CPUID_SS | CPUID_HTT |
+	CPUID_IA64 | CPUID_SBF
+};
+
+const struct nvmm_x86_cpuid_mask nvmm_cpuid_0007 = {
+	.eax = ~0,
+	.ebx =
+	/* Excluded: TSC_ADJUST, AVX2, INVPCID, AVX512*, PT, SHA. */
+	CPUID_SEF_FSGSBASE |
+	CPUID_SEF_SGX | CPUID_SEF_BMI1 |
+	CPUID_SEF_HLE | CPUID_SEF_FDPEXONLY |
+	CPUID_SEF_SMEP | CPUID_SEF_BMI2 |
+	CPUID_SEF_ERMS | CPUID_SEF_RTM |
+	CPUID_SEF_QM | CPUID_SEF_FPUCSDS |
+	CPUID_SEF_PQE | CPUID_SEF_RDSEED |
+	CPUID_SEF_ADX | CPUID_SEF_SMAP |
+	CPUID_SEF_CLFLUSHOPT | CPUID_SEF_CLWB,
+	.ecx =
+	/* Excluded: AVX512*, MAWAU, RDPID. */
+	CPUID_SEF_PREFETCHWT1 | CPUID_SEF_UMIP |
+	CPUID_SEF_PKU | CPUID_SEF_OSPKE |
+	CPUID_SEF_WAITPKG | CPUID_SEF_GFNI |
+	CPUID_SEF_VAES | CPUID_SEF_VPCLMULQDQ |
+	CPUID_SEF_CLDEMOTE | CPUID_SEF_MOVDIRI |
+	CPUID_SEF_MOVDIR64B | CPUID_SEF_SGXLC,
+	.edx =
+	/* Excluded: all except CAP. */
+	CPUID_SEF_ARCH_CAP
+};
+
+const struct nvmm_x86_cpuid_mask nvmm_cpuid_8001 = {
+	.eax = ~0,
+	.ebx = ~0,
+	.ecx =
+	/* Excluded: SVM, EAPIC, OSVW. */
+	CPUID_LAHF | CPUID_CMPLEGACY |
+	CPUID_ALTMOVCR0 | CPUID_LZCNT |
+	CPUID_SSE4A | CPUID_MISALIGNSSE |
+	CPUID_3DNOWPF | CPUID_IBS |
+	CPUID_XOP | CPUID_SKINIT |
+	CPUID_WDT | CPUID_LWP |
+	CPUID_FMA4 | CPUID_TCE |
+	CPUID_NODEID | CPUID_TBM |
+	CPUID_TOPOEXT | CPUID_PCEC |
+	CPUID_PCENB | CPUID_SPM |
+	CPUID_DBE | CPUID_PTSC |
+	CPUID_L2IPERFC | CPUID_MWAITX,
+	.edx =
+	/* Excluded: RDTSCP. */
+	CPUID_SYSCALL | CPUID_MPC |
+	CPUID_XD | CPUID_MMXX |
+	CPUID_MMX | CPUID_FXSR |
+	CPUID_FFXSR | CPUID_P1GB |
+	CPUID_EM64T | CPUID_3DNOW2 |
+	CPUID_3DNOW
+};

Index: src/sys/dev/nvmm/x86/nvmm_x86.h
diff -u src/sys/dev/nvmm/x86/nvmm_x86.h:1.7 src/sys/dev/nvmm/x86/nvmm_x86.h:1.8
--- src/sys/dev/nvmm/x86/nvmm_x86.h:1.7	Tue Feb 26 12:23:12 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86.h	Sun Mar  3 07:01:09 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86.h,v 1.7 2019/02/26 12:23:12 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86.h,v 1.8 2019/03/03 07:01:09 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -175,7 +175,16 @@ struct nvmm_x86_conf_cpuid {
 };
 
 #ifdef _KERNEL
+struct nvmm_x86_cpuid_mask {

CVS commit: src/sys/dev/nvmm/x86

2019-02-23 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Sat Feb 23 08:19:16 UTC 2019

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_svm.c nvmm_x86_vmx.c

Log Message:
Reorder the functions, and constify setstate. No functional change.


To generate a diff of this commit:
cvs rdiff -u -r1.29 -r1.30 src/sys/dev/nvmm/x86/nvmm_x86_svm.c
cvs rdiff -u -r1.11 -r1.12 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.29 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.30
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.29	Thu Feb 21 12:17:52 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Sat Feb 23 08:19:16 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.29 2019/02/21 12:17:52 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.30 2019/02/23 08:19:16 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.29 2019/02/21 12:17:52 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.30 2019/02/23 08:19:16 maxv Exp $");
 
 #include 
 #include 
@@ -1468,265 +1468,7 @@ svm_vcpu_msr_allow(uint8_t *bitmap, uint
 	}
 }
 
-static void
-svm_asid_alloc(struct nvmm_cpu *vcpu)
-{
-	struct svm_cpudata *cpudata = vcpu->cpudata;
-	struct vmcb *vmcb = cpudata->vmcb;
-	size_t i, oct, bit;
-
-	mutex_enter(_asidlock);
-
-	for (i = 0; i < svm_maxasid; i++) {
-		oct = i / 8;
-		bit = i % 8;
-
-		if (svm_asidmap[oct] & __BIT(bit)) {
-			continue;
-		}
-
-		svm_asidmap[oct] |= __BIT(bit);
-		vmcb->ctrl.guest_asid = i;
-		mutex_exit(_asidlock);
-		return;
-	}
-
-	/*
-	 * No free ASID. Use the last one, which is shared and requires
-	 * special TLB handling.
-	 */
-	cpudata->shared_asid = true;
-	vmcb->ctrl.guest_asid = svm_maxasid - 1;
-	mutex_exit(_asidlock);
-}
 
-static void
-svm_asid_free(struct nvmm_cpu *vcpu)
-{
-	struct svm_cpudata *cpudata = vcpu->cpudata;
-	struct vmcb *vmcb = cpudata->vmcb;
-	size_t oct, bit;
-
-	if (cpudata->shared_asid) {
-		return;
-	}
-
-	oct = vmcb->ctrl.guest_asid / 8;
-	bit = vmcb->ctrl.guest_asid % 8;
-
-	mutex_enter(_asidlock);
-	svm_asidmap[oct] &= ~__BIT(bit);
-	mutex_exit(_asidlock);
-}
-
-static void
-svm_vcpu_init(struct nvmm_machine *mach, struct nvmm_cpu *vcpu)
-{
-	struct svm_cpudata *cpudata = vcpu->cpudata;
-	struct vmcb *vmcb = cpudata->vmcb;
-
-	/* Allow reads/writes of Control Registers. */
-	vmcb->ctrl.intercept_cr = 0;
-
-	/* Allow reads/writes of Debug Registers. */
-	vmcb->ctrl.intercept_dr = 0;
-
-	/* Allow exceptions 0 to 31. */
-	vmcb->ctrl.intercept_vec = 0;
-
-	/*
-	 * Allow:
-	 *  - SMI [smm interrupts]
-	 *  - VINTR [virtual interrupts]
-	 *  - CR0_SPEC [CR0 writes changing other fields than CR0.TS or CR0.MP]
-	 *  - RIDTR [reads of IDTR]
-	 *  - RGDTR [reads of GDTR]
-	 *  - RLDTR [reads of LDTR]
-	 *  - RTR [reads of TR]
-	 *  - WIDTR [writes of IDTR]
-	 *  - WGDTR [writes of GDTR]
-	 *  - WLDTR [writes of LDTR]
-	 *  - WTR [writes of TR]
-	 *  - RDTSC [rdtsc instruction]
-	 *  - PUSHF [pushf instruction]
-	 *  - POPF [popf instruction]
-	 *  - IRET [iret instruction]
-	 *  - INTN [int $n instructions]
-	 *  - INVD [invd instruction]
-	 *  - PAUSE [pause instruction]
-	 *  - INVLPG [invplg instruction]
-	 *  - TASKSW [task switches]
-	 *
-	 * Intercept the rest below.
-	 */
-	vmcb->ctrl.intercept_misc1 =
-	VMCB_CTRL_INTERCEPT_INTR |
-	VMCB_CTRL_INTERCEPT_NMI |
-	VMCB_CTRL_INTERCEPT_INIT |
-	VMCB_CTRL_INTERCEPT_RDPMC |
-	VMCB_CTRL_INTERCEPT_CPUID |
-	VMCB_CTRL_INTERCEPT_RSM |
-	VMCB_CTRL_INTERCEPT_HLT |
-	VMCB_CTRL_INTERCEPT_INVLPGA |
-	VMCB_CTRL_INTERCEPT_IOIO_PROT |
-	VMCB_CTRL_INTERCEPT_MSR_PROT |
-	VMCB_CTRL_INTERCEPT_FERR_FREEZE |
-	VMCB_CTRL_INTERCEPT_SHUTDOWN;
-
-	/*
-	 * Allow:
-	 *  - ICEBP [icebp instruction]
-	 *  - WBINVD [wbinvd instruction]
-	 *  - WCR_SPEC(0..15) [writes of CR0-15, received after instruction]
-	 *
-	 * Intercept the rest below.
-	 */
-	vmcb->ctrl.intercept_misc2 =
-	VMCB_CTRL_INTERCEPT_VMRUN |
-	VMCB_CTRL_INTERCEPT_VMMCALL |
-	VMCB_CTRL_INTERCEPT_VMLOAD |
-	VMCB_CTRL_INTERCEPT_VMSAVE |
-	VMCB_CTRL_INTERCEPT_STGI |
-	VMCB_CTRL_INTERCEPT_CLGI |
-	VMCB_CTRL_INTERCEPT_SKINIT |
-	VMCB_CTRL_INTERCEPT_RDTSCP |
-	VMCB_CTRL_INTERCEPT_MONITOR |
-	VMCB_CTRL_INTERCEPT_MWAIT |
-	VMCB_CTRL_INTERCEPT_XSETBV;
-
-	/* Intercept all I/O accesses. */
-	memset(cpudata->iobm, 0xFF, IOBM_SIZE);
-	vmcb->ctrl.iopm_base_pa = cpudata->iobm_pa;
-
-	/*
-	 * Allow:
-	 *  - EFER [read]
-	 *  - STAR [read, write]
-	 *  - LSTAR [read, write]
-	 *  - CSTAR [read, write]
-	 *  - SFMASK [read, write]
-	 *  - KERNELGSBASE [read, write]
-	 *  - SYSENTER_CS [read, write]
-	 *  - SYSENTER_ESP [read, write]
-	 *  - SYSENTER_EIP [read, write]
-	 *  - FSBASE [read, write]
-	 *  - GSBASE [read, write]
-	 

CVS commit: src/sys/dev/nvmm/x86

2019-02-22 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Fri Feb 22 12:24:34 UTC 2019

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_vmx.c

Log Message:
Fix omission: if we receive a guest trap on CR0, and if the original
instruction would have resulted in Long Mode being enabled, we need to
manually enable Long Mode ourselves. We were already doing that correctly
in setstate, but not in the CR0 trap handler.

Problem initially reported by Aymeric Vincent; ArchLinux wouldn't boot,
now it does and works correctly.

While here, add CR0_ET in the CR0 mask, for the associated shadow to
be taken into account. Normally this shadow bit shouldn't be necessary,
but for now I keep it regardless.


To generate a diff of this commit:
cvs rdiff -u -r1.10 -r1.11 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_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.10 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.11
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.10	Thu Feb 21 13:25:44 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Fri Feb 22 12:24:34 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.10 2019/02/21 13:25:44 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.11 2019/02/22 12:24:34 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.10 2019/02/21 13:25:44 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.11 2019/02/22 12:24:34 maxv Exp $");
 
 #include 
 #include 
@@ -1154,6 +1154,7 @@ vmx_inkernel_handle_cr0(struct nvmm_mach
 {
 	struct vmx_cpudata *cpudata = vcpu->cpudata;
 	uint64_t type, gpr, cr0;
+	uint64_t efer, ctls1;
 
 	type = __SHIFTOUT(qual, VMX_QUAL_CR_TYPE);
 	if (type != CR_TYPE_WRITE) {
@@ -1176,6 +1177,25 @@ vmx_inkernel_handle_cr0(struct nvmm_mach
 		return -1;
 	}
 
+	/*
+	 * XXX Handle 32bit PAE paging, need to set PDPTEs, fetched manually
+	 * from CR3.
+	 */
+
+	if (cr0 & CR0_PG) {
+		vmx_vmread(VMCS_ENTRY_CTLS, );
+		vmx_vmread(VMCS_GUEST_IA32_EFER, );
+		if (efer & EFER_LME) {
+			ctls1 |= ENTRY_CTLS_LONG_MODE;
+			efer |= EFER_LMA;
+		} else {
+			ctls1 &= ~ENTRY_CTLS_LONG_MODE;
+			efer &= ~EFER_LMA;
+		}
+		vmx_vmwrite(VMCS_GUEST_IA32_EFER, efer);
+		vmx_vmwrite(VMCS_ENTRY_CTLS, ctls1);
+	}
+
 	vmx_vmwrite(VMCS_GUEST_CR0, cr0);
 	vmx_inkernel_advance();
 	return 0;
@@ -2043,7 +2063,7 @@ vmx_vcpu_init(struct nvmm_machine *mach,
 	vmx_vmwrite(VMCS_EXIT_MSR_STORE_COUNT, VMX_MSRLIST_EXIT_NMSR);
 
 	/* Force CR0_NW and CR0_CD to zero, CR0_ET to one. */
-	vmx_vmwrite(VMCS_CR0_MASK, CR0_NW|CR0_CD);
+	vmx_vmwrite(VMCS_CR0_MASK, CR0_NW|CR0_CD|CR0_ET);
 	vmx_vmwrite(VMCS_CR0_SHADOW, CR0_ET);
 
 	/* Force CR4_VMXE to zero. */



CVS commit: src/sys/dev/nvmm/x86

2019-02-21 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Thu Feb 21 13:25:44 UTC 2019

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_vmx.c

Log Message:
Reorder the detection in vmx_ident(), to fix panic on old CPUs. We must
read MSR_IA32_VMX_EPT_VPID_CAP _after_ ensuring EPT is there, because if
it's not, the rdmsr faults.


To generate a diff of this commit:
cvs rdiff -u -r1.9 -r1.10 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_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.9 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.10
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.9	Thu Feb 21 12:17:52 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Thu Feb 21 13:25:44 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.9 2019/02/21 12:17:52 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.10 2019/02/21 13:25:44 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.9 2019/02/21 12:17:52 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.10 2019/02/21 13:25:44 maxv Exp $");
 
 #include 
 #include 
@@ -2655,23 +2655,6 @@ vmx_ident(void)
 		return false;
 	}
 
-	msr = rdmsr(MSR_IA32_VMX_EPT_VPID_CAP);
-	if ((msr & IA32_VMX_EPT_VPID_WALKLENGTH_4) == 0) {
-		return false;
-	}
-	if ((msr & IA32_VMX_EPT_VPID_INVEPT) == 0) {
-		return false;
-	}
-	if ((msr & IA32_VMX_EPT_VPID_INVVPID) == 0) {
-		return false;
-	}
-	if ((msr & IA32_VMX_EPT_VPID_FLAGS_AD) == 0) {
-		return false;
-	}
-	if (!(msr & IA32_VMX_EPT_VPID_UC) && !(msr & IA32_VMX_EPT_VPID_WB)) {
-		return false;
-	}
-
 	/* PG and PE are reported, even if Unrestricted Guests is supported. */
 	vmx_cr0_fixed0 = rdmsr(MSR_IA32_VMX_CR0_FIXED0) & ~(CR0_PG|CR0_PE);
 	vmx_cr0_fixed1 = rdmsr(MSR_IA32_VMX_CR0_FIXED1) | (CR0_PG|CR0_PE);
@@ -2724,6 +2707,23 @@ vmx_ident(void)
 		return false;
 	}
 
+	msr = rdmsr(MSR_IA32_VMX_EPT_VPID_CAP);
+	if ((msr & IA32_VMX_EPT_VPID_WALKLENGTH_4) == 0) {
+		return false;
+	}
+	if ((msr & IA32_VMX_EPT_VPID_INVEPT) == 0) {
+		return false;
+	}
+	if ((msr & IA32_VMX_EPT_VPID_INVVPID) == 0) {
+		return false;
+	}
+	if ((msr & IA32_VMX_EPT_VPID_FLAGS_AD) == 0) {
+		return false;
+	}
+	if (!(msr & IA32_VMX_EPT_VPID_UC) && !(msr & IA32_VMX_EPT_VPID_WB)) {
+		return false;
+	}
+
 	return true;
 }
 



CVS commit: src/sys/dev/nvmm/x86

2019-02-21 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Thu Feb 21 11:58:04 UTC 2019

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_svm.c nvmm_x86_vmx.c

Log Message:
Clarify the gTLB code a little.


To generate a diff of this commit:
cvs rdiff -u -r1.27 -r1.28 src/sys/dev/nvmm/x86/nvmm_x86_svm.c
cvs rdiff -u -r1.7 -r1.8 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.27 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.28
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.27	Mon Feb 18 12:17:45 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Thu Feb 21 11:58:04 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.27 2019/02/18 12:17:45 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.28 2019/02/21 11:58:04 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.27 2019/02/18 12:17:45 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.28 2019/02/21 11:58:04 maxv Exp $");
 
 #include 
 #include 
@@ -502,7 +502,7 @@ static const size_t svm_conf_sizes[NVMM_
 struct svm_cpudata {
 	/* General */
 	bool shared_asid;
-	bool tlb_want_flush;
+	bool gtlb_want_flush;
 
 	/* VMCB */
 	struct vmcb *vmcb;
@@ -977,7 +977,7 @@ svm_inkernel_handle_msr(struct nvmm_mach
 			}
 			if ((vmcb->state.efer ^ exit->u.msr.val) &
 			 EFER_TLB_FLUSH) {
-cpudata->tlb_want_flush = true;
+cpudata->gtlb_want_flush = true;
 			}
 			vmcb->state.efer = exit->u.msr.val | EFER_SVME;
 			svm_vmcb_cache_flush(vmcb, VMCB_CTRL_VMCB_CLEAN_CR);
@@ -1185,21 +1185,30 @@ svm_vcpu_guest_misc_leave(struct nvmm_cp
 	wrmsr(MSR_KERNELGSBASE, cpudata->kernelgsbase);
 }
 
+/* -- */
+
+static inline void
+svm_gtlb_catchup(struct nvmm_cpu *vcpu, int hcpu)
+{
+	struct svm_cpudata *cpudata = vcpu->cpudata;
+
+	if (vcpu->hcpu_last != hcpu || cpudata->shared_asid) {
+		cpudata->gtlb_want_flush = true;
+	}
+}
+
 static int
 svm_vcpu_run(struct nvmm_machine *mach, struct nvmm_cpu *vcpu,
 struct nvmm_exit *exit)
 {
 	struct svm_cpudata *cpudata = vcpu->cpudata;
 	struct vmcb *vmcb = cpudata->vmcb;
-	bool tlb_need_flush = false;
 	int hcpu, s;
 
 	kpreempt_disable();
 	hcpu = cpu_number();
 
-	if (vcpu->hcpu_last != hcpu || cpudata->shared_asid) {
-		tlb_need_flush = true;
-	}
+	svm_gtlb_catchup(vcpu, hcpu);
 
 	if (vcpu->hcpu_last != hcpu) {
 		vmcb->ctrl.tsc_offset = cpudata->tsc_offset +
@@ -1211,7 +1220,7 @@ svm_vcpu_run(struct nvmm_machine *mach, 
 	svm_vcpu_guest_misc_enter(vcpu);
 
 	while (1) {
-		if (cpudata->tlb_want_flush || tlb_need_flush) {
+		if (cpudata->gtlb_want_flush) {
 			vmcb->ctrl.tlb_ctrl = svm_ctrl_tlb_flush;
 		} else {
 			vmcb->ctrl.tlb_ctrl = 0;
@@ -1226,8 +1235,7 @@ svm_vcpu_run(struct nvmm_machine *mach, 
 		svm_vmcb_cache_default(vmcb);
 
 		if (vmcb->ctrl.exitcode != VMCB_EXITCODE_INVALID) {
-			cpudata->tlb_want_flush = false;
-			tlb_need_flush = false;
+			cpudata->gtlb_want_flush = false;
 			vcpu->hcpu_last = hcpu;
 		}
 
@@ -1751,7 +1759,7 @@ svm_vcpu_setstate(struct nvmm_cpu *vcpu,
 	struct fxsave *fpustate;
 
 	if (svm_state_tlb_flush(vmcb, state, flags)) {
-		cpudata->tlb_want_flush = true;
+		cpudata->gtlb_want_flush = true;
 	}
 
 	if (flags & NVMM_X64_STATE_SEGS) {
@@ -1985,7 +1993,7 @@ svm_tlb_flush(struct pmap *pm)
 		if (error)
 			continue;
 		cpudata = vcpu->cpudata;
-		cpudata->tlb_want_flush = true;
+		cpudata->gtlb_want_flush = true;
 		nvmm_vcpu_put(vcpu);
 	}
 }

Index: src/sys/dev/nvmm/x86/nvmm_x86_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.7 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.8
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.7	Mon Feb 18 12:17:45 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Thu Feb 21 11:58:04 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.7 2019/02/18 12:17:45 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.8 2019/02/21 11:58:04 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.7 2019/02/18 12:17:45 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.8 2019/02/21 11:58:04 maxv Exp $");
 
 #include 
 #include 
@@ -637,7 +637,7 @@ static const size_t vmx_conf_sizes[NVMM_
 struct vmx_cpudata {
 	/* General */
 	uint64_t asid;
-	bool tlb_want_flush;
+	bool gtlb_want_flush;
 
 	/* VMCS */
 	struct vmcs *vmcs;
@@ -1601,6 +1601,8 @@ vmx_vcpu_guest_misc_leave(struct nvmm_cp
 	wrmsr(MSR_KERNELGSBASE, cpudata->kernelgsbase);
 }
 
+/* - */
+
 #define VMX_INVVPID_ADDRESS		0
 #define VMX_INVVPID_CONTEXT		1
 #define VMX_INVVPID_ALL			2
@@ -1609,13 +1611,22 @@ vmx_vcpu_guest_misc_leave(struct nvmm_cp
 #define VMX_INVEPT_CONTEXT		1
 

CVS commit: src/sys/dev/nvmm

2019-02-18 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Mon Feb 18 12:17:45 UTC 2019

Modified Files:
src/sys/dev/nvmm: nvmm.c
src/sys/dev/nvmm/x86: nvmm_x86_svm.c nvmm_x86_vmx.c

Log Message:
Ah, finally found you. Fix scheduling bug in NVMM.

When processing guest page faults, we were calling uvm_fault with
preemption disabled. The thing is, uvm_fault may block, and if it does,
we land in sleepq_block which calls mi_switch; so we get switched away
while we explicitly asked not to be. From then on things could go really
wrong.

Fix that by processing such faults in MI, where we have preemption enabled
and are allowed to block.

A KASSERT in sleepq_block (or before) would have helped.


To generate a diff of this commit:
cvs rdiff -u -r1.7 -r1.8 src/sys/dev/nvmm/nvmm.c
cvs rdiff -u -r1.26 -r1.27 src/sys/dev/nvmm/x86/nvmm_x86_svm.c
cvs rdiff -u -r1.6 -r1.7 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/nvmm.c
diff -u src/sys/dev/nvmm/nvmm.c:1.7 src/sys/dev/nvmm/nvmm.c:1.8
--- src/sys/dev/nvmm/nvmm.c:1.7	Wed Feb 13 16:03:16 2019
+++ src/sys/dev/nvmm/nvmm.c	Mon Feb 18 12:17:45 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm.c,v 1.7 2019/02/13 16:03:16 maxv Exp $	*/
+/*	$NetBSD: nvmm.c,v 1.8 2019/02/18 12:17:45 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.7 2019/02/13 16:03:16 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.8 2019/02/18 12:17:45 maxv Exp $");
 
 #include 
 #include 
@@ -478,6 +478,24 @@ out:
 	return error;
 }
 
+static void
+nvmm_do_vcpu_run(struct nvmm_machine *mach, struct nvmm_cpu *vcpu,
+struct nvmm_exit *exit)
+{
+	struct vmspace *vm = mach->vm;
+
+	while (1) {
+		(*nvmm_impl->vcpu_run)(mach, vcpu, exit);
+
+		if (__predict_true(exit->reason != NVMM_EXIT_MEMORY)) {
+			break;
+		}
+		if (uvm_fault(>vm_map, exit->u.mem.gpa, VM_PROT_ALL)) {
+			break;
+		}
+	}
+}
+
 static int
 nvmm_vcpu_run(struct nvmm_ioc_vcpu_run *args)
 {
@@ -493,7 +511,7 @@ nvmm_vcpu_run(struct nvmm_ioc_vcpu_run *
 	if (error)
 		goto out;
 
-	(*nvmm_impl->vcpu_run)(mach, vcpu, >exit);
+	nvmm_do_vcpu_run(mach, vcpu, >exit);
 	nvmm_vcpu_put(vcpu);
 
 out:

Index: src/sys/dev/nvmm/x86/nvmm_x86_svm.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.26 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.27
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.26	Sat Feb 16 12:58:13 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Mon Feb 18 12:17:45 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.26 2019/02/16 12:58:13 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.27 2019/02/18 12:17:45 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.26 2019/02/16 12:58:13 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.27 2019/02/18 12:17:45 maxv Exp $");
 
 #include 
 #include 
@@ -1048,25 +1048,18 @@ svm_exit_npf(struct nvmm_machine *mach, 
 {
 	struct svm_cpudata *cpudata = vcpu->cpudata;
 	gpaddr_t gpa = cpudata->vmcb->ctrl.exitinfo2;
-	int error;
-
-	error = uvm_fault(>vm->vm_map, gpa, VM_PROT_ALL);
 
-	if (error) {
-		exit->reason = NVMM_EXIT_MEMORY;
-		if (cpudata->vmcb->ctrl.exitinfo1 & PGEX_W)
-			exit->u.mem.perm = NVMM_EXIT_MEMORY_WRITE;
-		else if (cpudata->vmcb->ctrl.exitinfo1 & PGEX_X)
-			exit->u.mem.perm = NVMM_EXIT_MEMORY_EXEC;
-		else
-			exit->u.mem.perm = NVMM_EXIT_MEMORY_READ;
-		exit->u.mem.gpa = gpa;
-		exit->u.mem.inst_len = cpudata->vmcb->ctrl.inst_len;
-		memcpy(exit->u.mem.inst_bytes, cpudata->vmcb->ctrl.inst_bytes,
-		sizeof(exit->u.mem.inst_bytes));
-	} else {
-		exit->reason = NVMM_EXIT_NONE;
-	}
+	exit->reason = NVMM_EXIT_MEMORY;
+	if (cpudata->vmcb->ctrl.exitinfo1 & PGEX_W)
+		exit->u.mem.perm = NVMM_EXIT_MEMORY_WRITE;
+	else if (cpudata->vmcb->ctrl.exitinfo1 & PGEX_X)
+		exit->u.mem.perm = NVMM_EXIT_MEMORY_EXEC;
+	else
+		exit->u.mem.perm = NVMM_EXIT_MEMORY_READ;
+	exit->u.mem.gpa = gpa;
+	exit->u.mem.inst_len = cpudata->vmcb->ctrl.inst_len;
+	memcpy(exit->u.mem.inst_bytes, cpudata->vmcb->ctrl.inst_bytes,
+	sizeof(exit->u.mem.inst_bytes));
 }
 
 static void

Index: src/sys/dev/nvmm/x86/nvmm_x86_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.6 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.7
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.6	Sat Feb 16 12:40:31 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Mon Feb 18 12:17:45 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.6 2019/02/16 12:40:31 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.7 2019/02/18 12:17:45 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.6 2019/02/16 12:40:31 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.7 2019/02/18 12:17:45 maxv Exp $");
 
 #include 
 #include 

CVS commit: src/sys/dev/nvmm/x86

2019-02-16 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Sat Feb 16 12:58:14 UTC 2019

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_svm.c

Log Message:
Ah no, adapt previous, on AMD RAX is in the VMCB.


To generate a diff of this commit:
cvs rdiff -u -r1.25 -r1.26 src/sys/dev/nvmm/x86/nvmm_x86_svm.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.25 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.26
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.25	Sat Feb 16 12:40:31 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Sat Feb 16 12:58:13 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.25 2019/02/16 12:40:31 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.26 2019/02/16 12:58:13 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.25 2019/02/16 12:40:31 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.26 2019/02/16 12:58:13 maxv Exp $");
 
 #include 
 #include 
@@ -772,7 +772,7 @@ svm_inkernel_handle_cpuid(struct nvmm_cp
 		}
 		switch (ecx) {
 		case 0:
-			cpudata->gprs[NVMM_X64_GPR_RAX] = svm_xcr0_mask & 0x;
+			cpudata->vmcb->state.rax = svm_xcr0_mask & 0x;
 			if (cpudata->gxcr0 & XCR0_SSE) {
 cpudata->gprs[NVMM_X64_GPR_RBX] = sizeof(struct fxsave);
 			} else {
@@ -783,7 +783,7 @@ svm_inkernel_handle_cpuid(struct nvmm_cp
 			cpudata->gprs[NVMM_X64_GPR_RDX] = svm_xcr0_mask >> 32;
 			break;
 		case 1:
-			cpudata->gprs[NVMM_X64_GPR_RAX] &= ~CPUID_PES1_XSAVES;
+			cpudata->vmcb->state.rax &= ~CPUID_PES1_XSAVES;
 			break;
 		}
 		break;



CVS commit: src/sys/dev/nvmm/x86

2019-02-16 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Sat Feb 16 12:40:31 UTC 2019

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_svm.c nvmm_x86_vmx.c

Log Message:
Improve the FPU detection: hide XSAVES because we're not allowing it, and
don't set CPUID2_OSXSAVE if the guest didn't first set CR4_OSXSAVE.

With these changes in place, I can boot Windows 10 on NVMM.


To generate a diff of this commit:
cvs rdiff -u -r1.24 -r1.25 src/sys/dev/nvmm/x86/nvmm_x86_svm.c
cvs rdiff -u -r1.5 -r1.6 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.24 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.25
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.24	Fri Feb 15 13:17:05 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Sat Feb 16 12:40:31 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.24 2019/02/15 13:17:05 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.25 2019/02/16 12:40:31 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.24 2019/02/15 13:17:05 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.25 2019/02/16 12:40:31 maxv Exp $");
 
 #include 
 #include 
@@ -752,26 +752,40 @@ static void
 svm_inkernel_handle_cpuid(struct nvmm_cpu *vcpu, uint64_t eax, uint64_t ecx)
 {
 	struct svm_cpudata *cpudata = vcpu->cpudata;
+	uint64_t cr4;
 
 	switch (eax) {
-	case 0x0001: /* APIC number in RBX. The rest is tunable. */
+	case 0x0001:
 		cpudata->gprs[NVMM_X64_GPR_RBX] &= ~CPUID_LOCAL_APIC_ID;
 		cpudata->gprs[NVMM_X64_GPR_RBX] |= __SHIFTIN(vcpu->cpuid,
 		CPUID_LOCAL_APIC_ID);
+
+		/* CPUID2_OSXSAVE depends on CR4. */
+		cr4 = cpudata->vmcb->state.cr4;
+		if (!(cr4 & CR4_OSXSAVE)) {
+			cpudata->gprs[NVMM_X64_GPR_RCX] &= ~CPUID2_OSXSAVE;
+		}
 		break;
-	case 0x000D: /* FPU description. Not tunable. */
-		if (ecx != 0 || svm_xcr0_mask == 0) {
+	case 0x000D:
+		if (svm_xcr0_mask == 0) {
 			break;
 		}
-		cpudata->vmcb->state.rax = svm_xcr0_mask & 0x;
-		if (cpudata->gxcr0 & XCR0_SSE) {
-			cpudata->gprs[NVMM_X64_GPR_RBX] = sizeof(struct fxsave);
-		} else {
-			cpudata->gprs[NVMM_X64_GPR_RBX] = sizeof(struct save87);
+		switch (ecx) {
+		case 0:
+			cpudata->gprs[NVMM_X64_GPR_RAX] = svm_xcr0_mask & 0x;
+			if (cpudata->gxcr0 & XCR0_SSE) {
+cpudata->gprs[NVMM_X64_GPR_RBX] = sizeof(struct fxsave);
+			} else {
+cpudata->gprs[NVMM_X64_GPR_RBX] = sizeof(struct save87);
+			}
+			cpudata->gprs[NVMM_X64_GPR_RBX] += 64; /* XSAVE header */
+			cpudata->gprs[NVMM_X64_GPR_RCX] = sizeof(struct fxsave);
+			cpudata->gprs[NVMM_X64_GPR_RDX] = svm_xcr0_mask >> 32;
+			break;
+		case 1:
+			cpudata->gprs[NVMM_X64_GPR_RAX] &= ~CPUID_PES1_XSAVES;
+			break;
 		}
-		cpudata->gprs[NVMM_X64_GPR_RBX] += 64; /* XSAVE header */
-		cpudata->gprs[NVMM_X64_GPR_RCX] = sizeof(struct fxsave);
-		cpudata->gprs[NVMM_X64_GPR_RDX] = svm_xcr0_mask >> 32;
 		break;
 	case 0x4000:
 		cpudata->gprs[NVMM_X64_GPR_RBX] = 0;
@@ -781,7 +795,7 @@ svm_inkernel_handle_cpuid(struct nvmm_cp
 		memcpy(>gprs[NVMM_X64_GPR_RCX], "NVMM", 4);
 		memcpy(>gprs[NVMM_X64_GPR_RDX], " ___", 4);
 		break;
-	case 0x8001: /* No SVM, no RDTSCP. The rest is tunable. */
+	case 0x8001:
 		cpudata->gprs[NVMM_X64_GPR_RCX] &= ~CPUID_SVM;
 		cpudata->gprs[NVMM_X64_GPR_RDX] &= ~CPUID_RDTSCP;
 		break;

Index: src/sys/dev/nvmm/x86/nvmm_x86_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.5 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.6
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.5	Sat Feb 16 12:05:30 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Sat Feb 16 12:40:31 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.5 2019/02/16 12:05:30 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.6 2019/02/16 12:40:31 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.5 2019/02/16 12:05:30 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.6 2019/02/16 12:40:31 maxv Exp $");
 
 #include 
 #include 
@@ -984,6 +984,7 @@ static void
 vmx_inkernel_handle_cpuid(struct nvmm_cpu *vcpu, uint64_t eax, uint64_t ecx)
 {
 	struct vmx_cpudata *cpudata = vcpu->cpudata;
+	uint64_t cr4;
 
 	switch (eax) {
 	case 0x0001:
@@ -995,6 +996,12 @@ vmx_inkernel_handle_cpuid(struct nvmm_cp
 		  CPUID2_PCID|CPUID2_DEADLINE);
 		cpudata->gprs[NVMM_X64_GPR_RDX] &=
 		~(CPUID_DS|CPUID_ACPI|CPUID_TM);
+
+		/* CPUID2_OSXSAVE depends on CR4. */
+		vmx_vmread(VMCS_GUEST_CR4, );
+		if (!(cr4 & CR4_OSXSAVE)) {
+			cpudata->gprs[NVMM_X64_GPR_RCX] &= ~CPUID2_OSXSAVE;
+		}
 		break;
 	case 0x0005:
 	case 0x0006:
@@ -1010,18 +1017,25 @@ vmx_inkernel_handle_cpuid(struct nvmm_cp
 		  CPUID_SEF_SSBD);
 		break;
 	case 0x000D:
-		if (ecx != 0 || 

CVS commit: src/sys/dev/nvmm/x86

2019-02-15 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Fri Feb 15 13:17:05 UTC 2019

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_svm.c nvmm_x86_vmx.c

Log Message:
Initialize the guest TSC to zero at VCPU creation time, and handle guest
writes to MSR_TSC at run time.

This is imprecise, because the hardware does not provide a way to preserve
the TSC during #VMEXITs, but that's fine enough.


To generate a diff of this commit:
cvs rdiff -u -r1.23 -r1.24 src/sys/dev/nvmm/x86/nvmm_x86_svm.c
cvs rdiff -u -r1.3 -r1.4 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.23 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.24
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.23	Thu Feb 14 14:30:20 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Fri Feb 15 13:17:05 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.23 2019/02/14 14:30:20 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.24 2019/02/15 13:17:05 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.23 2019/02/14 14:30:20 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.24 2019/02/15 13:17:05 maxv Exp $");
 
 #include 
 #include 
@@ -46,6 +46,7 @@ __KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include 
@@ -965,7 +966,14 @@ svm_inkernel_handle_msr(struct nvmm_mach
 cpudata->tlb_want_flush = true;
 			}
 			vmcb->state.efer = exit->u.msr.val | EFER_SVME;
-			vmcb->ctrl.vmcb_clean &= ~VMCB_CTRL_VMCB_CLEAN_CR;
+			svm_vmcb_cache_flush(vmcb, VMCB_CTRL_VMCB_CLEAN_CR);
+			goto handled;
+		}
+		if (exit->u.msr.msr == MSR_TSC) {
+			cpudata->tsc_offset = exit->u.msr.val - cpu_counter();
+			vmcb->ctrl.tsc_offset = cpudata->tsc_offset +
+			curcpu()->ci_data.cpu_cc_skew;
+			svm_vmcb_cache_flush(vmcb, VMCB_CTRL_VMCB_CLEAN_I);
 			goto handled;
 		}
 		for (i = 0; i < __arraycount(msr_ignore_list); i++) {
@@ -1582,8 +1590,8 @@ svm_vcpu_init(struct nvmm_machine *mach,
 	cpudata->gfpu.xsh_xstate_bv = svm_xcr0_mask;
 	cpudata->gfpu.xsh_xcomp_bv = 0;
 
-	/* Bluntly hide the host TSC. */
-	cpudata->tsc_offset = rdtsc();
+	/* Set guest TSC to zero, more or less. */
+	cpudata->tsc_offset = -cpu_counter();
 
 	/* These MSRs are static. */
 	cpudata->star = rdmsr(MSR_STAR);

Index: src/sys/dev/nvmm/x86/nvmm_x86_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.3 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.4
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.3	Thu Feb 14 14:30:20 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Fri Feb 15 13:17:05 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.3 2019/02/14 14:30:20 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.4 2019/02/15 13:17:05 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.3 2019/02/14 14:30:20 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.4 2019/02/15 13:17:05 maxv Exp $");
 
 #include 
 #include 
@@ -46,6 +46,7 @@ __KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include 
@@ -1370,6 +1371,12 @@ vmx_inkernel_handle_msr(struct nvmm_mach
 		}
 		break;
 	case NVMM_EXIT_MSR_WRMSR:
+		if (exit->u.msr.msr == MSR_TSC) {
+			cpudata->tsc_offset = exit->u.msr.val - cpu_counter();
+			vmx_vmwrite(VMCS_TSC_OFFSET, cpudata->tsc_offset +
+			curcpu()->ci_data.cpu_cc_skew);
+			goto handled;
+		}
 		if (exit->u.msr.msr == MSR_CR_PAT) {
 			vmx_vmwrite(VMCS_GUEST_IA32_PAT, exit->u.msr.val);
 			goto handled;
@@ -2009,8 +2016,8 @@ vmx_vcpu_init(struct nvmm_machine *mach,
 	cpudata->gfpu.xsh_xstate_bv = vmx_xcr0_mask;
 	cpudata->gfpu.xsh_xcomp_bv = 0;
 
-	/* Bluntly hide the host TSC. */
-	cpudata->tsc_offset = rdtsc();
+	/* Set guest TSC to zero, more or less. */
+	cpudata->tsc_offset = -cpu_counter();
 
 	/* These MSRs are static. */
 	cpudata->star = rdmsr(MSR_STAR);



CVS commit: src/sys/dev/nvmm/x86

2019-02-14 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Thu Feb 14 09:37:32 UTC 2019

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_vmx.c

Log Message:
On AMD, the segments have a simple "present" bit. On Intel however there
is an extra "unusable" bit, which has a twisted meaning. We can't just
ignore this bit, because when unset, the CPU performs extra checks on the
other attributes, which may cause VMENTRY to fail and the guest to be
killed.

Typically, on Qemu, some guests like Windows XP trigger two consecutive
getstate+setstate calls, and while processing them, we end up wrongfully
removing the "unusable" bits that were previously set.

Fix that by forcing "unusable = !present". Each hypervisor I could check
does something different, but this seems to be the least problematic
solution for now.

While here, the fields of vmx_guest_segs are VMX indexes, so they should
be uint64_t (no functional change).


To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.2 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_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.1 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.2
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.1	Wed Feb 13 16:03:16 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Thu Feb 14 09:37:31 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.1 2019/02/13 16:03:16 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.2 2019/02/14 09:37:31 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.1 2019/02/13 16:03:16 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.2 2019/02/14 09:37:31 maxv Exp $");
 
 #include 
 #include 
@@ -674,9 +674,9 @@ struct vmx_cpudata {
 };
 
 static const struct {
-	uint16_t selector;
-	uint16_t attrib;
-	uint32_t limit;
+	uint64_t selector;
+	uint64_t attrib;
+	uint64_t limit;
 	uint64_t base;
 } vmx_guest_segs[NVMM_X64_NSEG] = {
 	[NVMM_X64_SEG_ES] = {
@@ -2113,7 +2113,8 @@ vmx_vcpu_setstate_seg(struct nvmm_x64_st
 	__SHIFTIN(segs[idx].attrib.avl, VMX_SEG_ATTRIB_AVL) |
 	__SHIFTIN(segs[idx].attrib.lng, VMX_SEG_ATTRIB_LONG) |
 	__SHIFTIN(segs[idx].attrib.def32, VMX_SEG_ATTRIB_DEF32) |
-	__SHIFTIN(segs[idx].attrib.gran, VMX_SEG_ATTRIB_GRAN);
+	__SHIFTIN(segs[idx].attrib.gran, VMX_SEG_ATTRIB_GRAN) |
+	(!segs[idx].attrib.p ? VMX_SEG_ATTRIB_UNUSABLE : 0);
 
 	if (idx != NVMM_X64_SEG_GDT && idx != NVMM_X64_SEG_IDT) {
 		vmx_vmwrite(vmx_guest_segs[idx].selector, segs[idx].selector);
@@ -2142,6 +2143,9 @@ vmx_vcpu_getstate_seg(struct nvmm_x64_st
 	segs[idx].attrib.lng = __SHIFTOUT(attrib, VMX_SEG_ATTRIB_LONG);
 	segs[idx].attrib.def32 = __SHIFTOUT(attrib, VMX_SEG_ATTRIB_DEF32);
 	segs[idx].attrib.gran = __SHIFTOUT(attrib, VMX_SEG_ATTRIB_GRAN);
+	if (attrib & VMX_SEG_ATTRIB_UNUSABLE) {
+		segs[idx].attrib.p = 0;
+	}
 }
 
 static inline bool



CVS commit: src/sys/dev/nvmm/x86

2019-02-13 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Wed Feb 13 10:55:13 UTC 2019

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_svm.c

Log Message:
Drop support for software interrupts. I had initially added that to cover
the three event types available on AMD, but Intel has seven of them, all
with weird and twisted meanings, and they require extra parameters.

Software interrupts should not be used anyway.


To generate a diff of this commit:
cvs rdiff -u -r1.21 -r1.22 src/sys/dev/nvmm/x86/nvmm_x86_svm.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.21 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.22
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.21	Wed Feb 13 07:04:12 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Wed Feb 13 10:55:13 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.21 2019/02/13 07:04:12 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.22 2019/02/13 10:55:13 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.21 2019/02/13 07:04:12 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.22 2019/02/13 10:55:13 maxv Exp $");
 
 #include 
 #include 
@@ -688,13 +688,13 @@ svm_vcpu_inject(struct nvmm_machine *mac
 		err = 0;
 		break;
 	case NVMM_EVENT_INTERRUPT_SW:
-		type = SVM_EVENT_TYPE_SW_INT;
-		err = 0;
-		break;
+		return EINVAL;
 	case NVMM_EVENT_EXCEPTION:
 		type = SVM_EVENT_TYPE_EXC;
 		if (event->vector == 2 || event->vector >= 32)
 			return EINVAL;
+		if (event->vector == 3 || event->vector == 0)
+			return EINVAL;
 		err = svm_event_has_error(event->vector);
 		break;
 	default:



CVS commit: src/sys/dev/nvmm/x86

2019-02-12 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Wed Feb 13 07:04:13 UTC 2019

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_svm.c

Log Message:
Micro optimization: the STAR/LSTAR/CSTAR/SFMASK MSRs are static, so rather
than saving them on each VMENTRY, save them only once, at VCPU creation
time.


To generate a diff of this commit:
cvs rdiff -u -r1.20 -r1.21 src/sys/dev/nvmm/x86/nvmm_x86_svm.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.20 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.21
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.20	Tue Feb 12 14:54:59 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Wed Feb 13 07:04:12 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.20 2019/02/12 14:54:59 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.21 2019/02/13 07:04:12 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.20 2019/02/12 14:54:59 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.21 2019/02/13 07:04:12 maxv Exp $");
 
 #include 
 #include 
@@ -1157,10 +1157,6 @@ svm_vcpu_guest_misc_enter(struct nvmm_cp
 {
 	struct svm_cpudata *cpudata = vcpu->cpudata;
 
-	cpudata->star = rdmsr(MSR_STAR);
-	cpudata->lstar = rdmsr(MSR_LSTAR);
-	cpudata->cstar = rdmsr(MSR_CSTAR);
-	cpudata->sfmask = rdmsr(MSR_SFMASK);
 	cpudata->fsbase = rdmsr(MSR_FSBASE);
 	cpudata->kernelgsbase = rdmsr(MSR_KERNELGSBASE);
 }
@@ -1592,6 +1588,12 @@ svm_vcpu_init(struct nvmm_machine *mach,
 
 	/* Bluntly hide the host TSC. */
 	cpudata->tsc_offset = rdtsc();
+
+	/* These MSRs are static. */
+	cpudata->star = rdmsr(MSR_STAR);
+	cpudata->lstar = rdmsr(MSR_LSTAR);
+	cpudata->cstar = rdmsr(MSR_CSTAR);
+	cpudata->sfmask = rdmsr(MSR_SFMASK);
 }
 
 static int



CVS commit: src/sys/dev/nvmm/x86

2019-02-12 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Wed Feb 13 06:32:45 UTC 2019

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86.h

Log Message:
Reorder the GPRs to match the CPU encoding, simplifies things on Intel.


To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/sys/dev/nvmm/x86/nvmm_x86.h

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.h
diff -u src/sys/dev/nvmm/x86/nvmm_x86.h:1.3 src/sys/dev/nvmm/x86/nvmm_x86.h:1.4
--- src/sys/dev/nvmm/x86/nvmm_x86.h:1.3	Sun Jan  6 16:10:51 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86.h	Wed Feb 13 06:32:45 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86.h,v 1.3 2019/01/06 16:10:51 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86.h,v 1.4 2019/02/13 06:32:45 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -47,21 +47,21 @@
 
 /* General Purpose Registers. */
 #define NVMM_X64_GPR_RAX		0
-#define NVMM_X64_GPR_RBX		1
-#define NVMM_X64_GPR_RCX		2
-#define NVMM_X64_GPR_RDX		3
-#define NVMM_X64_GPR_R8			4
-#define NVMM_X64_GPR_R9			5
-#define NVMM_X64_GPR_R10		6
-#define NVMM_X64_GPR_R11		7
-#define NVMM_X64_GPR_R12		8
-#define NVMM_X64_GPR_R13		9
-#define NVMM_X64_GPR_R14		10
-#define NVMM_X64_GPR_R15		11
-#define NVMM_X64_GPR_RDI		12
-#define NVMM_X64_GPR_RSI		13
-#define NVMM_X64_GPR_RBP		14
-#define NVMM_X64_GPR_RSP		15
+#define NVMM_X64_GPR_RCX		1
+#define NVMM_X64_GPR_RDX		2
+#define NVMM_X64_GPR_RBX		3
+#define NVMM_X64_GPR_RSP		4
+#define NVMM_X64_GPR_RBP		5
+#define NVMM_X64_GPR_RSI		6
+#define NVMM_X64_GPR_RDI		7
+#define NVMM_X64_GPR_R8			8
+#define NVMM_X64_GPR_R9			9
+#define NVMM_X64_GPR_R10		10
+#define NVMM_X64_GPR_R11		11
+#define NVMM_X64_GPR_R12		12
+#define NVMM_X64_GPR_R13		13
+#define NVMM_X64_GPR_R14		14
+#define NVMM_X64_GPR_R15		15
 #define NVMM_X64_GPR_RIP		16
 #define NVMM_X64_GPR_RFLAGS		17
 #define NVMM_X64_NGPR			18



CVS commit: src/sys/dev/nvmm/x86

2019-02-12 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Tue Feb 12 14:54:59 UTC 2019

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_svm.c

Log Message:
Optimize: the hardware does not clear the TLB flush command after a
VMENTRY, so clear it ourselves, to avoid uselessly flushing the guest
TLB. While here also fix the processing of EFER-induced flushes, they
shouldn't be delayed.


To generate a diff of this commit:
cvs rdiff -u -r1.19 -r1.20 src/sys/dev/nvmm/x86/nvmm_x86_svm.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.19 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.20
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.19	Mon Feb  4 12:11:18 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Tue Feb 12 14:54:59 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.19 2019/02/04 12:11:18 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.20 2019/02/12 14:54:59 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.19 2019/02/04 12:11:18 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.20 2019/02/12 14:54:59 maxv Exp $");
 
 #include 
 #include 
@@ -1194,12 +1194,6 @@ svm_vcpu_run(struct nvmm_machine *mach, 
 		tlb_need_flush = true;
 	}
 
-	if (cpudata->tlb_want_flush || tlb_need_flush) {
-		vmcb->ctrl.tlb_ctrl = svm_ctrl_tlb_flush;
-	} else {
-		vmcb->ctrl.tlb_ctrl = 0;
-	}
-
 	if (vcpu->hcpu_last != hcpu) {
 		vmcb->ctrl.tsc_offset = cpudata->tsc_offset +
 		curcpu()->ci_data.cpu_cc_skew;
@@ -1210,6 +1204,12 @@ svm_vcpu_run(struct nvmm_machine *mach, 
 	svm_vcpu_guest_misc_enter(vcpu);
 
 	while (1) {
+		if (cpudata->tlb_want_flush || tlb_need_flush) {
+			vmcb->ctrl.tlb_ctrl = svm_ctrl_tlb_flush;
+		} else {
+			vmcb->ctrl.tlb_ctrl = 0;
+		}
+
 		s = splhigh();
 		svm_vcpu_guest_fpu_enter(vcpu);
 		svm_vmrun(cpudata->vmcb_pa, cpudata->gprs);
@@ -1219,9 +1219,8 @@ svm_vcpu_run(struct nvmm_machine *mach, 
 		svm_vmcb_cache_default(vmcb);
 
 		if (vmcb->ctrl.exitcode != VMCB_EXITCODE_INVALID) {
-			if (cpudata->tlb_want_flush) {
-cpudata->tlb_want_flush = false;
-			}
+			cpudata->tlb_want_flush = false;
+			tlb_need_flush = false;
 			vcpu->hcpu_last = hcpu;
 		}
 



CVS commit: src/sys/dev/nvmm

2019-02-10 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Mon Feb 11 07:07:37 UTC 2019

Modified Files:
src/sys/dev/nvmm: nvmm_internal.h

Log Message:
Increase the max guest ram from 4GB to 128GB.


To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/sys/dev/nvmm/nvmm_internal.h

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/nvmm_internal.h
diff -u src/sys/dev/nvmm/nvmm_internal.h:1.3 src/sys/dev/nvmm/nvmm_internal.h:1.4
--- src/sys/dev/nvmm/nvmm_internal.h:1.3	Sat Jan 26 15:25:51 2019
+++ src/sys/dev/nvmm/nvmm_internal.h	Mon Feb 11 07:07:37 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_internal.h,v 1.3 2019/01/26 15:25:51 maxv Exp $	*/
+/*	$NetBSD: nvmm_internal.h,v 1.4 2019/02/11 07:07:37 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
 #define NVMM_MAX_MACHINES	128
 #define NVMM_MAX_VCPUS		256
 #define NVMM_MAX_SEGS		32
-#define NVMM_MAX_RAM		(4UL * (1 << 30))
+#define NVMM_MAX_RAM		(128ULL * (1 << 30))
 
 struct nvmm_cpu {
 	/* Shared. */



CVS commit: src/sys/dev/nvmm/x86

2019-02-04 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Mon Feb  4 12:11:18 UTC 2019

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_svm.c

Log Message:
Improvements:

 - Guest reads/writes to PAT land in gPAT, so no need to emulate them.

 - When emulating EFER, don't advance the RIP if a fault occurs, and don't
   forget to flush the VMCB cache accordingly.


To generate a diff of this commit:
cvs rdiff -u -r1.18 -r1.19 src/sys/dev/nvmm/x86/nvmm_x86_svm.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.18 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.19
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.18	Sat Jan 26 15:12:20 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Mon Feb  4 12:11:18 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.18 2019/01/26 15:12:20 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.19 2019/02/04 12:11:18 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.18 2019/01/26 15:12:20 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.19 2019/02/04 12:11:18 maxv Exp $");
 
 #include 
 #include 
@@ -938,20 +938,15 @@ svm_inkernel_handle_msr(struct nvmm_mach
 struct nvmm_exit *exit)
 {
 	struct svm_cpudata *cpudata = vcpu->cpudata;
+	struct vmcb *vmcb = cpudata->vmcb;
 	uint64_t val;
 	size_t i;
 
 	switch (exit->u.msr.type) {
 	case NVMM_EXIT_MSR_RDMSR:
-		if (exit->u.msr.msr == MSR_CR_PAT) {
-			val = cpudata->vmcb->state.g_pat;
-			cpudata->vmcb->state.rax = (val & 0x);
-			cpudata->gprs[NVMM_X64_GPR_RDX] = (val >> 32);
-			goto handled;
-		}
 		if (exit->u.msr.msr == MSR_NB_CFG) {
 			val = NB_CFG_INITAPICCPUIDLO;
-			cpudata->vmcb->state.rax = (val & 0x);
+			vmcb->state.rax = (val & 0x);
 			cpudata->gprs[NVMM_X64_GPR_RDX] = (val >> 32);
 			goto handled;
 		}
@@ -959,7 +954,7 @@ svm_inkernel_handle_msr(struct nvmm_mach
 			if (msr_ignore_list[i] != exit->u.msr.msr)
 continue;
 			val = 0;
-			cpudata->vmcb->state.rax = (val & 0x);
+			vmcb->state.rax = (val & 0x);
 			cpudata->gprs[NVMM_X64_GPR_RDX] = (val >> 32);
 			goto handled;
 		}
@@ -967,18 +962,14 @@ svm_inkernel_handle_msr(struct nvmm_mach
 	case NVMM_EXIT_MSR_WRMSR:
 		if (exit->u.msr.msr == MSR_EFER) {
 			if (__predict_false(exit->u.msr.val & ~EFER_VALID)) {
-svm_inject_gp(mach, vcpu);
-goto handled;
+goto error;
 			}
-			if ((cpudata->vmcb->state.efer ^ exit->u.msr.val) &
+			if ((vmcb->state.efer ^ exit->u.msr.val) &
 			 EFER_TLB_FLUSH) {
 cpudata->tlb_want_flush = true;
 			}
-			cpudata->vmcb->state.efer = exit->u.msr.val | EFER_SVME;
-			goto handled;
-		}
-		if (exit->u.msr.msr == MSR_CR_PAT) {
-			cpudata->vmcb->state.g_pat = exit->u.msr.val;
+			vmcb->state.efer = exit->u.msr.val | EFER_SVME;
+			vmcb->ctrl.vmcb_clean &= ~VMCB_CTRL_VMCB_CLEAN_CR;
 			goto handled;
 		}
 		for (i = 0; i < __arraycount(msr_ignore_list); i++) {
@@ -994,6 +985,10 @@ svm_inkernel_handle_msr(struct nvmm_mach
 handled:
 	svm_inkernel_advance(cpudata->vmcb);
 	return true;
+
+error:
+	svm_inject_gp(mach, vcpu);
+	return true;
 }
 
 static void
@@ -1557,6 +1552,7 @@ svm_vcpu_init(struct nvmm_machine *mach,
 	 *  - SYSENTER_EIP [read, write]
 	 *  - FSBASE [read, write]
 	 *  - GSBASE [read, write]
+	 *  - PAT [read, write]
 	 *  - TSC [read]
 	 *
 	 * Intercept the rest.
@@ -1573,6 +1569,7 @@ svm_vcpu_init(struct nvmm_machine *mach,
 	svm_vcpu_msr_allow(cpudata->msrbm, MSR_SYSENTER_EIP, true, true);
 	svm_vcpu_msr_allow(cpudata->msrbm, MSR_FSBASE, true, true);
 	svm_vcpu_msr_allow(cpudata->msrbm, MSR_GSBASE, true, true);
+	svm_vcpu_msr_allow(cpudata->msrbm, MSR_CR_PAT, true, true);
 	svm_vcpu_msr_allow(cpudata->msrbm, MSR_TSC, true, false);
 	vmcb->ctrl.msrpm_base_pa = cpudata->msrbm_pa;
 



CVS commit: src/sys/dev/nvmm

2019-01-26 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Sat Jan 26 15:25:51 UTC 2019

Modified Files:
src/sys/dev/nvmm: nvmm.c nvmm_internal.h

Log Message:
Optimize: keep a per-VCPU buffer for the state, and copy in and out
directly on it. The VCPUs are protected by mutexes, so nothing to worry
about.

This saves two kmem_allocs in {get,set}state.


To generate a diff of this commit:
cvs rdiff -u -r1.5 -r1.6 src/sys/dev/nvmm/nvmm.c
cvs rdiff -u -r1.2 -r1.3 src/sys/dev/nvmm/nvmm_internal.h

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/nvmm.c
diff -u src/sys/dev/nvmm/nvmm.c:1.5 src/sys/dev/nvmm/nvmm.c:1.6
--- src/sys/dev/nvmm/nvmm.c:1.5	Sun Jan  6 16:10:51 2019
+++ src/sys/dev/nvmm/nvmm.c	Sat Jan 26 15:25:51 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm.c,v 1.5 2019/01/06 16:10:51 maxv Exp $	*/
+/*	$NetBSD: nvmm.c,v 1.6 2019/01/26 15:25:51 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.5 2019/01/06 16:10:51 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.6 2019/01/26 15:25:51 maxv Exp $");
 
 #include 
 #include 
@@ -142,6 +142,7 @@ nvmm_vcpu_alloc(struct nvmm_machine *mac
 
 		vcpu->present = true;
 		vcpu->cpuid = i;
+		vcpu->state = kmem_zalloc(nvmm_impl->state_size, KM_SLEEP);
 		*ret = vcpu;
 		return 0;
 	}
@@ -154,6 +155,7 @@ nvmm_vcpu_free(struct nvmm_machine *mach
 {
 	KASSERT(mutex_owned(>lock));
 	vcpu->present = false;
+	kmem_free(vcpu->state, nvmm_impl->state_size);
 	vcpu->hcpu_last = -1;
 }
 
@@ -404,33 +406,27 @@ nvmm_vcpu_setstate(struct nvmm_ioc_vcpu_
 {
 	struct nvmm_machine *mach;
 	struct nvmm_cpu *vcpu;
-	void *data;
 	int error;
 
-	data = kmem_alloc(nvmm_impl->state_size, KM_SLEEP);
-
 	error = nvmm_machine_get(args->machid, , false);
-	if (error) {
-		kmem_free(data, nvmm_impl->state_size);
+	if (error)
 		return error;
-	}
 
 	error = nvmm_vcpu_get(mach, args->cpuid, );
 	if (error)
 		goto out;
 
-	error = copyin(args->state, data, nvmm_impl->state_size);
+	error = copyin(args->state, vcpu->state, nvmm_impl->state_size);
 	if (error) {
 		nvmm_vcpu_put(vcpu);
 		goto out;
 	}
 
-	(*nvmm_impl->vcpu_setstate)(vcpu, data, args->flags);
+	(*nvmm_impl->vcpu_setstate)(vcpu, vcpu->state, args->flags);
 	nvmm_vcpu_put(vcpu);
 
 out:
 	nvmm_machine_put(mach);
-	kmem_free(data, nvmm_impl->state_size);
 	return error;
 }
 
@@ -439,28 +435,22 @@ nvmm_vcpu_getstate(struct nvmm_ioc_vcpu_
 {
 	struct nvmm_machine *mach;
 	struct nvmm_cpu *vcpu;
-	void *data;
 	int error;
 
-	data = kmem_alloc(nvmm_impl->state_size, KM_SLEEP);
-
 	error = nvmm_machine_get(args->machid, , false);
-	if (error) {
-		kmem_free(data, nvmm_impl->state_size);
+	if (error)
 		return error;
-	}
 
 	error = nvmm_vcpu_get(mach, args->cpuid, );
 	if (error)
 		goto out;
 
-	(*nvmm_impl->vcpu_getstate)(vcpu, data, args->flags);
+	(*nvmm_impl->vcpu_getstate)(vcpu, vcpu->state, args->flags);
 	nvmm_vcpu_put(vcpu);
-	error = copyout(data, args->state, nvmm_impl->state_size);
+	error = copyout(vcpu->state, args->state, nvmm_impl->state_size);
 
 out:
 	nvmm_machine_put(mach);
-	kmem_free(data, nvmm_impl->state_size);
 	return error;
 }
 

Index: src/sys/dev/nvmm/nvmm_internal.h
diff -u src/sys/dev/nvmm/nvmm_internal.h:1.2 src/sys/dev/nvmm/nvmm_internal.h:1.3
--- src/sys/dev/nvmm/nvmm_internal.h:1.2	Sat Dec 15 13:39:43 2018
+++ src/sys/dev/nvmm/nvmm_internal.h	Sat Jan 26 15:25:51 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_internal.h,v 1.2 2018/12/15 13:39:43 maxv Exp $	*/
+/*	$NetBSD: nvmm_internal.h,v 1.3 2019/01/26 15:25:51 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -43,6 +43,9 @@ struct nvmm_cpu {
 	nvmm_cpuid_t cpuid;
 	kmutex_t lock;
 
+	/* State buffer. */
+	void *state;
+
 	/* Last host CPU on which the VCPU ran. */
 	int hcpu_last;
 



CVS commit: src/sys/dev/nvmm

2019-01-26 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Sat Jan 26 15:12:20 UTC 2019

Modified Files:
src/sys/dev/nvmm: nvmm.h
src/sys/dev/nvmm/x86: nvmm_x86_svm.c

Log Message:
Remove nvmm_exit_memory.npc, useless.


To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/sys/dev/nvmm/nvmm.h
cvs rdiff -u -r1.17 -r1.18 src/sys/dev/nvmm/x86/nvmm_x86_svm.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/nvmm.h
diff -u src/sys/dev/nvmm/nvmm.h:1.3 src/sys/dev/nvmm/nvmm.h:1.4
--- src/sys/dev/nvmm/nvmm.h:1.3	Thu Jan 24 13:05:59 2019
+++ src/sys/dev/nvmm/nvmm.h	Sat Jan 26 15:12:20 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm.h,v 1.3 2019/01/24 13:05:59 maxv Exp $	*/
+/*	$NetBSD: nvmm.h,v 1.4 2019/01/26 15:12:20 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -75,7 +75,6 @@ struct nvmm_exit_memory {
 	gpaddr_t gpa;
 	uint8_t inst_len;
 	uint8_t inst_bytes[15];
-	uint64_t npc;
 };
 
 enum nvmm_exit_io_type {

Index: src/sys/dev/nvmm/x86/nvmm_x86_svm.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.17 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.18
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.17	Thu Jan 24 13:05:59 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Sat Jan 26 15:12:20 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.17 2019/01/24 13:05:59 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.18 2019/01/26 15:12:20 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.17 2019/01/24 13:05:59 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.18 2019/01/26 15:12:20 maxv Exp $");
 
 #include 
 #include 
@@ -1051,7 +1051,6 @@ svm_exit_npf(struct nvmm_machine *mach, 
 		exit->u.mem.inst_len = cpudata->vmcb->ctrl.inst_len;
 		memcpy(exit->u.mem.inst_bytes, cpudata->vmcb->ctrl.inst_bytes,
 		sizeof(exit->u.mem.inst_bytes));
-		exit->u.mem.npc = cpudata->vmcb->ctrl.nrip;
 	} else {
 		exit->reason = NVMM_EXIT_NONE;
 	}



CVS commit: src/sys/dev/nvmm

2019-01-24 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Thu Jan 24 13:05:59 UTC 2019

Modified Files:
src/sys/dev/nvmm: nvmm.h
src/sys/dev/nvmm/x86: nvmm_x86_svm.c

Log Message:
Optimize: change the behavior of the HLT vmexit, make it a "change in vcpu
state" which occurs after the instruction executed, rather than an
instruction intercept which occurs before. Disable the shadow and the intr
window in kernel mode, and advance the RIP, so that the virtualizer doesn't
have to do it itself. This saves two syscalls and one VMCB cache flush.

Provide npc for other instruction intercepts, in case someone is
interested.


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/sys/dev/nvmm/nvmm.h
cvs rdiff -u -r1.16 -r1.17 src/sys/dev/nvmm/x86/nvmm_x86_svm.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/nvmm.h
diff -u src/sys/dev/nvmm/nvmm.h:1.2 src/sys/dev/nvmm/nvmm.h:1.3
--- src/sys/dev/nvmm/nvmm.h:1.2	Sun Jan  6 16:10:51 2019
+++ src/sys/dev/nvmm/nvmm.h	Thu Jan 24 13:05:59 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm.h,v 1.2 2019/01/06 16:10:51 maxv Exp $	*/
+/*	$NetBSD: nvmm.h,v 1.3 2019/01/24 13:05:59 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -53,13 +53,13 @@ enum nvmm_exit_reason {
 	NVMM_EXIT_MSR		= 0x0003,
 	NVMM_EXIT_INT_READY	= 0x0004,
 	NVMM_EXIT_NMI_READY	= 0x0005,
-	NVMM_EXIT_SHUTDOWN	= 0x0006,
+	NVMM_EXIT_HALTED	= 0x0006,
+	NVMM_EXIT_SHUTDOWN	= 0x0007,
 
 	/* Instructions (x86). */
-	NVMM_EXIT_HLT		= 0x1000,
-	NVMM_EXIT_MONITOR	= 0x1001,
-	NVMM_EXIT_MWAIT		= 0x1002,
-	NVMM_EXIT_MWAIT_COND	= 0x1003,
+	NVMM_EXIT_MONITOR	= 0x1000,
+	NVMM_EXIT_MWAIT		= 0x1001,
+	NVMM_EXIT_MWAIT_COND	= 0x1002,
 
 	NVMM_EXIT_INVALID	= 0x
 };
@@ -106,7 +106,7 @@ struct nvmm_exit_msr {
 	uint64_t npc;
 };
 
-struct nvmm_exit_hlt {
+struct nvmm_exit_insn {
 	uint64_t npc;
 };
 
@@ -116,7 +116,7 @@ struct nvmm_exit {
 		struct nvmm_exit_memory mem;
 		struct nvmm_exit_io io;
 		struct nvmm_exit_msr msr;
-		struct nvmm_exit_hlt hlt;
+		struct nvmm_exit_insn insn;
 	} u;
 	uint64_t exitstate[8];
 };

Index: src/sys/dev/nvmm/x86/nvmm_x86_svm.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.16 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.17
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.16	Sun Jan 20 16:55:21 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Thu Jan 24 13:05:59 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.16 2019/01/20 16:55:21 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.17 2019/01/24 13:05:59 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.16 2019/01/20 16:55:21 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.17 2019/01/24 13:05:59 maxv Exp $");
 
 #include 
 #include 
@@ -726,31 +726,29 @@ svm_inject_ud(struct nvmm_machine *mach,
 }
 
 static void
-svm_inject_db(struct nvmm_machine *mach, struct nvmm_cpu *vcpu)
+svm_inject_gp(struct nvmm_machine *mach, struct nvmm_cpu *vcpu)
 {
 	struct nvmm_event event;
 	int ret __diagused;
 
 	event.type = NVMM_EVENT_EXCEPTION;
-	event.vector = 1;
+	event.vector = 13;
 	event.u.error = 0;
 
 	ret = svm_vcpu_inject(mach, vcpu, );
 	KASSERT(ret == 0);
 }
 
-static void
-svm_inject_gp(struct nvmm_machine *mach, struct nvmm_cpu *vcpu)
+static inline void
+svm_inkernel_advance(struct vmcb *vmcb)
 {
-	struct nvmm_event event;
-	int ret __diagused;
-
-	event.type = NVMM_EVENT_EXCEPTION;
-	event.vector = 13;
-	event.u.error = 0;
-
-	ret = svm_vcpu_inject(mach, vcpu, );
-	KASSERT(ret == 0);
+	/*
+	 * Maybe we should also apply single-stepping and debug exceptions.
+	 * Matters for guest-ring3, because it can execute 'cpuid' under a
+	 * debugger.
+	 */
+	vmcb->state.rip = vmcb->ctrl.nrip;
+	vmcb->ctrl.intr &= ~VMCB_CTRL_INTR_SHADOW;
 }
 
 static void
@@ -842,12 +840,7 @@ svm_exit_cpuid(struct nvmm_machine *mach
 	/* Overwrite non-tunable leaves. */
 	svm_inkernel_handle_cpuid(vcpu, eax, ecx);
 
-	/* For now we omit DBREGS. */
-	if (__predict_false(cpudata->vmcb->state.rflags & PSL_T)) {
-		svm_inject_db(mach, vcpu);
-	}
-
-	cpudata->vmcb->state.rip = cpudata->vmcb->ctrl.nrip;
+	svm_inkernel_advance(cpudata->vmcb);
 	exit->reason = NVMM_EXIT_NONE;
 }
 
@@ -856,9 +849,14 @@ svm_exit_hlt(struct nvmm_machine *mach, 
 struct nvmm_exit *exit)
 {
 	struct svm_cpudata *cpudata = vcpu->cpudata;
+	struct vmcb *vmcb = cpudata->vmcb;
 
-	exit->reason = NVMM_EXIT_HLT;
-	exit->u.hlt.npc = cpudata->vmcb->ctrl.nrip;
+	if (cpudata->int_window_exit && (vmcb->state.rflags & PSL_I)) {
+		svm_event_waitexit_disable(vcpu, false);
+	}
+
+	svm_inkernel_advance(cpudata->vmcb);
+	exit->reason = NVMM_EXIT_HALTED;
 }
 
 #define SVM_EXIT_IO_PORT	__BITS(31,16)
@@ -994,7 

CVS commit: src/sys/dev/nvmm/x86

2019-01-13 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Sun Jan 13 10:07:50 UTC 2019

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_svm.c

Log Message:
Reset DR7 before loading DR0-3, to prevent a fault if the host process
has dbregs enabled.


To generate a diff of this commit:
cvs rdiff -u -r1.14 -r1.15 src/sys/dev/nvmm/x86/nvmm_x86_svm.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.14 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.15
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.14	Thu Jan 10 06:58:36 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Sun Jan 13 10:07:50 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.14 2019/01/10 06:58:36 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.15 2019/01/13 10:07:50 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.14 2019/01/10 06:58:36 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.15 2019/01/13 10:07:50 maxv Exp $");
 
 #include 
 #include 
@@ -1128,6 +1128,8 @@ svm_vcpu_guest_dbregs_enter(struct nvmm_
 
 	x86_dbregs_save(curlwp);
 
+	ldr7(0);
+
 	ldr0(cpudata->drs[NVMM_X64_DR_DR0]);
 	ldr1(cpudata->drs[NVMM_X64_DR_DR1]);
 	ldr2(cpudata->drs[NVMM_X64_DR_DR2]);



CVS commit: src/sys/dev/nvmm/x86

2019-01-09 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Thu Jan 10 06:58:37 UTC 2019

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_svm.c nvmm_x86_svmfunc.S

Log Message:
Optimize:

 * Don't save/restore the host CR2, we don't care because we're not in a
   #PF context (and preemption switches already handle CR2 safely).

 * Don't save/restore the host FS and GS, just reset them to zero after
   VMRUN. Note: DS and ES must be reset _before_ VMRUN, but that doesn't
   apply to FS and GS.

 * Handle FSBASE and KGSBASE outside of the VCPU loop, to avoid the cost
   of saving/restoring them when there's no reason to leave the loop.


To generate a diff of this commit:
cvs rdiff -u -r1.13 -r1.14 src/sys/dev/nvmm/x86/nvmm_x86_svm.c
cvs rdiff -u -r1.1 -r1.2 src/sys/dev/nvmm/x86/nvmm_x86_svmfunc.S

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.13 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.14
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.13	Tue Jan  8 14:43:18 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Thu Jan 10 06:58:36 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.13 2019/01/08 14:43:18 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.14 2019/01/10 06:58:36 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.13 2019/01/08 14:43:18 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.14 2019/01/10 06:58:36 maxv Exp $");
 
 #include 
 #include 
@@ -521,7 +521,8 @@ struct svm_cpudata {
 	uint64_t lstar;
 	uint64_t cstar;
 	uint64_t sfmask;
-	uint64_t cr2;
+	uint64_t fsbase;
+	uint64_t kernelgsbase;
 	bool ts_set;
 	struct xsave_header hfpu __aligned(16);
 
@@ -1151,14 +1152,12 @@ svm_vcpu_guest_misc_enter(struct nvmm_cp
 {
 	struct svm_cpudata *cpudata = vcpu->cpudata;
 
-	/* Save the fixed Host MSRs. */
 	cpudata->star = rdmsr(MSR_STAR);
 	cpudata->lstar = rdmsr(MSR_LSTAR);
 	cpudata->cstar = rdmsr(MSR_CSTAR);
 	cpudata->sfmask = rdmsr(MSR_SFMASK);
-
-	/* Save the Host CR2. */
-	cpudata->cr2 = rcr2();
+	cpudata->fsbase = rdmsr(MSR_FSBASE);
+	cpudata->kernelgsbase = rdmsr(MSR_KERNELGSBASE);
 }
 
 static void
@@ -1166,14 +1165,12 @@ svm_vcpu_guest_misc_leave(struct nvmm_cp
 {
 	struct svm_cpudata *cpudata = vcpu->cpudata;
 
-	/* Restore the fixed Host MSRs. */
 	wrmsr(MSR_STAR, cpudata->star);
 	wrmsr(MSR_LSTAR, cpudata->lstar);
 	wrmsr(MSR_CSTAR, cpudata->cstar);
 	wrmsr(MSR_SFMASK, cpudata->sfmask);
-
-	/* Restore the Host CR2. */
-	lcr2(cpudata->cr2);
+	wrmsr(MSR_FSBASE, cpudata->fsbase);
+	wrmsr(MSR_KERNELGSBASE, cpudata->kernelgsbase);
 }
 
 static int

Index: src/sys/dev/nvmm/x86/nvmm_x86_svmfunc.S
diff -u src/sys/dev/nvmm/x86/nvmm_x86_svmfunc.S:1.1 src/sys/dev/nvmm/x86/nvmm_x86_svmfunc.S:1.2
--- src/sys/dev/nvmm/x86/nvmm_x86_svmfunc.S:1.1	Wed Nov  7 07:43:08 2018
+++ src/sys/dev/nvmm/x86/nvmm_x86_svmfunc.S	Thu Jan 10 06:58:36 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svmfunc.S,v 1.1 2018/11/07 07:43:08 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svmfunc.S,v 1.2 2019/01/10 06:58:36 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -73,14 +73,6 @@
 	movq	$msr,%rcx	;\
 	wrmsr
 
-#define HOST_SAVE_SEGREG(sreg)	\
-	movw	sreg,%ax	;\
-	pushw	%ax
-
-#define HOST_RESTORE_SEGREG(sreg)\
-	popw	%ax		;\
-	movw	%ax,sreg
-
 #define HOST_SAVE_TR		\
 	strw	%ax		;\
 	pushw	%ax
@@ -150,22 +142,13 @@ ENTRY(svm_vmrun)
 	/* Save the Host TR. */
 	HOST_SAVE_TR
 
-	/* Save the variable Host MSRs. */
-	HOST_SAVE_MSR(MSR_KERNELGSBASE)
+	/* Save the Host GSBASE. */
 	HOST_SAVE_MSR(MSR_GSBASE)
-	HOST_SAVE_MSR(MSR_FSBASE)
 
-	/* Reset the Host Segregs. */
+	/* Reset DS and ES. */
 	movq	$GSEL(GUDATA_SEL, SEL_UPL),%rax
 	movw	%ax,%ds
 	movw	%ax,%es
-	xorq	%rax,%rax
-	movw	%ax,%fs
-	movw	%ax,%gs
-
-	/* Save some Host Segregs. */
-	HOST_SAVE_SEGREG(%fs)
-	HOST_SAVE_SEGREG(%gs)
 
 	/* Save the Host LDT. */
 	HOST_SAVE_LDT
@@ -195,14 +178,13 @@ ENTRY(svm_vmrun)
 	/* Restore the Host LDT. */
 	HOST_RESTORE_LDT
 
-	/* Restore the Host Segregs. */
-	HOST_RESTORE_SEGREG(%gs)
-	HOST_RESTORE_SEGREG(%fs)
+	/* Reset FS and GS. */
+	xorq	%rax,%rax
+	movw	%ax,%fs
+	movw	%ax,%gs
 
-	/* Restore the variable Host MSRs. */
-	HOST_RESTORE_MSR(MSR_FSBASE)
+	/* Restore the Host GSBASE. */
 	HOST_RESTORE_MSR(MSR_GSBASE)
-	HOST_RESTORE_MSR(MSR_KERNELGSBASE)
 
 	/* Restore the Host TR. */
 	HOST_RESTORE_TR



CVS commit: src/sys/dev/nvmm/x86

2019-01-08 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Tue Jan  8 14:43:18 UTC 2019

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_svm.c

Log Message:
Optimize: don't keep a full copy of the guest state, rather take only what
is needed. This avoids expensive memcpy's.

Also flush the V_TPR as part of the CR-state, because there is CR8 in it.


To generate a diff of this commit:
cvs rdiff -u -r1.12 -r1.13 src/sys/dev/nvmm/x86/nvmm_x86_svm.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.12 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.13
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.12	Mon Jan  7 14:08:02 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Tue Jan  8 14:43:18 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.12 2019/01/07 14:08:02 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.13 2019/01/08 14:43:18 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.12 2019/01/07 14:08:02 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.13 2019/01/08 14:43:18 maxv Exp $");
 
 #include 
 #include 
@@ -499,9 +499,6 @@ static const size_t svm_conf_sizes[NVMM_
 };
 
 struct svm_cpudata {
-	/* x64-specific */
-	struct nvmm_x64_state state;
-
 	/* General */
 	bool shared_asid;
 	bool tlb_want_flush;
@@ -519,7 +516,7 @@ struct svm_cpudata {
 	paddr_t msrbm_pa;
 
 	/* Host state */
-	uint64_t xcr0;
+	uint64_t hxcr0;
 	uint64_t star;
 	uint64_t lstar;
 	uint64_t cstar;
@@ -533,6 +530,9 @@ struct svm_cpudata {
 	bool nmi_window_exit;
 
 	/* Guest state */
+	uint64_t gxcr0;
+	uint64_t gprs[NVMM_X64_NGPR];
+	uint64_t drs[NVMM_X64_NDR];
 	uint64_t tsc_offset;
 	struct xsave_header gfpu __aligned(16);
 };
@@ -564,7 +564,8 @@ svm_vmcb_cache_update(struct vmcb *vmcb,
 	}
 	if (flags & NVMM_X64_STATE_CRS) {
 		vmcb->ctrl.vmcb_clean &=
-		~(VMCB_CTRL_VMCB_CLEAN_CR | VMCB_CTRL_VMCB_CLEAN_CR2);
+		~(VMCB_CTRL_VMCB_CLEAN_CR | VMCB_CTRL_VMCB_CLEAN_CR2 |
+		  VMCB_CTRL_VMCB_CLEAN_TPR);
 	}
 	if (flags & NVMM_X64_STATE_DRS) {
 		vmcb->ctrl.vmcb_clean &= ~VMCB_CTRL_VMCB_CLEAN_DR;
@@ -755,12 +756,11 @@ static void
 svm_inkernel_handle_cpuid(struct nvmm_cpu *vcpu, uint64_t eax, uint64_t ecx)
 {
 	struct svm_cpudata *cpudata = vcpu->cpudata;
-	struct nvmm_x64_state *state = >state;
 
 	switch (eax) {
 	case 0x0001: /* APIC number in RBX. The rest is tunable. */
-		state->gprs[NVMM_X64_GPR_RBX] &= ~CPUID_LOCAL_APIC_ID;
-		state->gprs[NVMM_X64_GPR_RBX] |= __SHIFTIN(vcpu->cpuid,
+		cpudata->gprs[NVMM_X64_GPR_RBX] &= ~CPUID_LOCAL_APIC_ID;
+		cpudata->gprs[NVMM_X64_GPR_RBX] |= __SHIFTIN(vcpu->cpuid,
 		CPUID_LOCAL_APIC_ID);
 		break;
 	case 0x000D: /* FPU description. Not tunable. */
@@ -768,22 +768,22 @@ svm_inkernel_handle_cpuid(struct nvmm_cp
 			break;
 		}
 		cpudata->vmcb->state.rax = svm_xcr0_mask & 0x;
-		if (state->crs[NVMM_X64_CR_XCR0] & XCR0_SSE) {
-			state->gprs[NVMM_X64_GPR_RBX] = sizeof(struct fxsave);
+		if (cpudata->gxcr0 & XCR0_SSE) {
+			cpudata->gprs[NVMM_X64_GPR_RBX] = sizeof(struct fxsave);
 		} else {
-			state->gprs[NVMM_X64_GPR_RBX] = sizeof(struct save87);
+			cpudata->gprs[NVMM_X64_GPR_RBX] = sizeof(struct save87);
 		}
-		state->gprs[NVMM_X64_GPR_RBX] += 64; /* XSAVE header */
-		state->gprs[NVMM_X64_GPR_RCX] = sizeof(struct fxsave);
-		state->gprs[NVMM_X64_GPR_RDX] = svm_xcr0_mask >> 32;
+		cpudata->gprs[NVMM_X64_GPR_RBX] += 64; /* XSAVE header */
+		cpudata->gprs[NVMM_X64_GPR_RCX] = sizeof(struct fxsave);
+		cpudata->gprs[NVMM_X64_GPR_RDX] = svm_xcr0_mask >> 32;
 		break;
 	case 0x4000:
-		memcpy(>gprs[NVMM_X64_GPR_RBX], "___ ", 4);
-		memcpy(>gprs[NVMM_X64_GPR_RCX], "NVMM", 4);
-		memcpy(>gprs[NVMM_X64_GPR_RDX], " ___", 4);
+		memcpy(>gprs[NVMM_X64_GPR_RBX], "___ ", 4);
+		memcpy(>gprs[NVMM_X64_GPR_RCX], "NVMM", 4);
+		memcpy(>gprs[NVMM_X64_GPR_RDX], " ___", 4);
 		break;
 	case 0x8001: /* No SVM in ECX. The rest is tunable. */
-		state->gprs[NVMM_X64_GPR_RCX] &= ~CPUID_SVM;
+		cpudata->gprs[NVMM_X64_GPR_RCX] &= ~CPUID_SVM;
 		break;
 	default:
 		break;
@@ -796,20 +796,19 @@ svm_exit_cpuid(struct nvmm_machine *mach
 {
 	struct svm_machdata *machdata = mach->machdata;
 	struct svm_cpudata *cpudata = vcpu->cpudata;
-	struct nvmm_x64_state *state = >state;
 	struct nvmm_x86_conf_cpuid *cpuid;
 	uint64_t eax, ecx;
 	u_int descs[4];
 	size_t i;
 
 	eax = cpudata->vmcb->state.rax;
-	ecx = state->gprs[NVMM_X64_GPR_RCX];
+	ecx = cpudata->gprs[NVMM_X64_GPR_RCX];
 	x86_cpuid2(eax, ecx, descs);
 
 	cpudata->vmcb->state.rax = descs[0];
-	state->gprs[NVMM_X64_GPR_RBX] = descs[1];
-	state->gprs[NVMM_X64_GPR_RCX] = descs[2];
-	state->gprs[NVMM_X64_GPR_RDX] = descs[3];
+	cpudata->gprs[NVMM_X64_GPR_RBX] = descs[1];
+	cpudata->gprs[NVMM_X64_GPR_RCX] = descs[2];
+	cpudata->gprs[NVMM_X64_GPR_RDX] = descs[3];
 

CVS commit: src/sys/dev/nvmm

2019-01-07 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Tue Jan  8 07:29:46 UTC 2019

Modified Files:
src/sys/dev/nvmm: nvmm_ioctl.h

Log Message:
_IOWR -> _IOW


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/sys/dev/nvmm/nvmm_ioctl.h

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/nvmm_ioctl.h
diff -u src/sys/dev/nvmm/nvmm_ioctl.h:1.2 src/sys/dev/nvmm/nvmm_ioctl.h:1.3
--- src/sys/dev/nvmm/nvmm_ioctl.h:1.2	Sat Dec 15 13:39:43 2018
+++ src/sys/dev/nvmm/nvmm_ioctl.h	Tue Jan  8 07:29:46 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_ioctl.h,v 1.2 2018/12/15 13:39:43 maxv Exp $	*/
+/*	$NetBSD: nvmm_ioctl.h,v 1.3 2019/01/08 07:29:46 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -126,7 +126,7 @@ struct nvmm_ioc_gpa_unmap {
 #define NVMM_IOC_VCPU_DESTROY		_IOW ('N',  5, struct nvmm_ioc_vcpu_destroy)
 #define NVMM_IOC_VCPU_SETSTATE		_IOW ('N',  6, struct nvmm_ioc_vcpu_setstate)
 #define NVMM_IOC_VCPU_GETSTATE		_IOW ('N',  7, struct nvmm_ioc_vcpu_getstate)
-#define NVMM_IOC_VCPU_INJECT		_IOWR('N',  8, struct nvmm_ioc_vcpu_inject)
+#define NVMM_IOC_VCPU_INJECT		_IOW ('N',  8, struct nvmm_ioc_vcpu_inject)
 #define NVMM_IOC_VCPU_RUN		_IOWR('N',  9, struct nvmm_ioc_vcpu_run)
 #define NVMM_IOC_GPA_MAP		_IOW ('N', 10, struct nvmm_ioc_gpa_map)
 #define NVMM_IOC_GPA_UNMAP		_IOW ('N', 11, struct nvmm_ioc_gpa_unmap)



CVS commit: src/sys/dev/nvmm/x86

2019-01-07 Thread Maxime Villard
Module Name:src
Committed By:   maxv
Date:   Mon Jan  7 14:08:02 UTC 2019

Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_svm.c

Log Message:
Optimize: cache the guest state entirely in the VMCB-cache, flush it on a
state-by-state basis when needed.


To generate a diff of this commit:
cvs rdiff -u -r1.11 -r1.12 src/sys/dev/nvmm/x86/nvmm_x86_svm.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.11 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.12
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.11	Sun Jan  6 18:32:54 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Mon Jan  7 14:08:02 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.11 2019/01/06 18:32:54 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.12 2019/01/07 14:08:02 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.11 2019/01/06 18:32:54 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.12 2019/01/07 14:08:02 maxv Exp $");
 
 #include 
 #include 
@@ -314,7 +314,6 @@ struct vmcb_ctrl {
 
 	uint64_t intr;
 #define VMCB_CTRL_INTR_SHADOW		__BIT(0)
-#define VMCB_CTRL_GUEST_INTR_MASK	__BIT(1)
 
 	uint64_t exitcode;
 	uint64_t exitinfo1;
@@ -538,6 +537,61 @@ struct svm_cpudata {
 	struct xsave_header gfpu __aligned(16);
 };
 
+static void
+svm_vmcb_cache_default(struct vmcb *vmcb)
+{
+	vmcb->ctrl.vmcb_clean =
+	VMCB_CTRL_VMCB_CLEAN_I |
+	VMCB_CTRL_VMCB_CLEAN_IOPM |
+	VMCB_CTRL_VMCB_CLEAN_ASID |
+	VMCB_CTRL_VMCB_CLEAN_TPR |
+	VMCB_CTRL_VMCB_CLEAN_NP |
+	VMCB_CTRL_VMCB_CLEAN_CR |
+	VMCB_CTRL_VMCB_CLEAN_DR |
+	VMCB_CTRL_VMCB_CLEAN_DT |
+	VMCB_CTRL_VMCB_CLEAN_SEG |
+	VMCB_CTRL_VMCB_CLEAN_CR2 |
+	VMCB_CTRL_VMCB_CLEAN_LBR |
+	VMCB_CTRL_VMCB_CLEAN_AVIC;
+}
+
+static void
+svm_vmcb_cache_update(struct vmcb *vmcb, uint64_t flags)
+{
+	if (flags & NVMM_X64_STATE_SEGS) {
+		vmcb->ctrl.vmcb_clean &=
+		~(VMCB_CTRL_VMCB_CLEAN_SEG | VMCB_CTRL_VMCB_CLEAN_DT);
+	}
+	if (flags & NVMM_X64_STATE_CRS) {
+		vmcb->ctrl.vmcb_clean &=
+		~(VMCB_CTRL_VMCB_CLEAN_CR | VMCB_CTRL_VMCB_CLEAN_CR2);
+	}
+	if (flags & NVMM_X64_STATE_DRS) {
+		vmcb->ctrl.vmcb_clean &= ~VMCB_CTRL_VMCB_CLEAN_DR;
+	}
+	if (flags & NVMM_X64_STATE_MSRS) {
+		/* CR for EFER, NP for PAT. */
+		vmcb->ctrl.vmcb_clean &=
+		~(VMCB_CTRL_VMCB_CLEAN_CR | VMCB_CTRL_VMCB_CLEAN_NP);
+	}
+	if (flags & NVMM_X64_STATE_MISC) {
+		/* SEG for CPL. */
+		vmcb->ctrl.vmcb_clean &= ~VMCB_CTRL_VMCB_CLEAN_SEG;
+	}
+}
+
+static inline void
+svm_vmcb_cache_flush(struct vmcb *vmcb, uint64_t flags)
+{
+	vmcb->ctrl.vmcb_clean &= ~flags;
+}
+
+static inline void
+svm_vmcb_cache_flush_all(struct vmcb *vmcb)
+{
+	vmcb->ctrl.vmcb_clean = 0;
+}
+
 #define SVM_EVENT_TYPE_HW_INT	0
 #define SVM_EVENT_TYPE_NMI	2
 #define SVM_EVENT_TYPE_EXC	3
@@ -555,8 +609,11 @@ svm_event_waitexit_enable(struct nvmm_cp
 	} else {
 		vmcb->ctrl.intercept_misc1 |= VMCB_CTRL_INTERCEPT_VINTR;
 		vmcb->ctrl.v |= (VMCB_CTRL_V_IRQ | VMCB_CTRL_V_IGN_TPR);
+		svm_vmcb_cache_flush(vmcb, VMCB_CTRL_VMCB_CLEAN_TPR);
 		cpudata->int_window_exit = true;
 	}
+
+	svm_vmcb_cache_flush(vmcb, VMCB_CTRL_VMCB_CLEAN_I);
 }
 
 static void
@@ -571,8 +628,11 @@ svm_event_waitexit_disable(struct nvmm_c
 	} else {
 		vmcb->ctrl.intercept_misc1 &= ~VMCB_CTRL_INTERCEPT_VINTR;
 		vmcb->ctrl.v &= ~(VMCB_CTRL_V_IRQ | VMCB_CTRL_V_IGN_TPR);
+		svm_vmcb_cache_flush(vmcb, VMCB_CTRL_VMCB_CLEAN_TPR);
 		cpudata->int_window_exit = false;
 	}
+
+	svm_vmcb_cache_flush(vmcb, VMCB_CTRL_VMCB_CLEAN_I);
 }
 
 static inline int
@@ -1031,23 +1091,6 @@ error:
 }
 
 static void
-svm_vmcb_cache_default(struct vmcb *vmcb)
-{
-	vmcb->ctrl.vmcb_clean =
-	VMCB_CTRL_VMCB_CLEAN_I |
-	VMCB_CTRL_VMCB_CLEAN_IOPM |
-	VMCB_CTRL_VMCB_CLEAN_ASID |
-	VMCB_CTRL_VMCB_CLEAN_LBR |
-	VMCB_CTRL_VMCB_CLEAN_AVIC;
-}
-
-static void
-svm_vmcb_cache_flush(struct vmcb *vmcb)
-{
-	vmcb->ctrl.vmcb_clean = 0;
-}
-
-static void
 svm_vcpu_guest_fpu_enter(struct nvmm_cpu *vcpu)
 {
 	struct svm_cpudata *cpudata = vcpu->cpudata;
@@ -1164,7 +1207,7 @@ svm_vcpu_run(struct nvmm_machine *mach, 
 	if (vcpu->hcpu_last != hcpu) {
 		vmcb->ctrl.tsc_offset = cpudata->tsc_offset +
 		curcpu()->ci_data.cpu_cc_skew;
-		svm_vmcb_cache_flush(vmcb);
+		svm_vmcb_cache_flush_all(vmcb);
 	}
 
 	svm_vcpu_guest_dbregs_enter(vcpu);
@@ -1821,6 +1864,8 @@ svm_vcpu_setstate(struct nvmm_cpu *vcpu,
 		fpustate->fx_mxcsr_mask &= x86_fpu_mxcsr_mask;
 		fpustate->fx_mxcsr &= fpustate->fx_mxcsr_mask;
 	}
+
+	svm_vmcb_cache_update(vmcb, flags);
 }
 
 static void



  1   2   >