Introduce new CPU property x-force-cpuid-0x80000026 using which the CPUID 0x80000026 is enabled. It defaults to false. If a vCPU's model is host, then CPUID is enabled based on CPU family/model. Implement x86_is_amd_zen4_or_above() helper to detect Zen4+ CPUs using family/model. Signed-off-by: Shivansh Dhiman --- target/i386/cpu.c | 8 ++++++++ target/i386/cpu.h | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index b7827e448aa5..01c4da7cf134 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -9158,6 +9158,12 @@ void x86_cpu_expand_features(X86CPU *cpu, Error **errp) if (env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_SGX) { x86_cpu_adjust_level(cpu, &env->cpuid_min_level, 0x12); } + + /* Enable CPUID[0x80000026] for AMD Genoa models and above */ + if (cpu->force_cpuid_0x80000026 || + (!xcc->model && x86_is_amd_zen4_or_above(cpu))) { + x86_cpu_adjust_level(cpu, &env->cpuid_min_xlevel, 0x80000026); + } } /* Set cpuid_*level* based on cpuid_min_*level, if not explicitly set */ @@ -10133,6 +10139,8 @@ static const Property x86_cpu_properties[] = { arch_cap_always_on, false), DEFINE_PROP_BOOL("x-pdcm-on-even-without-pmu", X86CPU, pdcm_on_even_without_pmu, false), + DEFINE_PROP_BOOL("x-force-cpuid-0x80000026", X86CPU, force_cpuid_0x80000026, + false), }; #ifndef CONFIG_USER_ONLY diff --git a/target/i386/cpu.h b/target/i386/cpu.h index cee1f692a1c3..0fecca26dc4a 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -2292,6 +2292,9 @@ struct ArchCPU { /* Force to enable cpuid 0x1f */ bool force_cpuid_0x1f; + /* Force to enable cpuid 0x80000026 */ + bool force_cpuid_0x80000026; + /* Enable auto level-increase for all CPUID leaves */ bool full_cpuid_auto_level; @@ -2879,6 +2882,21 @@ void x86_cpu_xsave_all_areas(X86CPU *cpu, void *buf, uint32_t buflen); uint32_t xsave_area_size(uint64_t mask, bool compacted); void x86_update_hflags(CPUX86State* env); +static inline bool x86_is_amd_zen4_or_above(X86CPU *cpu) +{ + uint32_t family = x86_cpu_family(cpu->env.cpuid_version); + uint32_t model = x86_cpu_model(cpu->env.cpuid_version); + + if (!IS_AMD_CPU(&cpu->env) || family < 0x19) { + return false; + } + if (family > 0x19) { + return true; + } + return (model >= 0x10 && model <= 0x1f) || + (model >= 0x60 && model <= 0xaf); +} + static inline bool hyperv_feat_enabled(X86CPU *cpu, int feat) { return !!(cpu->hyperv_features & BIT(feat)); -- 2.43.0