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 <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 @@ const struct nvmm_x64_state nvmm_x86_res
 		.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
+};

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 {
+	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 */

Index: src/sys/dev/nvmm/x86/nvmm_x86_svm.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.32 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.33
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.32	Tue Feb 26 12:23:12 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Sun Mar  3 07:01:09 2019
@@ -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 @@ svm_inkernel_handle_cpuid(struct nvmm_cp
 
 	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 @@ svm_inkernel_handle_cpuid(struct nvmm_cp
 		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;

Index: src/sys/dev/nvmm/x86/nvmm_x86_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.15 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.16
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.15	Tue Feb 26 12:23:12 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Sun Mar  3 07:01:09 2019
@@ -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 @@ vmx_inkernel_handle_cpuid(struct nvmm_cp
 
 	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 @@ vmx_inkernel_handle_cpuid(struct nvmm_cp
 		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 @@ vmx_inkernel_handle_cpuid(struct nvmm_cp
 		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;

Reply via email to