Module Name:    src
Committed By:   maxv
Date:           Sat May  9 08:39:07 UTC 2020

Modified Files:
        src/sys/dev/nvmm: nvmm.c nvmm_internal.h
        src/sys/dev/nvmm/x86: nvmm_x86_vmx.c

Log Message:
On Intel CPUs, CPUID leaf 0xB, too, provides topology information, so
filter it correctly, to avoid inconsistencies if the host has SMT.

This fixes HaikuOS which fetches SMT information from there and would
panic because of the inconsistencies.


To generate a diff of this commit:
cvs rdiff -u -r1.27 -r1.28 src/sys/dev/nvmm/nvmm.c
cvs rdiff -u -r1.13 -r1.14 src/sys/dev/nvmm/nvmm_internal.h
cvs rdiff -u -r1.54 -r1.55 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/nvmm/nvmm.c
diff -u src/sys/dev/nvmm/nvmm.c:1.27 src/sys/dev/nvmm/nvmm.c:1.28
--- src/sys/dev/nvmm/nvmm.c:1.27	Thu Apr 30 16:50:17 2020
+++ src/sys/dev/nvmm/nvmm.c	Sat May  9 08:39:07 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm.c,v 1.27 2020/04/30 16:50:17 maxv Exp $	*/
+/*	$NetBSD: nvmm.c,v 1.28 2020/05/09 08:39:07 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.27 2020/04/30 16:50:17 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.28 2020/05/09 08:39:07 maxv Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -413,6 +413,8 @@ nvmm_vcpu_create(struct nvmm_owner *owne
 
 	nvmm_vcpu_put(vcpu);
 
+	atomic_inc_uint(&mach->ncpus);
+
 out:
 	nvmm_machine_put(mach);
 	return error;
@@ -437,6 +439,8 @@ nvmm_vcpu_destroy(struct nvmm_owner *own
 	nvmm_vcpu_free(mach, vcpu);
 	nvmm_vcpu_put(vcpu);
 
+	atomic_dec_uint(&mach->ncpus);
+
 out:
 	nvmm_machine_put(mach);
 	return error;

Index: src/sys/dev/nvmm/nvmm_internal.h
diff -u src/sys/dev/nvmm/nvmm_internal.h:1.13 src/sys/dev/nvmm/nvmm_internal.h:1.14
--- src/sys/dev/nvmm/nvmm_internal.h:1.13	Wed Oct 23 07:01:11 2019
+++ src/sys/dev/nvmm/nvmm_internal.h	Sat May  9 08:39:07 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_internal.h,v 1.13 2019/10/23 07:01:11 maxv Exp $	*/
+/*	$NetBSD: nvmm_internal.h,v 1.14 2020/05/09 08:39:07 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
@@ -83,6 +83,7 @@ struct nvmm_machine {
 	struct nvmm_hmapping hmap[NVMM_MAX_HMAPPINGS];
 
 	/* CPU */
+	volatile unsigned int ncpus;
 	struct nvmm_cpu cpus[NVMM_MAX_VCPUS];
 
 	/* Implementation-specific */

Index: src/sys/dev/nvmm/x86/nvmm_x86_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.54 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.55
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.54	Thu Apr 30 16:56:23 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Sat May  9 08:39:07 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.54 2020/04/30 16:56:23 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.55 2020/05/09 08:39:07 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.54 2020/04/30 16:56:23 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.55 2020/05/09 08:39:07 maxv Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -39,6 +39,7 @@ __KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx
 #include <sys/cpu.h>
 #include <sys/xcall.h>
 #include <sys/mman.h>
+#include <sys/bitops.h>
 
 #include <uvm/uvm.h>
 #include <uvm/uvm_page.h>
@@ -1137,9 +1138,11 @@ error:
 }
 
 static void
-vmx_inkernel_handle_cpuid(struct nvmm_cpu *vcpu, uint64_t eax, uint64_t ecx)
+vmx_inkernel_handle_cpuid(struct nvmm_machine *mach, struct nvmm_cpu *vcpu,
+    uint64_t eax, uint64_t ecx)
 {
 	struct vmx_cpudata *cpudata = vcpu->cpudata;
+	unsigned int ncpus;
 	uint64_t cr4;
 
 	switch (eax) {
@@ -1186,6 +1189,33 @@ vmx_inkernel_handle_cpuid(struct nvmm_cp
 		cpudata->gprs[NVMM_X64_GPR_RCX] = 0;
 		cpudata->gprs[NVMM_X64_GPR_RDX] = 0;
 		break;
+	case 0x0000000B:
+		switch (ecx) {
+		case 0: /* Threads */
+			cpudata->gprs[NVMM_X64_GPR_RAX] = 0;
+			cpudata->gprs[NVMM_X64_GPR_RBX] = 0;
+			cpudata->gprs[NVMM_X64_GPR_RCX] =
+			    __SHIFTIN(ecx, CPUID_TOP_LVLNUM) |
+			    __SHIFTIN(CPUID_TOP_LVLTYPE_SMT, CPUID_TOP_LVLTYPE);
+			cpudata->gprs[NVMM_X64_GPR_RDX] = vcpu->cpuid;
+			break;
+		case 1: /* Cores */
+			ncpus = atomic_load_relaxed(&mach->ncpus);
+			cpudata->gprs[NVMM_X64_GPR_RAX] = ilog2(ncpus);
+			cpudata->gprs[NVMM_X64_GPR_RBX] = ncpus;
+			cpudata->gprs[NVMM_X64_GPR_RCX] =
+			    __SHIFTIN(ecx, CPUID_TOP_LVLNUM) |
+			    __SHIFTIN(CPUID_TOP_LVLTYPE_CORE, CPUID_TOP_LVLTYPE);
+			cpudata->gprs[NVMM_X64_GPR_RDX] = vcpu->cpuid;
+			break;
+		default:
+			cpudata->gprs[NVMM_X64_GPR_RAX] = 0;
+			cpudata->gprs[NVMM_X64_GPR_RBX] = 0;
+			cpudata->gprs[NVMM_X64_GPR_RCX] = 0; /* LVLTYPE_INVAL */
+			cpudata->gprs[NVMM_X64_GPR_RDX] = 0;
+			break;
+		}
+		break;
 	case 0x0000000D:
 		if (vmx_xcr0_mask == 0) {
 			break;
@@ -1267,7 +1297,7 @@ vmx_exit_cpuid(struct nvmm_machine *mach
 	cpudata->gprs[NVMM_X64_GPR_RCX] = descs[2];
 	cpudata->gprs[NVMM_X64_GPR_RDX] = descs[3];
 
-	vmx_inkernel_handle_cpuid(vcpu, eax, ecx);
+	vmx_inkernel_handle_cpuid(mach, vcpu, eax, ecx);
 
 	for (i = 0; i < VMX_NCPUIDS; i++) {
 		if (!cpudata->cpuidpresent[i]) {

Reply via email to