CVS commit: src/sys/dev/nvmm
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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