From 84a72f96178d4f1c7b995a0517837188deb31dde Mon Sep 17 00:00:00 2001 From: Aaron LI Date: Sat, 3 Jul 2021 14:29:15 +0800 Subject: [PATCH] nvmm: Improve CPUID emulation #4: handle Fn0000_0004 on Intel Handle CPUID Fn0000_0004 (Deterministic Cache Parameters) on Intel CPUs. --- sys/dev/virtual/nvmm/nvmm_compat.h | 9 +++++++++ sys/dev/virtual/nvmm/x86/nvmm_x86_vmx.c | 21 ++++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/sys/dev/virtual/nvmm/nvmm_compat.h b/sys/dev/virtual/nvmm/nvmm_compat.h index dc470d0188..2ac355f0f7 100644 --- a/sys/dev/virtual/nvmm/nvmm_compat.h +++ b/sys/dev/virtual/nvmm/nvmm_compat.h @@ -85,6 +85,15 @@ #define CPUID2_DEADLINE CPUID2_TSCDLT #define CPUID2_RAZ CPUID2_VMM +/* + * Intel Deterministic Cache Parameters + * CPUID Fn0000_0004 + */ +/* %eax */ +#define CPUID_DCP_CACHELEVEL __BITS(7, 5) /* Cache level (start at 1) */ +#define CPUID_DCP_SHARING __BITS(25, 14) /* Sharing */ +#define CPUID_DCP_CORE_P_PKG __BITS(31, 26) /* Cores/package */ + /* * Intel/AMD Structured Extended Feature * CPUID Fn0000_0007 diff --git a/sys/dev/virtual/nvmm/x86/nvmm_x86_vmx.c b/sys/dev/virtual/nvmm/x86/nvmm_x86_vmx.c index 346a0bf4e5..044cf25102 100644 --- a/sys/dev/virtual/nvmm/x86/nvmm_x86_vmx.c +++ b/sys/dev/virtual/nvmm/x86/nvmm_x86_vmx.c @@ -1276,6 +1276,7 @@ vmx_inkernel_handle_cpuid(struct nvmm_machine *mach, struct nvmm_cpu *vcpu, { struct vmx_cpudata *cpudata = vcpu->cpudata; unsigned int ncpus; + uint32_t clevel; uint64_t cr4; if (eax < 0x40000000) { @@ -1329,7 +1330,25 @@ vmx_inkernel_handle_cpuid(struct nvmm_machine *mach, struct nvmm_cpu *vcpu, cpudata->gprs[NVMM_X64_GPR_RDX] = 0; break; case 0x00000004: /* Deterministic Cache Parameters */ - break; /* TODO? */ + ncpus = atomic_load_acq_int(&mach->ncpus); + clevel = __SHIFTOUT(cpudata->gprs[NVMM_X64_GPR_RAX], + CPUID_DCP_CACHELEVEL); + + cpudata->gprs[NVMM_X64_GPR_RAX] &= ~CPUID_DCP_SHARING; + if (clevel >= 3) { + /* L3 and above: all CPUs. */ + cpudata->gprs[NVMM_X64_GPR_RAX] |= + __SHIFTIN(ncpus - 1, CPUID_DCP_SHARING); + } else { + /* L2 and below: one LP per CPU. */ + cpudata->gprs[NVMM_X64_GPR_RAX] |= + __SHIFTIN(0, CPUID_DCP_SHARING); + } + + cpudata->gprs[NVMM_X64_GPR_RAX] &= ~CPUID_DCP_CORE_P_PKG; + cpudata->gprs[NVMM_X64_GPR_RAX] |= + __SHIFTIN(ncpus - 1, CPUID_DCP_CORE_P_PKG); + break; case 0x00000005: /* MONITOR/MWAIT */ case 0x00000006: /* Thermal and Power Management */ cpudata->gprs[NVMM_X64_GPR_RAX] = 0; -- 2.41.0