Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/nvmm/x86 Choose which CPUID bits to allow, rather th...



details:   https://anonhg.NetBSD.org/src/rev/fe9f6e1f7f96
branches:  trunk
changeset: 449304:fe9f6e1f7f96
user:      maxv <maxv%NetBSD.org@localhost>
date:      Sun Mar 03 07:01:09 2019 +0000

description:
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.

diffstat:

 sys/dev/nvmm/x86/nvmm_x86.c     |  90 ++++++++++++++++++++++++++++++++++++++++-
 sys/dev/nvmm/x86/nvmm_x86.h     |  11 ++++-
 sys/dev/nvmm/x86/nvmm_x86_svm.c |  30 +++++++++++-
 sys/dev/nvmm/x86/nvmm_x86_vmx.c |  29 +++++++-----
 4 files changed, 141 insertions(+), 19 deletions(-)

diffs (269 lines):

diff -r c4204ab87ede -r fe9f6e1f7f96 sys/dev/nvmm/x86/nvmm_x86.c
--- a/sys/dev/nvmm/x86/nvmm_x86.c       Sun Mar 03 04:51:57 2019 +0000
+++ b/sys/dev/nvmm/x86/nvmm_x86.c       Sun Mar 03 07:01:09 2019 +0000
@@ -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 <sys/cdefs.h>
-__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 <sys/param.h>
 #include <sys/systm.h>
@@ -226,3 +226,89 @@
                .fx_mxcsr = 0x1F80,
        }
 };
