From a7a0da844d299971bdbf99665bd63398668dde83 Mon Sep 17 00:00:00 2001 From: Michael Roth Date: Wed, 7 Jul 2021 19:36:23 -0500 Subject: [PATCH] target/i386: suppress CPUID leaves not defined by the CPU vendor Currently all built-in CPUs report cache information via CPUID leaves 2 and 4, but these have never been defined for AMD. In the case of SEV-SNP this can cause issues with CPUID enforcement. Address this by allowing CPU types to suppress these via a new "x-vendor-cpuid-only" CPU property, which is true by default, but switched off for older machine types to maintain compatibility. Cc: "Dr. David Alan Gilbert" Cc: Eduardo Habkost Cc: Richard Henderson Cc: Igor Mammedov Cc: zhenwei pi Suggested-by: Eduardo Habkost Signed-off-by: Michael Roth Message-Id: <20210708003623.18665-1-michael.roth@amd.com> Signed-off-by: Eduardo Habkost --- hw/i386/pc.c | 1 + target/i386/cpu.c | 6 ++++++ target/i386/cpu.h | 3 +++ 3 files changed, 10 insertions(+) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 8e1220db72..aa79c5e0e6 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -98,6 +98,7 @@ GlobalProperty pc_compat_6_0[] = { { "qemu64" "-" TYPE_X86_CPU, "family", "6" }, { "qemu64" "-" TYPE_X86_CPU, "model", "6" }, { "qemu64" "-" TYPE_X86_CPU, "stepping", "3" }, + { TYPE_X86_CPU, "x-vendor-cpuid-only", "off" }, }; const size_t pc_compat_6_0_len = G_N_ELEMENTS(pc_compat_6_0); diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 46befde387..6b7043e425 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -5155,6 +5155,9 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, if (cpu->cache_info_passthrough) { host_cpuid(index, 0, eax, ebx, ecx, edx); break; + } else if (cpu->vendor_cpuid_only && IS_AMD_CPU(env)) { + *eax = *ebx = *ecx = *edx = 0; + break; } *eax = 1; /* Number of CPUID[EAX=2] calls required */ *ebx = 0; @@ -5176,6 +5179,8 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, if ((*eax & 31) && cs->nr_cores > 1) { *eax |= (cs->nr_cores - 1) << 26; } + } else if (cpu->vendor_cpuid_only && IS_AMD_CPU(env)) { + *eax = *ebx = *ecx = *edx = 0; } else { *eax = 0; switch (count) { @@ -6651,6 +6656,7 @@ static Property x86_cpu_properties[] = { DEFINE_PROP_BOOL("full-cpuid-auto-level", X86CPU, full_cpuid_auto_level, true), DEFINE_PROP_STRING("hv-vendor-id", X86CPU, hyperv_vendor), DEFINE_PROP_BOOL("cpuid-0xb", X86CPU, enable_cpuid_0xb, true), + DEFINE_PROP_BOOL("x-vendor-cpuid-only", X86CPU, vendor_cpuid_only, true), DEFINE_PROP_BOOL("lmce", X86CPU, enable_lmce, false), DEFINE_PROP_BOOL("l3-cache", X86CPU, enable_l3_cache, true), DEFINE_PROP_BOOL("kvm-no-smi-migration", X86CPU, kvm_no_smi_migration, diff --git a/target/i386/cpu.h b/target/i386/cpu.h index 8f3747dd28..950a991a71 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -1748,6 +1748,9 @@ struct X86CPU { /* Enable auto level-increase for all CPUID leaves */ bool full_cpuid_auto_level; + /* Only advertise CPUID leaves defined by the vendor */ + bool vendor_cpuid_only; + /* Enable auto level-increase for Intel Processor Trace leave */ bool intel_pt_auto_level;