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 <[email protected]>
---
 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


Reply via email to