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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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
CVS commit: src/sys/dev/nvmm/x86
Module Name:src Committed By: maxv Date: Sun Jan 6 18:32:54 UTC 2019 Modified Files: src/sys/dev/nvmm/x86: nvmm_x86_svm.c Log Message: Add more VMCB fields. Also remove debugging code I mistakenly committed in the previous revision. No functional change. To generate a diff of this commit: cvs rdiff -u -r1.10 -r1.11 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.10 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.11 --- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.10 Sun Jan 6 16:10:51 2019 +++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c Sun Jan 6 18:32:54 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: nvmm_x86_svm.c,v 1.10 2019/01/06 16:10:51 maxv Exp $ */ +/* $NetBSD: nvmm_x86_svm.c,v 1.11 2019/01/06 18:32:54 maxv Exp $ */ /* * Copyright (c) 2018 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.10 2019/01/06 16:10:51 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.11 2019/01/06 18:32:54 maxv Exp $"); #include #include @@ -368,7 +368,18 @@ struct vmcb_ctrl { uint64_t nrip; uint8_t inst_len; uint8_t inst_bytes[15]; - uint8_t pad[800]; + uint64_t avic_abpp; + uint64_t rsvd3; + uint64_t avic_ltp; + + uint64_t avic_phys; +#define VMCB_CTRL_AVIC_PHYS_TABLE_PTR __BITS(51,12) +#define VMCB_CTRL_AVIC_PHYS_MAX_INDEX __BITS(7,0) + + uint64_t rsvd4; + uint64_t vmcb_ptr; + + uint8_t pad[752]; } __packed; CTASSERT(sizeof(struct vmcb_ctrl) == 1024); @@ -1238,10 +1249,6 @@ svm_vcpu_run(struct nvmm_machine *mach, break; } - if (vmcb->ctrl.exitintinfo & VMCB_CTRL_EXITINTINFO_V) { - printf("WAS PROCESSING!\n"); - } - /* If no reason to return to userland, keep rolling. */ if (curcpu()->ci_schedstate.spc_flags & SPCF_SHOULDYIELD) { break;
CVS commit: src/sys/dev/nvmm/x86
Module Name:src Committed By: maxv Date: Thu Jan 3 08:02:50 UTC 2019 Modified Files: src/sys/dev/nvmm/x86: nvmm_x86_svm.c Log Message: Fix another gross copy-pasto. To generate a diff of this commit: cvs rdiff -u -r1.8 -r1.9 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.8 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.9 --- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.8 Wed Jan 2 12:18:08 2019 +++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c Thu Jan 3 08:02:49 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: nvmm_x86_svm.c,v 1.8 2019/01/02 12:18:08 maxv Exp $ */ +/* $NetBSD: nvmm_x86_svm.c,v 1.9 2019/01/03 08:02:49 maxv Exp $ */ /* * Copyright (c) 2018 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.8 2019/01/02 12:18:08 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.9 2019/01/03 08:02:49 maxv Exp $"); #include #include @@ -1820,7 +1820,7 @@ svm_vcpu_getstate(struct nvmm_cpu *vcpu, memcpy(>fpu, cpudata->gfpu.xsh_fxsave, sizeof(cstate->fpu)); - memcpy(>fpu, >fpu, sizeof(cstate->fpu)); + memcpy(>fpu, >fpu, sizeof(cstate->fpu)); } }
CVS commit: src/sys/dev/nvmm/x86
Module Name:src Committed By: maxv Date: Thu Dec 13 16:28:10 UTC 2018 Modified Files: src/sys/dev/nvmm/x86: nvmm_x86_svm.c Log Message: Don't forget to advance the RIP after an XSETBV emulation. To generate a diff of this commit: cvs rdiff -u -r1.6 -r1.7 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.6 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.7 --- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.6 Sun Nov 25 14:09:57 2018 +++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c Thu Dec 13 16:28:10 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: nvmm_x86_svm.c,v 1.6 2018/11/25 14:09:57 maxv Exp $ */ +/* $NetBSD: nvmm_x86_svm.c,v 1.7 2018/12/13 16:28:10 maxv Exp $ */ /* * Copyright (c) 2018 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.6 2018/11/25 14:09:57 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.7 2018/12/13 16:28:10 maxv Exp $"); #include #include @@ -963,6 +963,7 @@ svm_exit_xsetbv(struct nvmm_machine *mac state->crs[NVMM_X64_CR_XCR0] = val; + cpudata->vmcb->state.rip = cpudata->vmcb->ctrl.nrip; return; error:
CVS commit: src/sys/dev/nvmm/x86
Module Name:src Committed By: maxv Date: Sun Nov 25 14:09:57 UTC 2018 Modified Files: src/sys/dev/nvmm/x86: nvmm_x86.h nvmm_x86_svm.c Log Message: Add RFLAGS in the exitstate. To generate a diff of this commit: cvs rdiff -u -r1.1 -r1.2 src/sys/dev/nvmm/x86/nvmm_x86.h cvs rdiff -u -r1.5 -r1.6 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.h diff -u src/sys/dev/nvmm/x86/nvmm_x86.h:1.1 src/sys/dev/nvmm/x86/nvmm_x86.h:1.2 --- src/sys/dev/nvmm/x86/nvmm_x86.h:1.1 Wed Nov 7 07:43:08 2018 +++ src/sys/dev/nvmm/x86/nvmm_x86.h Sun Nov 25 14:09:57 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: nvmm_x86.h,v 1.1 2018/11/07 07:43:08 maxv Exp $ */ +/* $NetBSD: nvmm_x86.h,v 1.2 2018/11/25 14:09:57 maxv Exp $ */ /* * Copyright (c) 2018 The NetBSD Foundation, Inc. @@ -123,7 +123,8 @@ struct nvmm_x64_state_seg { }; /* VM exit state indexes. */ -#define NVMM_X64_EXITSTATE_CR8 0 +#define NVMM_X64_EXITSTATE_CR8 0 +#define NVMM_X64_EXITSTATE_RFLAGS 1 /* Flags. */ #define NVMM_X64_STATE_SEGS 0x01 Index: src/sys/dev/nvmm/x86/nvmm_x86_svm.c diff -u src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.5 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.6 --- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.5 Thu Nov 22 07:37:12 2018 +++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c Sun Nov 25 14:09:57 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: nvmm_x86_svm.c,v 1.5 2018/11/22 07:37:12 maxv Exp $ */ +/* $NetBSD: nvmm_x86_svm.c,v 1.6 2018/11/25 14:09:57 maxv Exp $ */ /* * Copyright (c) 2018 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.5 2018/11/22 07:37:12 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.6 2018/11/25 14:09:57 maxv Exp $"); #include #include @@ -1205,6 +1205,7 @@ svm_vcpu_run(struct nvmm_machine *mach, exit->exitstate[NVMM_X64_EXITSTATE_CR8] = __SHIFTOUT(vmcb->ctrl.v, VMCB_CTRL_V_TPR); + exit->exitstate[NVMM_X64_EXITSTATE_RFLAGS] = vmcb->state.rflags; return 0; }
CVS commit: src/sys/dev/nvmm/x86
Module Name:src Committed By: maxv Date: Thu Nov 22 07:37:12 UTC 2018 Modified Files: src/sys/dev/nvmm/x86: nvmm_x86_svm.c Log Message: Add missing pmap_update after pmap_kenter_pa, noted by Kamil. To generate a diff of this commit: cvs rdiff -u -r1.4 -r1.5 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.4 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.5 --- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.4 Mon Nov 19 17:35:12 2018 +++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c Thu Nov 22 07:37:12 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: nvmm_x86_svm.c,v 1.4 2018/11/19 17:35:12 maxv Exp $ */ +/* $NetBSD: nvmm_x86_svm.c,v 1.5 2018/11/22 07:37: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.4 2018/11/19 17:35:12 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.5 2018/11/22 07:37:12 maxv Exp $"); #include #include @@ -1234,6 +1234,7 @@ svm_memalloc(paddr_t *pa, vaddr_t *va, s pmap_kenter_pa(_va + i * PAGE_SIZE, _pa + i * PAGE_SIZE, VM_PROT_READ | VM_PROT_WRITE, PMAP_WRITE_BACK); } + pmap_update(pmap_kernel()); memset((void *)_va, 0, npages * PAGE_SIZE);
CVS commit: src/sys/dev/nvmm/x86
Module Name:src Committed By: maxv Date: Mon Nov 19 17:35:12 UTC 2018 Modified Files: src/sys/dev/nvmm/x86: nvmm_x86_svm.c Log Message: Rename one constant, for clarity. To generate a diff of this commit: cvs rdiff -u -r1.3 -r1.4 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.3 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.4 --- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.3 Wed Nov 14 19:14:40 2018 +++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c Mon Nov 19 17:35:12 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: nvmm_x86_svm.c,v 1.3 2018/11/14 19:14:40 maxv Exp $ */ +/* $NetBSD: nvmm_x86_svm.c,v 1.4 2018/11/19 17:35: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.3 2018/11/14 19:14:40 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.4 2018/11/19 17:35:12 maxv Exp $"); #include #include @@ -770,7 +770,7 @@ svm_exit_cpuid(struct nvmm_machine *mach #define SVM_EXIT_IO_SZ8 __BIT(4) #define SVM_EXIT_IO_REP __BIT(3) #define SVM_EXIT_IO_STR __BIT(2) -#define SVM_EXIT_IO_TYPE __BIT(0) +#define SVM_EXIT_IO_IN __BIT(0) static const int seg_to_nvmm[] = { [0] = NVMM_X64_SEG_ES, @@ -791,7 +791,7 @@ svm_exit_io(struct nvmm_machine *mach, s exit->reason = NVMM_EXIT_IO; - if (info & SVM_EXIT_IO_TYPE) { + if (info & SVM_EXIT_IO_IN) { exit->u.io.type = NVMM_EXIT_IO_IN; } else { exit->u.io.type = NVMM_EXIT_IO_OUT;
CVS commit: src/sys/dev/nvmm/x86
Module Name:src Committed By: maxv Date: Wed Nov 14 19:14:40 UTC 2018 Modified Files: src/sys/dev/nvmm/x86: nvmm_x86_svm.c Log Message: Take RAX from the VMCB and not the VCPU state, the latter is not synchronized and contains old values. To generate a diff of this commit: cvs rdiff -u -r1.2 -r1.3 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.2 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.3 --- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.2 Sat Nov 10 09:42:42 2018 +++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c Wed Nov 14 19:14:40 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: nvmm_x86_svm.c,v 1.2 2018/11/10 09:42:42 maxv Exp $ */ +/* $NetBSD: nvmm_x86_svm.c,v 1.3 2018/11/14 19:14:40 maxv Exp $ */ /* * Copyright (c) 2018 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.2 2018/11/10 09:42:42 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.3 2018/11/14 19:14:40 maxv Exp $"); #include #include @@ -843,7 +843,7 @@ svm_inkernel_handle_msr(struct nvmm_mach case NVMM_EXIT_MSR_RDMSR: if (exit->u.msr.msr == MSR_CR_PAT) { pat = cpudata->vmcb->state.g_pat; - state->gprs[NVMM_X64_GPR_RAX] = (pat & 0x); + cpudata->vmcb->state.rax = (pat & 0x); state->gprs[NVMM_X64_GPR_RDX] = (pat >> 32); goto handled; } @@ -949,7 +949,7 @@ svm_exit_xsetbv(struct nvmm_machine *mac exit->reason = NVMM_EXIT_NONE; val = (state->gprs[NVMM_X64_GPR_RDX] << 32) | - (state->gprs[NVMM_X64_GPR_RAX] & 0x); + (vmcb->state.rax & 0x); if (__predict_false(state->gprs[NVMM_X64_GPR_RCX] != 0)) { goto error;