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 nvmm-x86: improve the CPUID emulation



details:   https://anonhg.NetBSD.org/src/rev/8823a1aa3245
branches:  trunk
changeset: 937476:8823a1aa3245
user:      maxv <maxv%NetBSD.org@localhost>
date:      Thu Aug 20 11:09:56 2020 +0000

description:
nvmm-x86: improve the CPUID emulation

 - x86-svm: explicitly handle 0x80000007 and 0x80000008. The latter
   contains extended features we must filter out. Apply the same in
   x86-vmx for symmetry.
 - x86-svm: explicitly handle extended leaves until 0x8000001F, and
   truncate to it.

diffstat:

 sys/dev/nvmm/x86/nvmm_x86.c     |  24 +++++++++++-
 sys/dev/nvmm/x86/nvmm_x86.h     |   6 ++-
 sys/dev/nvmm/x86/nvmm_x86_svm.c |  77 +++++++++++++++++++++++++++++++++++++++-
 sys/dev/nvmm/x86/nvmm_x86_vmx.c |  14 ++++++-
 4 files changed, 113 insertions(+), 8 deletions(-)

diffs (230 lines):

diff -r 7873e5db2eb1 -r 8823a1aa3245 sys/dev/nvmm/x86/nvmm_x86.c
--- a/sys/dev/nvmm/x86/nvmm_x86.c       Thu Aug 20 11:07:43 2020 +0000
+++ b/sys/dev/nvmm/x86/nvmm_x86.c       Thu Aug 20 11:09:56 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nvmm_x86.c,v 1.13 2020/08/20 11:07:43 maxv Exp $       */
+/*     $NetBSD: nvmm_x86.c,v 1.14 2020/08/20 11:09:56 maxv Exp $       */
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86.c,v 1.13 2020/08/20 11:07:43 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86.c,v 1.14 2020/08/20 11:09:56 maxv Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -421,6 +421,26 @@
            CPUID_3DNOW
 };
 
+const struct nvmm_x86_cpuid_mask nvmm_cpuid_80000007 = {
+       .eax = 0,
+       .ebx = 0,
+       .ecx = 0,
+       .edx = CPUID_APM_ITSC
+};
+
+const struct nvmm_x86_cpuid_mask nvmm_cpuid_80000008 = {
+       .eax = ~0,
+       .ebx =
+           CPUID_CAPEX_CLZERO |
+           /* CPUID_CAPEX_IRPERF excluded */
+           CPUID_CAPEX_XSAVEERPTR |
+           /* CPUID_CAPEX_RDPRU excluded */
+           /* CPUID_CAPEX_MCOMMIT excluded */
+           CPUID_CAPEX_WBNOINVD,
+       .ecx = ~0, /* TODO? */
+       .edx = 0
+};
+
 bool
 nvmm_x86_pat_validate(uint64_t val)
 {
diff -r 7873e5db2eb1 -r 8823a1aa3245 sys/dev/nvmm/x86/nvmm_x86.h
--- a/sys/dev/nvmm/x86/nvmm_x86.h       Thu Aug 20 11:07:43 2020 +0000
+++ b/sys/dev/nvmm/x86/nvmm_x86.h       Thu Aug 20 11:09:56 2020 +0000
@@ -1,7 +1,7 @@
-/*     $NetBSD: nvmm_x86.h,v 1.18 2019/10/28 08:30:49 maxv Exp $       */
+/*     $NetBSD: nvmm_x86.h,v 1.19 2020/08/20 11:09:56 maxv Exp $       */
 
 /*
- * Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
+ * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -320,6 +320,8 @@
 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;
+extern const struct nvmm_x86_cpuid_mask nvmm_cpuid_80000007;
+extern const struct nvmm_x86_cpuid_mask nvmm_cpuid_80000008;
 bool nvmm_x86_pat_validate(uint64_t);
 #endif
 
diff -r 7873e5db2eb1 -r 8823a1aa3245 sys/dev/nvmm/x86/nvmm_x86_svm.c
--- a/sys/dev/nvmm/x86/nvmm_x86_svm.c   Thu Aug 20 11:07:43 2020 +0000
+++ b/sys/dev/nvmm/x86/nvmm_x86_svm.c   Thu Aug 20 11:09:56 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nvmm_x86_svm.c,v 1.69 2020/08/18 17:08:05 maxv Exp $   */
+/*     $NetBSD: nvmm_x86_svm.c,v 1.70 2020/08/20 11:09:56 maxv Exp $   */
 
 /*
  * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.69 2020/08/18 17:08:05 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.70 2020/08/20 11:09:56 maxv Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -795,7 +795,9 @@
 
 #define SVM_CPUID_MAX_BASIC            0xD
 #define SVM_CPUID_MAX_HYPERVISOR       0x40000000
+#define SVM_CPUID_MAX_EXTENDED         0x8000001F
 static uint32_t svm_cpuid_max_basic __read_mostly;
+static uint32_t svm_cpuid_max_extended __read_mostly;
 
 static void
 svm_inkernel_exec_cpuid(struct svm_cpudata *cpudata, uint64_t eax, uint64_t ecx)
@@ -825,6 +827,11 @@
                        eax = svm_cpuid_max_basic;
                        svm_inkernel_exec_cpuid(cpudata, eax, ecx);
                }
+       } else {
+               if (__predict_false(eax > svm_cpuid_max_extended)) {
+                       eax = svm_cpuid_max_basic;
+                       svm_inkernel_exec_cpuid(cpudata, eax, ecx);
+               }
        }
 
        switch (eax) {
@@ -928,12 +935,74 @@
                memcpy(&cpudata->gprs[NVMM_X64_GPR_RDX], " ___", 4);
                break;
 
+       case 0x80000000:
+               cpudata->vmcb->state.rax = svm_cpuid_max_extended;
+               break;
        case 0x80000001:
                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;
+       case 0x80000002: /* Extended Processor Name String */
+       case 0x80000003: /* Extended Processor Name String */
+       case 0x80000004: /* Extended Processor Name String */
+       case 0x80000005: /* L1 Cache and TLB Information */
+       case 0x80000006: /* L2 Cache and TLB and L3 Cache Information */
+               break;
+       case 0x80000007: /* Processor Power Management and RAS Capabilities */
+               cpudata->vmcb->state.rax &= nvmm_cpuid_80000007.eax;
+               cpudata->gprs[NVMM_X64_GPR_RBX] &= nvmm_cpuid_80000007.ebx;
+               cpudata->gprs[NVMM_X64_GPR_RCX] &= nvmm_cpuid_80000007.ecx;
+               cpudata->gprs[NVMM_X64_GPR_RDX] &= nvmm_cpuid_80000007.edx;
+               break;
+       case 0x80000008: /* Processor Capacity Parameters and Ext Feat Ident */
+               cpudata->vmcb->state.rax &= nvmm_cpuid_80000008.eax;
+               cpudata->gprs[NVMM_X64_GPR_RBX] &= nvmm_cpuid_80000008.ebx;
+               cpudata->gprs[NVMM_X64_GPR_RCX] &= nvmm_cpuid_80000008.ecx;
+               cpudata->gprs[NVMM_X64_GPR_RDX] &= nvmm_cpuid_80000008.edx;
+               break;
+       case 0x80000009: /* Empty */
+       case 0x8000000A: /* SVM Features */
+       case 0x8000000B: /* Empty */
+       case 0x8000000C: /* Empty */
+       case 0x8000000D: /* Empty */
+       case 0x8000000E: /* Empty */
+       case 0x8000000F: /* Empty */
+       case 0x80000010: /* Empty */
+       case 0x80000011: /* Empty */
+       case 0x80000012: /* Empty */
+       case 0x80000013: /* Empty */
+       case 0x80000014: /* Empty */
+       case 0x80000015: /* Empty */
+       case 0x80000016: /* Empty */
+       case 0x80000017: /* Empty */
+       case 0x80000018: /* Empty */
+               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 0x80000019: /* TLB Characteristics for 1GB pages */
+       case 0x8000001A: /* Instruction Optimizations */
+               break;
+       case 0x8000001B: /* Instruction-Based Sampling Capabilities */
+       case 0x8000001C: /* Lightweight Profiling Capabilities */
+               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 0x8000001D: /* Cache Topology Information */
+       case 0x8000001E: /* Processor Topology Information */
+               break; /* TODO? */
+       case 0x8000001F: /* Encrypted Memory Capabilities */
+               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;
+
        default:
                break;
        }
