Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/nvmm On Intel CPUs, CPUID leaf 0xB, too, provides to...



details:   https://anonhg.NetBSD.org/src/rev/fa7303e23809
branches:  trunk
changeset: 932491:fa7303e23809
user:      maxv <maxv%NetBSD.org@localhost>
date:      Sat May 09 08:39:07 2020 +0000

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

diffstat:

 sys/dev/nvmm/nvmm.c             |   8 ++++++--
 sys/dev/nvmm/nvmm_internal.h    |   3 ++-
 sys/dev/nvmm/x86/nvmm_x86_vmx.c |  38 ++++++++++++++++++++++++++++++++++----
 3 files changed, 42 insertions(+), 7 deletions(-)

diffs (135 lines):

diff -r cba302040512 -r fa7303e23809 sys/dev/nvmm/nvmm.c
--- a/sys/dev/nvmm/nvmm.c       Sat May 09 08:25:33 2020 +0000
+++ b/sys/dev/nvmm/nvmm.c       Sat May 09 08:39:07 2020 +0000
@@ -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_put(vcpu);
 
+       atomic_inc_uint(&mach->ncpus);
+
 out:
        nvmm_machine_put(mach);
        return error;
@@ -437,6 +439,8 @@
        nvmm_vcpu_free(mach, vcpu);
        nvmm_vcpu_put(vcpu);
 
+       atomic_dec_uint(&mach->ncpus);
+
 out:
        nvmm_machine_put(mach);
        return error;
diff -r cba302040512 -r fa7303e23809 sys/dev/nvmm/nvmm_internal.h
--- a/sys/dev/nvmm/nvmm_internal.h      Sat May 09 08:25:33 2020 +0000
+++ b/sys/dev/nvmm/nvmm_internal.h      Sat May 09 08:39:07 2020 +0000
@@ -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_hmapping hmap[NVMM_MAX_HMAPPINGS];
 
        /* CPU */
+       volatile unsigned int ncpus;
        struct nvmm_cpu cpus[NVMM_MAX_VCPUS];
 
        /* Implementation-specific */
diff -r cba302040512 -r fa7303e23809 sys/dev/nvmm/x86/nvmm_x86_vmx.c
--- a/sys/dev/nvmm/x86/nvmm_x86_vmx.c   Sat May 09 08:25:33 2020 +0000
+++ b/sys/dev/nvmm/x86/nvmm_x86_vmx.c   Sat May 09 08:39:07 2020 +0000
@@ -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 @@
 #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 @@
 }
 
 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 @@
                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 @@
        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]) {



Home | Main Index | Thread Index | Old Index