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/16305c07a61e
branches:  trunk
changeset: 971926:16305c07a61e
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 8a97d6f41c7f -r 16305c07a61e 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 8a97d6f41c7f -r 16305c07a61e 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 8a97d6f41c7f -r 16305c07a61e 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