Module Name: src Committed By: maxv Date: Sun Oct 27 18:26:54 UTC 2019
Modified Files: src/sys/dev/nvmm/x86: nvmm_x86_vmx.c Log Message: Add PCID support in the guests. This speeds up most 64bit guests, because since Meltdown, everybody uses PCID (including NetBSD). To generate a diff of this commit: cvs rdiff -u -r1.42 -r1.43 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.42 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.43 --- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.42 Sun Oct 27 11:11:09 2019 +++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c Sun Oct 27 18:26:54 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: nvmm_x86_vmx.c,v 1.42 2019/10/27 11:11:09 maxv Exp $ */ +/* $NetBSD: nvmm_x86_vmx.c,v 1.43 2019/10/27 18:26:54 maxv Exp $ */ /* * Copyright (c) 2018-2019 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.42 2019/10/27 11:11:09 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.43 2019/10/27 18:26:54 maxv Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -1150,6 +1150,9 @@ vmx_inkernel_handle_cpuid(struct nvmm_cp cpudata->gprs[NVMM_X64_GPR_RCX] &= nvmm_cpuid_00000001.ecx; cpudata->gprs[NVMM_X64_GPR_RCX] |= CPUID2_RAZ; + if (vmx_procbased_ctls2 & PROC_CTLS2_INVPCID_ENABLE) { + cpudata->gprs[NVMM_X64_GPR_RCX] |= CPUID2_PCID; + } cpudata->gprs[NVMM_X64_GPR_RDX] &= nvmm_cpuid_00000001.edx; @@ -1171,6 +1174,9 @@ vmx_inkernel_handle_cpuid(struct nvmm_cp cpudata->gprs[NVMM_X64_GPR_RBX] &= nvmm_cpuid_00000007.ebx; cpudata->gprs[NVMM_X64_GPR_RCX] &= nvmm_cpuid_00000007.ecx; cpudata->gprs[NVMM_X64_GPR_RDX] &= nvmm_cpuid_00000007.edx; + if (vmx_procbased_ctls2 & PROC_CTLS2_INVPCID_ENABLE) { + cpudata->gprs[NVMM_X64_GPR_RBX] |= CPUID_SEF_INVPCID; + } break; case 0x0000000A: cpudata->gprs[NVMM_X64_GPR_RAX] = 0; @@ -2893,6 +2899,40 @@ vmx_machine_configure(struct nvmm_machin /* -------------------------------------------------------------------------- */ +#define CTLS_ONE_ALLOWED(msrval, bitoff) \ + ((msrval & __BIT(32 + bitoff)) != 0) +#define CTLS_ZERO_ALLOWED(msrval, bitoff) \ + ((msrval & __BIT(bitoff)) == 0) + +static int +vmx_check_ctls(uint64_t msr_ctls, uint64_t msr_true_ctls, uint64_t set_one) +{ + uint64_t basic, val, true_val; + bool has_true; + size_t i; + + basic = rdmsr(MSR_IA32_VMX_BASIC); + has_true = (basic & IA32_VMX_BASIC_TRUE_CTLS) != 0; + + val = rdmsr(msr_ctls); + if (has_true) { + true_val = rdmsr(msr_true_ctls); + } else { + true_val = val; + } + + for (i = 0; i < 32; i++) { + if (!(set_one & __BIT(i))) { + continue; + } + if (!CTLS_ONE_ALLOWED(true_val, i)) { + return -1; + } + } + + return 0; +} + static int vmx_init_ctls(uint64_t msr_ctls, uint64_t msr_true_ctls, uint64_t set_one, uint64_t set_zero, uint64_t *res) @@ -2911,14 +2951,9 @@ vmx_init_ctls(uint64_t msr_ctls, uint64_ true_val = val; } -#define ONE_ALLOWED(msrval, bitoff) \ - ((msrval & __BIT(32 + bitoff)) != 0) -#define ZERO_ALLOWED(msrval, bitoff) \ - ((msrval & __BIT(bitoff)) == 0) - for (i = 0; i < 32; i++) { - one_allowed = ONE_ALLOWED(true_val, i); - zero_allowed = ZERO_ALLOWED(true_val, i); + one_allowed = CTLS_ONE_ALLOWED(true_val, i); + zero_allowed = CTLS_ZERO_ALLOWED(true_val, i); if (zero_allowed && !one_allowed) { if (set_one & __BIT(i)) @@ -2935,9 +2970,9 @@ vmx_init_ctls(uint64_t msr_ctls, uint64_ *res |= __BIT(i); } else if (!has_true) { *res &= ~__BIT(i); - } else if (ZERO_ALLOWED(val, i)) { + } else if (CTLS_ZERO_ALLOWED(val, i)) { *res &= ~__BIT(i); - } else if (ONE_ALLOWED(val, i)) { + } else if (CTLS_ONE_ALLOWED(val, i)) { *res |= __BIT(i); } else { return -1; @@ -3011,6 +3046,12 @@ vmx_ident(void) if (ret == -1) { return false; } + ret = vmx_check_ctls( + MSR_IA32_VMX_PROCBASED_CTLS2, MSR_IA32_VMX_PROCBASED_CTLS2, + PROC_CTLS2_INVPCID_ENABLE); + if (ret != -1) { + vmx_procbased_ctls2 |= PROC_CTLS2_INVPCID_ENABLE; + } ret = vmx_init_ctls( MSR_IA32_VMX_ENTRY_CTLS, MSR_IA32_VMX_TRUE_ENTRY_CTLS, VMX_ENTRY_CTLS_ONE, VMX_ENTRY_CTLS_ZERO,