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/7ec825d9544e
branches: trunk
changeset: 942799:7ec825d9544e
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 bb9e1cf3c42f -r 7ec825d9544e 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 bb9e1cf3c42f -r 7ec825d9544e 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 bb9e1cf3c42f -r 7ec825d9544e 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 bb9e1cf3c42f -r 7ec825d9544e 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