+
+const struct nvmm_x86_cpuid_mask nvmm_cpuid_00000001 = {
+       .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_00000007 = {
+       .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_80000001 = {
+       .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
+};
diff -r c4204ab87ede -r fe9f6e1f7f96 sys/dev/nvmm/x86/nvmm_x86.h
--- a/sys/dev/nvmm/x86/nvmm_x86.h       Sun Mar 03 04:51:57 2019 +0000
+++ b/sys/dev/nvmm/x86/nvmm_x86.h       Sun Mar 03 07:01:09 2019 +0000
@@ -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 @@
 };
 
 #ifdef _KERNEL
+struct nvmm_x86_cpuid_mask {
+       uint32_t eax;
+       uint32_t ebx;
+       uint32_t ecx;
+       uint32_t edx;
+};
 extern const struct nvmm_x64_state nvmm_x86_reset_state;
+extern const struct nvmm_x86_cpuid_mask nvmm_cpuid_00000001;
+extern const struct nvmm_x86_cpuid_mask nvmm_cpuid_00000007;
+extern const struct nvmm_x86_cpuid_mask nvmm_cpuid_80000001;
 #endif
 
 #endif /* ASM_NVMM */
diff -r c4204ab87ede -r fe9f6e1f7f96 sys/dev/nvmm/x86/nvmm_x86_svm.c
--- a/sys/dev/nvmm/x86/nvmm_x86_svm.c   Sun Mar 03 04:51:57 2019 +0000
+++ b/sys/dev/nvmm/x86/nvmm_x86_svm.c   Sun Mar 03 07:01:09 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nvmm_x86_svm.c,v 1.32 2019/02/26 12:23:12 maxv Exp $   */
+/*     $NetBSD: nvmm_x86_svm.c,v 1.33 2019/03/03 07:01:09 maxv Exp $   */
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.32 2019/02/26 12:23:12 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.33 2019/03/03 07:01:09 maxv Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -758,16 +758,36 @@
 
        switch (eax) {
        case 0x00000001:
+               cpudata->vmcb->state.rax &= nvmm_cpuid_00000001.eax;
+
                cpudata->gprs[NVMM_X64_GPR_RBX] &= ~CPUID_LOCAL_APIC_ID;
                cpudata->gprs[NVMM_X64_GPR_RBX] |= __SHIFTIN(vcpu->cpuid,
                    CPUID_LOCAL_APIC_ID);
 
+               cpudata->gprs[NVMM_X64_GPR_RCX] &= nvmm_cpuid_00000001.ecx;
+               cpudata->gprs[NVMM_X64_GPR_RCX] |= CPUID2_RAZ;
+
+               cpudata->gprs[NVMM_X64_GPR_RDX] &= nvmm_cpuid_00000001.edx;
+
                /* CPUID2_OSXSAVE depends on CR4. */
                cr4 = cpudata->vmcb->state.cr4;
                if (!(cr4 & CR4_OSXSAVE)) {
                        cpudata->gprs[NVMM_X64_GPR_RCX] &= ~CPUID2_OSXSAVE;
                }
                break;
+       case 0x00000005:
+       case 0x00000006:
+               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 0x00000007:
+               cpudata->vmcb->state.rax &= nvmm_cpuid_00000007.eax;
+               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;
+               break;
        case 0x0000000D:
                if (svm_xcr0_mask == 0) {
                        break;
@@ -798,8 +818,10 @@
                memcpy(&cpudata->gprs[NVMM_X64_GPR_RDX], " ___", 4);
                break;
        case 0x80000001:
-               cpudata->gprs[NVMM_X64_GPR_RCX] &= ~CPUID_SVM;
-               cpudata->gprs[NVMM_X64_GPR_RDX] &= ~CPUID_RDTSCP;
+               cpudata->vmcb->state.rax &= nvmm_cpuid_80000001.eax;
+               cpudata->gprs[NVMM_X64_GPR_RBX] &= nvmm_cpuid_80000001.ebx;
+               cpudata->gprs[NVMM_X64_GPR_RCX] &= nvmm_cpuid_80000001.ecx;
+               cpudata->gprs[NVMM_X64_GPR_RDX] &= nvmm_cpuid_80000001.edx;
                break;
        default:
                break;
diff -r c4204ab87ede -r fe9f6e1f7f96 sys/dev/nvmm/x86/nvmm_x86_vmx.c
--- a/sys/dev/nvmm/x86/nvmm_x86_vmx.c   Sun Mar 03 04:51:57 2019 +0000
+++ b/sys/dev/nvmm/x86/nvmm_x86_vmx.c   Sun Mar 03 07:01:09 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nvmm_x86_vmx.c,v 1.15 2019/02/26 12:23:12 maxv Exp $   */
+/*     $NetBSD: nvmm_x86_vmx.c,v 1.16 2019/03/03 07:01:09 maxv Exp $   */
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.15 2019/02/26 12:23:12 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.16 2019/03/03 07:01:09 maxv Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -992,14 +992,16 @@
 
        switch (eax) {
        case 0x00000001:
+               cpudata->gprs[NVMM_X64_GPR_RAX] &= nvmm_cpuid_00000001.eax;
+
                cpudata->gprs[NVMM_X64_GPR_RBX] &= ~CPUID_LOCAL_APIC_ID;
                cpudata->gprs[NVMM_X64_GPR_RBX] |= __SHIFTIN(vcpu->cpuid,
                    CPUID_LOCAL_APIC_ID);
-               cpudata->gprs[NVMM_X64_GPR_RCX] &=
-                   ~(CPUID2_VMX|CPUID2_SMX|CPUID2_EST|CPUID2_TM2|CPUID2_PDCM|
-                     CPUID2_PCID|CPUID2_DEADLINE);
-               cpudata->gprs[NVMM_X64_GPR_RDX] &=
-                   ~(CPUID_DS|CPUID_ACPI|CPUID_TM);
+
+               cpudata->gprs[NVMM_X64_GPR_RCX] &= nvmm_cpuid_00000001.ecx;
+               cpudata->gprs[NVMM_X64_GPR_RCX] |= CPUID2_RAZ;
+
+               cpudata->gprs[NVMM_X64_GPR_RDX] &= nvmm_cpuid_00000001.edx;
 
                /* CPUID2_OSXSAVE depends on CR4. */
                vmx_vmread(VMCS_GUEST_CR4, &cr4);
@@ -1015,10 +1017,10 @@
                cpudata->gprs[NVMM_X64_GPR_RDX] = 0;
                break;
        case 0x00000007:
-               cpudata->gprs[NVMM_X64_GPR_RBX] &= ~CPUID_SEF_INVPCID;
-               cpudata->gprs[NVMM_X64_GPR_RDX] &=
-                   ~(CPUID_SEF_IBRS|CPUID_SEF_STIBP|CPUID_SEF_L1D_FLUSH|
-                     CPUID_SEF_SSBD);
+               cpudata->gprs[NVMM_X64_GPR_RAX] &= nvmm_cpuid_00000007.eax;
+               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;
                break;
        case 0x0000000D:
                if (vmx_xcr0_mask == 0) {
@@ -1050,7 +1052,10 @@
                memcpy(&cpudata->gprs[NVMM_X64_GPR_RDX], " ___", 4);
                break;
        case 0x80000001:
-               cpudata->gprs[NVMM_X64_GPR_RDX] &= ~CPUID_RDTSCP;
+               cpudata->gprs[NVMM_X64_GPR_RAX] &= nvmm_cpuid_80000001.eax;
+               cpudata->gprs[NVMM_X64_GPR_RBX] &= nvmm_cpuid_80000001.ebx;
+               cpudata->gprs[NVMM_X64_GPR_RCX] &= nvmm_cpuid_80000001.ecx;
+               cpudata->gprs[NVMM_X64_GPR_RDX] &= nvmm_cpuid_80000001.edx;
                break;
        default:
                break;



Home | Main Index | Thread Index | Old Index