@@ -2460,6 +2529,10 @@
        /* Init the max basic CPUID leaf. */
        svm_cpuid_max_basic = uimin(cpuid_level, SVM_CPUID_MAX_BASIC);
 
+       /* Init the max extended CPUID leaf. */
+       x86_cpuid(0x80000000, descs);
+       svm_cpuid_max_extended = uimin(descs[0], SVM_CPUID_MAX_EXTENDED);
+
        memset(hsave, 0, sizeof(hsave));
        for (CPU_INFO_FOREACH(cii, ci)) {
                pg = uvm_pagealloc(NULL, 0, NULL, UVM_PGA_ZERO);
diff -r 7873e5db2eb1 -r 8823a1aa3245 sys/dev/nvmm/x86/nvmm_x86_vmx.c
--- a/sys/dev/nvmm/x86/nvmm_x86_vmx.c   Thu Aug 20 11:07:43 2020 +0000
+++ b/sys/dev/nvmm/x86/nvmm_x86_vmx.c   Thu Aug 20 11:09:56 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nvmm_x86_vmx.c,v 1.70 2020/08/18 17:03:10 maxv Exp $   */
+/*     $NetBSD: nvmm_x86_vmx.c,v 1.71 2020/08/20 11:09:56 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.70 2020/08/18 17:03:10 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.71 2020/08/20 11:09:56 maxv Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -1395,8 +1395,18 @@
        case 0x80000004: /* Processor Brand String */
        case 0x80000005: /* Reserved Zero */
        case 0x80000006: /* Cache Information */
+               break;
        case 0x80000007: /* TSC Information */
+               cpudata->gprs[NVMM_X64_GPR_RAX] &= nvmm_cpuid_80000007.eax;
+               cpudata->gprs[NVMM_X64_GPR_RBX] &= nvmm_cpuid_80000007.ebx;
+               cpudata->gprs[NVMM_X64_GPR_RCX] &= nvmm_cpuid_80000007.ecx;
+               cpudata->gprs[NVMM_X64_GPR_RDX] &= nvmm_cpuid_80000007.edx;
+               break;
        case 0x80000008: /* Address Sizes */
+               cpudata->gprs[NVMM_X64_GPR_RAX] &= nvmm_cpuid_80000008.eax;
+               cpudata->gprs[NVMM_X64_GPR_RBX] &= nvmm_cpuid_80000008.ebx;
+               cpudata->gprs[NVMM_X64_GPR_RCX] &= nvmm_cpuid_80000008.ecx;
+               cpudata->gprs[NVMM_X64_GPR_RDX] &= nvmm_cpuid_80000008.edx;
                break;
 
        default:



Home | Main Index | Thread Index | Old Index