Kernel KVM virtualization development
 help / color / mirror / Atom feed
* [PATCH v1 0/9] target/i386: Fix Hygon vendor-specific CPU behavior
@ 2026-07-06  5:55 zhang_wei
  2026-07-06  5:55 ` [PATCH v1 1/9] target/i386: Sync AMD CPUID aliases for Hygon zhang_wei
                   ` (9 more replies)
  0 siblings, 10 replies; 20+ messages in thread
From: zhang_wei @ 2026-07-06  5:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: kvm, Michael S . Tsirkin, Paolo Bonzini, Marcelo Tosatti,
	Tina Zhang

From: Tina Zhang <zhang_wei@hygon.cn>

Hygon Dhyana uses the HygonGenuine vendor string, but a number of
guest-visible and KVM-facing interfaces follow AMD-compatible behavior.
QEMU currently keys several of these paths only on AuthenticAMD, so Hygon
guests can see vendor-inconsistent CPUID/MSR state or use the wrong KVM
PMU/MCE handling paths.

This series makes those checks explicit for Hygon where appropriate.

Guest-visible CPU ABI changes are gated by the new
x-hygon-vendor-abi-fixes property.  The property defaults to true for new
machine types and is disabled for pc-11.0 and older, so existing machine
types keep their previous Hygon ABI for migration compatibility.

The KVM injected-MCE and PMU path changes are not CPUID model table
changes.  They make QEMU use the AMD-compatible runtime handling that
Linux/KVM already uses for Hygon.

The series covers:

  * AMD CPUID[0x80000001].EDX aliases for Hygon
  * hiding Intel cache CPUID leaves 2 and 4 for Hygon
  * hiding IA32_ARCH_CAPABILITIES for Hygon unless old ABI requires it
  * AMD MCE status encoding for Hygon memory-failure injection
  * AMD PMU MSR setup/save/restore paths for Hygon
  * disabling Intel-style MCA broadcast for Hygon injected MCEs
  * AMD IOMMU HT GPA hole layout for Hygon on new machine types
  * AMD legacy cache fallback for Hygon when legacy-cache=on
  * AMD-shaped default ucode-rev value for Hygon

Tests were added for the Dhyana CPUID/ucode compatibility behavior and
for the Hygon HT GPA hole memory-layout case.

Tested with:

  ninja -C build

  build/pyvenv/bin/meson test -C build --print-errorlogs \
      qemu:qtest-i386/test-x86-cpuid-compat \
      qemu:qtest-x86_64/test-x86-cpuid-compat \
      qemu:func-x86_64-mem_addr_space

Tina Zhang (9):
  target/i386: Sync AMD CPUID aliases for Hygon
  target/i386: Hide Intel cache CPUID leaves for Hygon
  target/i386: Hide ARCH_CAPABILITIES for Hygon
  target/i386/kvm: Use AMD MCE status encoding for Hygon
  target/i386/kvm: Use AMD PMU MSR paths for Hygon
  target/i386: Do not broadcast injected MCEs for Hygon
  hw/i386: Apply AMD IOMMU HT GPA hole to Hygon
  target/i386: Use AMD legacy cache fallback for Hygon
  target/i386: Use AMD ucode-rev default for Hygon

 hw/i386/pc.c                                  | 22 +++--
 target/i386/cpu.c                             | 86 +++++++++++++----
 target/i386/cpu.h                             | 12 +++
 target/i386/helper.c                          |  6 +-
 target/i386/kvm/kvm.c                         | 36 +++++--
 .../functional/x86_64/test_mem_addr_space.py  | 36 +++++++
 tests/qtest/test-x86-cpuid-compat.c           | 95 +++++++++++++++++++
 7 files changed, 263 insertions(+), 30 deletions(-)

-- 
2.43.7

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH v1 1/9] target/i386: Sync AMD CPUID aliases for Hygon
  2026-07-06  5:55 [PATCH v1 0/9] target/i386: Fix Hygon vendor-specific CPU behavior zhang_wei
@ 2026-07-06  5:55 ` zhang_wei
  2026-07-31  7:02   ` Zhao Liu
  2026-07-06  5:55 ` [PATCH v1 2/9] target/i386: Hide Intel cache CPUID leaves " zhang_wei
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 20+ messages in thread
From: zhang_wei @ 2026-07-06  5:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: kvm, Michael S . Tsirkin, Paolo Bonzini, Marcelo Tosatti,
	Tina Zhang

From: Tina Zhang <zhang_wei@open-hieco.net>

AMD defines CPUID[0x80000001].EDX bits as aliases for a subset of
CPUID[1].EDX.  QEMU currently synchronizes those aliases only when the
guest CPU vendor is AuthenticAMD.

Hygon Dhyana uses the HygonGenuine vendor string, but implements the
same AMD-compatible extended CPUID feature aliases.  This can leave QEMU
advertising a feature in CPUID[1].EDX while the matching extended alias
in CPUID[0x80000001].EDX stays clear, for example MMX.  Windows guests
with Hyper-V enabled can fail to start the Hyper-V hypervisor when
exposed to that inconsistent CPUID state.

Apply the alias synchronization to Hygon CPUs as well.  Gate the new
behavior with x-hygon-vendor-abi-fixes and disable it for pc-11.0 and
older machine types, because the CPUID result is guest-visible ABI and
must remain migration-compatible.

Add qtest coverage for the Dhyana model, including the
Hygon vendor ABI fixes property.

Signed-off-by: Tina Zhang <zhang_wei@open-hieco.net>
---
 hw/i386/pc.c                        |  4 +-
 target/i386/cpu.c                   | 23 +++++++--
 target/i386/cpu.h                   | 12 +++++
 tests/qtest/test-x86-cpuid-compat.c | 76 +++++++++++++++++++++++++++++
 4 files changed, 111 insertions(+), 4 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 73a625327c..11dade642f 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -73,7 +73,9 @@
 #include "hw/xen/xen-bus.h"
 #endif
 
-GlobalProperty pc_compat_11_0[] = {};
+GlobalProperty pc_compat_11_0[] = {
+    { TYPE_X86_CPU, "x-hygon-vendor-abi-fixes", "false" },
+};
 const size_t pc_compat_11_0_len = G_N_ELEMENTS(pc_compat_11_0);
 
 GlobalProperty pc_compat_10_2[] = {};
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 5805d33ab9..32b8bc9ebd 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -8608,6 +8608,20 @@ uint32_t cpu_x86_virtual_addr_width(CPUX86State *env)
     }
 }
 
+/*
+ * AMD CPUs define CPUID[0x80000001].EDX aliases for selected CPUID[1].EDX
+ * feature bits.  Hygon Dhyana follows the same extended feature alias rules.
+ * Enable the corrected Hygon behavior only for machine types where Hygon
+ * vendor ABI fixes are on.
+ */
+static bool x86_cpu_has_amd_cpuid_aliases(const X86CPU *cpu)
+{
+    const CPUX86State *env = &cpu->env;
+
+    return IS_AMD_CPU(env) ||
+           (cpu->hygon_vendor_abi_fixes && IS_HYGON_CPU(env));
+}
+
 void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
                    uint32_t *eax, uint32_t *ebx,
                    uint32_t *ecx, uint32_t *edx)
@@ -10147,10 +10161,11 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
         }
     }
 
-    /* On AMD CPUs, some CPUID[8000_0001].EDX bits must match the bits on
-     * CPUID[1].EDX.
+    /*
+     * CPUs that use AMD-compatible extended CPUID aliases must keep selected
+     * CPUID[0x80000001].EDX bits synchronized with CPUID[1].EDX.
      */
-    if (IS_AMD_CPU(env)) {
+    if (x86_cpu_has_amd_cpuid_aliases(cpu)) {
         env->features[FEAT_8000_0001_EDX] &= ~CPUID_EXT2_AMD_ALIASES;
         env->features[FEAT_8000_0001_EDX] |= (env->features[FEAT_1_EDX]
            & CPUID_EXT2_AMD_ALIASES);
@@ -10810,6 +10825,8 @@ static const Property x86_cpu_properties[] = {
     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("x-vendor-cpuid-only-v2", X86CPU, vendor_cpuid_only_v2, true),
+    DEFINE_PROP_BOOL("x-hygon-vendor-abi-fixes", X86CPU,
+                     hygon_vendor_abi_fixes, true),
     DEFINE_PROP_BOOL("x-amd-topoext-features-only", X86CPU, amd_topoext_features_only, true),
     DEFINE_PROP_BOOL("lmce", X86CPU, enable_lmce, false),
     DEFINE_PROP_BOOL("l3-cache", X86CPU, enable_l3_cache, true),
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index e6a197602d..3e75b03609 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1281,6 +1281,9 @@ uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w);
 #define CPUID_VENDOR_ZHAOXIN1   "CentaurHauls"
 #define CPUID_VENDOR_ZHAOXIN2   "  Shanghai  "
 
+#define CPUID_VENDOR_HYGON_1  0x6f677948 /* "Hygo" */
+#define CPUID_VENDOR_HYGON_2  0x6e65476e /* "nGen" */
+#define CPUID_VENDOR_HYGON_3  0x656e6975 /* "uine" */
 #define CPUID_VENDOR_HYGON    "HygonGenuine"
 
 #define IS_INTEL_CPU(env) ((env)->cpuid_vendor1 == CPUID_VENDOR_INTEL_1 && \
@@ -1289,6 +1292,9 @@ uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w);
 #define IS_AMD_CPU(env) ((env)->cpuid_vendor1 == CPUID_VENDOR_AMD_1 && \
                          (env)->cpuid_vendor2 == CPUID_VENDOR_AMD_2 && \
                          (env)->cpuid_vendor3 == CPUID_VENDOR_AMD_3)
+#define IS_HYGON_CPU(env) ((env)->cpuid_vendor1 == CPUID_VENDOR_HYGON_1 && \
+                           (env)->cpuid_vendor2 == CPUID_VENDOR_HYGON_2 && \
+                           (env)->cpuid_vendor3 == CPUID_VENDOR_HYGON_3)
 #define IS_ZHAOXIN1_CPU(env) \
     ((env)->cpuid_vendor1 == CPUID_VENDOR_ZHAOXIN1_1 && \
      (env)->cpuid_vendor2 == CPUID_VENDOR_ZHAOXIN1_2 && \
@@ -2461,6 +2467,12 @@ struct ArchCPU {
      */
     bool vendor_cpuid_only_v2;
 
+    /*
+     * Enable Hygon vendor ABI fixes for new machine types.  Old machine
+     * types disable this to preserve guest-visible CPU ABI.
+     */
+    bool hygon_vendor_abi_fixes;
+
     /* Only advertise TOPOEXT features that AMD defines */
     bool amd_topoext_features_only;
 
diff --git a/tests/qtest/test-x86-cpuid-compat.c b/tests/qtest/test-x86-cpuid-compat.c
index 17c0965827..b7f8834052 100644
--- a/tests/qtest/test-x86-cpuid-compat.c
+++ b/tests/qtest/test-x86-cpuid-compat.c
@@ -113,6 +113,21 @@ typedef struct FeatureTestArgs {
     bool expected_value;
 } FeatureTestArgs;
 
+typedef struct BoolPropTestArgs {
+    /* Test name */
+    const char *name;
+    /* CPU type */
+    const char *cpu;
+    /* CPU features (may be NULL) */
+    const char *cpufeat;
+    /* machine type (may be NULL to use default machine) */
+    const char *machine;
+    /* CPU property to read */
+    const char *property;
+    /* expected value of the property */
+    bool expected_value;
+} BoolPropTestArgs;
+
 /* Get the value for a feature word in a X86CPUFeatureWordInfo list */
 static uint32_t get_feature_word(QList *features, uint32_t eax, uint32_t ecx,
                                  const char *reg)
@@ -170,6 +185,38 @@ static void test_feature_flag(const void *data)
     g_free(cmdline);
 }
 
+static void test_bool_prop(const void *data)
+{
+    const BoolPropTestArgs *args = data;
+    char *cmdline;
+    char *save;
+    char *path;
+    bool value;
+
+    cmdline = g_strdup_printf("-cpu %s", args->cpu);
+
+    if (args->cpufeat) {
+        save = cmdline;
+        cmdline = g_strdup_printf("%s,%s", cmdline, args->cpufeat);
+        g_free(save);
+    }
+    if (args->machine) {
+        save = cmdline;
+        cmdline = g_strdup_printf("-machine %s %s", args->machine, cmdline);
+        g_free(save);
+    }
+
+    qtest_start(cmdline);
+    path = get_cpu0_qom_path();
+    value = qom_get_bool(path, args->property);
+    qtest_end();
+
+    g_assert_cmpint(value, ==, args->expected_value);
+
+    g_free(path);
+    g_free(cmdline);
+}
+
 static void test_plus_minus_subprocess(void)
 {
     char *path;
@@ -407,6 +454,28 @@ static const FeatureTestArgs feature_tests[] = {
         "max", "mmx=off",
         1, 0, "EDX", 23, false,
     },
+    {
+        "x86/cpuid/features/dhyana/ext-mmx",
+        "Dhyana", NULL,
+        0x80000001, 0, "EDX", 23, true,
+    },
+    {
+        "x86/cpuid/features/dhyana/ext-mmx/compat-off",
+        "Dhyana", "x-hygon-vendor-abi-fixes=off",
+        0x80000001, 0, "EDX", 23, false,
+    },
+};
+
+static const BoolPropTestArgs bool_prop_tests[] = {
+    {
+        "x86/cpuid/props/dhyana/hygon-vendor-abi-fixes/default",
+        "Dhyana", NULL, NULL, "x-hygon-vendor-abi-fixes", true,
+    },
+    {
+        "x86/cpuid/props/dhyana/hygon-vendor-abi-fixes/pc-i440fx-11.0",
+        "Dhyana", NULL, "pc-i440fx-11.0",
+        "x-hygon-vendor-abi-fixes", false,
+    },
 };
 
 int main(int argc, char **argv)
@@ -433,6 +502,13 @@ int main(int argc, char **argv)
         qtest_add_data_func(feature_tests[i].name,
                             &feature_tests[i], test_feature_flag);
     }
+    for (int i = 0; i < ARRAY_SIZE(bool_prop_tests); i++) {
+        if (!qtest_has_cpu_model(bool_prop_tests[i].cpu)) {
+            continue;
+        }
+        qtest_add_data_func(bool_prop_tests[i].name,
+                            &bool_prop_tests[i], test_bool_prop);
+    }
 
     return g_test_run();
 }
-- 
2.43.7


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v1 2/9] target/i386: Hide Intel cache CPUID leaves for Hygon
  2026-07-06  5:55 [PATCH v1 0/9] target/i386: Fix Hygon vendor-specific CPU behavior zhang_wei
  2026-07-06  5:55 ` [PATCH v1 1/9] target/i386: Sync AMD CPUID aliases for Hygon zhang_wei
@ 2026-07-06  5:55 ` zhang_wei
  2026-07-31  7:03   ` Zhao Liu
  2026-07-06  5:55 ` [PATCH v1 3/9] target/i386: Hide ARCH_CAPABILITIES " zhang_wei
                   ` (7 subsequent siblings)
  9 siblings, 1 reply; 20+ messages in thread
From: zhang_wei @ 2026-07-06  5:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: kvm, Michael S . Tsirkin, Paolo Bonzini, Marcelo Tosatti,
	Tina Zhang

From: Tina Zhang <zhang_wei@open-hieco.net>

When x-vendor-cpuid-only is enabled, QEMU suppresses CPUID leaves 2
and 4 for AuthenticAMD CPUs because those leaves describe Intel cache
information.  Hygon Dhyana uses the HygonGenuine vendor string, so it
currently skips that filtering and can expose Intel cache leaves together
with AMD/Hygon extended cache leaves.

That is inconsistent guest-visible CPUID: Hygon Dhyana provides cache
information through the extended cache leaves, so it should not also
advertise the Intel cache descriptor and deterministic cache parameter
leaves.

Apply the same leaf 2 and leaf 4 filtering to Hygon CPUs when Hygon
vendor ABI fixes are enabled.  The property keeps the old CPUID output
for pc-11.0 and older machine types.

Signed-off-by: Tina Zhang <zhang_wei@open-hieco.net>
---
 target/i386/cpu.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 32b8bc9ebd..f0cad38c94 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -8622,6 +8622,21 @@ static bool x86_cpu_has_amd_cpuid_aliases(const X86CPU *cpu)
            (cpu->hygon_vendor_abi_fixes && IS_HYGON_CPU(env));
 }
 
+/*
+ * CPUID leaves 2 and 4 describe Intel cache information.  AMD CPUs use
+ * extended cache leaves instead, and Hygon Dhyana follows that AMD/Hygon
+ * convention.  Enable the corrected Hygon behavior only for machine types
+ * where Hygon vendor ABI fixes are on.
+ */
+static bool x86_cpu_filter_intel_cache_leaves(const X86CPU *cpu)
+{
+    const CPUX86State *env = &cpu->env;
+
+    return cpu->vendor_cpuid_only &&
+           (IS_AMD_CPU(env) ||
+            (cpu->hygon_vendor_abi_fixes && IS_HYGON_CPU(env)));
+}
+
 void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
                    uint32_t *eax, uint32_t *ebx,
                    uint32_t *ecx, uint32_t *edx)
@@ -8707,7 +8722,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
         if (cpu->cache_info_passthrough) {
             x86_cpu_get_cache_cpuid(index, 0, eax, ebx, ecx, edx);
             break;
-        } else if (cpu->vendor_cpuid_only && IS_AMD_CPU(env)) {
+        } else if (x86_cpu_filter_intel_cache_leaves(cpu)) {
             *eax = *ebx = *ecx = *edx = 0;
             break;
         }
@@ -8743,7 +8758,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
                                 CPU_TOPOLOGY_LEVEL_SOCKET), 4095) << 14;
                 }
             }
-        } else if (cpu->vendor_cpuid_only && IS_AMD_CPU(env)) {
+        } else if (x86_cpu_filter_intel_cache_leaves(cpu)) {
             *eax = *ebx = *ecx = *edx = 0;
         } else {
             *eax = 0;
-- 
2.43.7


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v1 3/9] target/i386: Hide ARCH_CAPABILITIES for Hygon
  2026-07-06  5:55 [PATCH v1 0/9] target/i386: Fix Hygon vendor-specific CPU behavior zhang_wei
  2026-07-06  5:55 ` [PATCH v1 1/9] target/i386: Sync AMD CPUID aliases for Hygon zhang_wei
  2026-07-06  5:55 ` [PATCH v1 2/9] target/i386: Hide Intel cache CPUID leaves " zhang_wei
@ 2026-07-06  5:55 ` zhang_wei
  2026-07-31  7:05   ` Zhao Liu
  2026-07-06  5:55 ` [PATCH v1 4/9] target/i386/kvm: Use AMD MCE status encoding " zhang_wei
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 20+ messages in thread
From: zhang_wei @ 2026-07-06  5:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: kvm, Michael S . Tsirkin, Paolo Bonzini, Marcelo Tosatti,
	Tina Zhang

From: Tina Zhang <zhang_wei@open-hieco.net>

IA32_ARCH_CAPABILITIES is an Intel-defined MSR.  KVM can synthesize the
CPUID bit and read-only MSR for non-Intel guests, and QEMU already hides
that interface for AMD CPU models because Windows may not expect it on
AMD-compatible CPUs.

Hygon Dhyana uses the HygonGenuine vendor string, so it currently skips
that AMD filter.  If arch-capabilities=on is requested, QEMU can expose
CPUID.7.0.EDX[ARCH_CAPABILITIES] and the associated MSR feature word to
a Hygon guest.

That creates a vendor-inconsistent CPU ABI: the guest sees an
AMD-compatible vendor and cache/topology interface, but also sees an
Intel-specific architectural capabilities MSR.  Guests that choose CPU
mitigation or feature paths from the vendor can mis-handle that
combination; Windows is known to be sensitive to ARCH_CAPABILITIES on
AMD-compatible CPUs.

Apply the same ARCH_CAPABILITIES hiding rule to Hygon CPUs when Hygon
vendor ABI fixes are enabled.  Keep arch_cap_always_on as the migration
escape hatch, and keep the old Hygon CPUID/MSR output for pc-11.0 and
older machine types via x-hygon-vendor-abi-fixes=false.

Signed-off-by: Tina Zhang <zhang_wei@open-hieco.net>
---
 target/i386/cpu.c | 33 ++++++++++++++++++++++++---------
 1 file changed, 24 insertions(+), 9 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index f0cad38c94..47f48f4a96 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -8209,6 +8209,8 @@ static uint8_t x86_cpu_get_host_avx10_version(void)
     return ebx & 0xff;
 }
 
+static bool x86_cpu_should_hide_arch_capabilities(const X86CPU *cpu);
+
 uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w)
 {
     FeatureWordInfo *wi = &feature_word_info[w];
@@ -8294,15 +8296,7 @@ uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w)
         break;
 
     case FEAT_7_0_EDX:
-        /*
-         * Windows does not like ARCH_CAPABILITIES on AMD machines at all.
-         * Do not show the fake ARCH_CAPABILITIES MSR that KVM sets up,
-         * except if needed for migration.
-         *
-         * When arch_cap_always_on is removed, this tweak can move to
-         * kvm_arch_get_supported_cpuid.
-         */
-        if (cpu && IS_AMD_CPU(&cpu->env) && !cpu->arch_cap_always_on) {
+        if (cpu && x86_cpu_should_hide_arch_capabilities(cpu)) {
             unavail = CPUID_7_0_EDX_ARCH_CAPABILITIES;
         }
         break;
@@ -8608,6 +8602,27 @@ uint32_t cpu_x86_virtual_addr_width(CPUX86State *env)
     }
 }
 
+/*
+ * Windows does not like ARCH_CAPABILITIES on AMD machines at all.
+ * Do not show the fake ARCH_CAPABILITIES MSR that KVM sets up,
+ * except if needed for migration.  Apply the same rule to Hygon CPUs when
+ * Hygon vendor ABI fixes are enabled.
+ *
+ * When arch_cap_always_on is removed, this tweak can move to
+ * kvm_arch_get_supported_cpuid.
+ */
+static bool x86_cpu_should_hide_arch_capabilities(const X86CPU *cpu)
+{
+    const CPUX86State *env = &cpu->env;
+
+    if (cpu->arch_cap_always_on) {
+        return false;
+    }
+
+    return IS_AMD_CPU(env) ||
+           (cpu->hygon_vendor_abi_fixes && IS_HYGON_CPU(env));
+}
+
 /*
  * AMD CPUs define CPUID[0x80000001].EDX aliases for selected CPUID[1].EDX
  * feature bits.  Hygon Dhyana follows the same extended feature alias rules.
-- 
2.43.7


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v1 4/9] target/i386/kvm: Use AMD MCE status encoding for Hygon
  2026-07-06  5:55 [PATCH v1 0/9] target/i386: Fix Hygon vendor-specific CPU behavior zhang_wei
                   ` (2 preceding siblings ...)
  2026-07-06  5:55 ` [PATCH v1 3/9] target/i386: Hide ARCH_CAPABILITIES " zhang_wei
@ 2026-07-06  5:55 ` zhang_wei
  2026-07-31  7:06   ` Zhao Liu
  2026-07-06  5:55 ` [PATCH v1 5/9] target/i386/kvm: Use AMD PMU MSR paths " zhang_wei
                   ` (5 subsequent siblings)
  9 siblings, 1 reply; 20+ messages in thread
From: zhang_wei @ 2026-07-06  5:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: kvm, Michael S . Tsirkin, Paolo Bonzini, Marcelo Tosatti,
	Tina Zhang

From: Tina Zhang <zhang_wei@open-hieco.net>

QEMU's KVM memory-failure injection path builds synthetic MCI_STATUS
records for the guest CPU.  The status encoding is vendor-specific:
Intel-style records use bits such as MCI_STATUS_S and MCI_STATUS_AR for
action-required events, while the AMD path uses the AMD memory-failure
encoding.

Today QEMU selects the AMD status encoding only for AuthenticAMD guests.
Hygon guests therefore get Intel-style injected status bits, including
MCI_STATUS_S and MCI_STATUS_AR for action-required events, and a
non-deferred action-optional record.

Use the AMD injected-memory-failure MCE status encoding for Hygon guests
as well.  This does not depend on Hygon exposing CPUID 0x80000007.EBX
recovery features such as SUCCOR, and it does not advertise any new
recovery capability.  The change is limited to QEMU's synthetic KVM
memory-failure MCE status; it does not change CPUID, MCE bank state, or
migrated CPU state.

Signed-off-by: Tina Zhang <zhang_wei@open-hieco.net>
---
 target/i386/kvm/kvm.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index 64cc421abe..8e2bfbbe1d 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -698,6 +698,15 @@ static int kvm_get_mce_cap_supported(KVMState *s, uint64_t *mce_cap,
     return kvm_ioctl(s, KVM_X86_GET_MCE_CAP_SUPPORTED, mce_cap);
 }
 
+/*
+ * Use AMD-style MCE status records for QEMU-injected memory failures on
+ * AMD and Hygon CPUs.
+ */
+static bool kvm_mce_inject_uses_amd_status(const CPUX86State *env)
+{
+    return IS_AMD_CPU(env) || IS_HYGON_CPU(env);
+}
+
 static void kvm_mce_inject(X86CPU *cpu, hwaddr paddr, int code)
 {
     CPUState *cs = CPU(cpu);
@@ -707,7 +716,7 @@ static void kvm_mce_inject(X86CPU *cpu, hwaddr paddr, int code)
     uint64_t mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV;
     int flags = 0;
 
-    if (!IS_AMD_CPU(env)) {
+    if (!kvm_mce_inject_uses_amd_status(env)) {
         status |= MCI_STATUS_S | MCI_STATUS_UC;
         if (code == BUS_MCEERR_AR) {
             status |= MCI_STATUS_AR | 0x134;
-- 
2.43.7


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v1 5/9] target/i386/kvm: Use AMD PMU MSR paths for Hygon
  2026-07-06  5:55 [PATCH v1 0/9] target/i386: Fix Hygon vendor-specific CPU behavior zhang_wei
                   ` (3 preceding siblings ...)
  2026-07-06  5:55 ` [PATCH v1 4/9] target/i386/kvm: Use AMD MCE status encoding " zhang_wei
@ 2026-07-06  5:55 ` zhang_wei
  2026-07-31  5:55   ` Zhao Liu
  2026-07-06  5:55 ` [PATCH v1 6/9] target/i386: Do not broadcast injected MCEs " zhang_wei
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 20+ messages in thread
From: zhang_wei @ 2026-07-06  5:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: kvm, Michael S . Tsirkin, Paolo Bonzini, Marcelo Tosatti,
	Tina Zhang

From: Tina Zhang <zhang_wei@open-hieco.net>

On SVM, KVM uses the AMD PMU implementation and AMD PMU CPUID/MSR
layout.  Hygon guests that enable PMU and request AMD PMU CPUID
features such as perfctr-core need QEMU's KVM PMU setup and MSR state
paths to use that layout too.

The relevant QEMU KVM PMU paths are currently restricted to
AuthenticAMD guests: host/guest PMU compatibility checks, AMD PMU
information initialization, and AMD PMU MSR save/restore.  As a result,
a Hygon Dhyana guest can be rejected as unsupported because the guest
vendor is HygonGenuine rather than AuthenticAMD.  If the VM continues,
QEMU still skips AMD PMU setup and the AMD PMU MSR get/put paths.

Treat Hygon as using the AMD PMU CPUID/MSR layout for these KVM PMU
paths.  Because the PMU MSR layout is shared, accept both AMD and Hygon
hosts for guests using that layout.  This intentionally allows the PMU
compatibility check to pass for AMD-host/Hygon-guest and
Hygon-host/AMD-guest combinations.

This does not enable PMU, perfctr-core, or perfmon-v2 by default for the
Dhyana CPU model.  On backward migration to older QEMU, Hygon PMU MSR
state may still be dropped because older QEMU did not write that state
back through the AMD PMU MSR KVM paths for Hygon guests.

Signed-off-by: Tina Zhang <zhang_wei@open-hieco.net>
---
 target/i386/kvm/kvm.c | 25 ++++++++++++++++++++-----
 1 file changed, 20 insertions(+), 5 deletions(-)

diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index 8e2bfbbe1d..215e0c8f03 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -2175,6 +2175,21 @@ static void kvm_init_pmu_info_amd(struct kvm_cpuid2 *cpuid, X86CPU *cpu)
     }
 }
 
+/*
+ * KVM exposes the AMD PMU CPUID/MSR layout for Hygon guests, so QEMU must
+ * use the AMD PMU setup and MSR state paths for Hygon too.
+ */
+static bool kvm_pmu_uses_amd_msrs(const CPUX86State *env)
+{
+    return IS_AMD_CPU(env) || IS_HYGON_CPU(env);
+}
+
+static bool host_cpu_uses_amd_pmu_msrs(const char *host_vendor)
+{
+    return g_str_equal(host_vendor, CPUID_VENDOR_AMD) ||
+           g_str_equal(host_vendor, CPUID_VENDOR_HYGON);
+}
+
 static bool is_host_compat_vendor(CPUX86State *env)
 {
     char host_vendor[CPUID_VENDOR_SZ + 1];
@@ -2191,8 +2206,8 @@ static bool is_host_compat_vendor(CPUX86State *env)
         return true;
     }
 
-    return g_str_equal(host_vendor, CPUID_VENDOR_AMD) &&
-           IS_AMD_CPU(env);
+    return host_cpu_uses_amd_pmu_msrs(host_vendor) &&
+           kvm_pmu_uses_amd_msrs(env);
 }
 
 static void kvm_init_pmu_info(struct kvm_cpuid2 *cpuid, X86CPU *cpu)
@@ -2222,7 +2237,7 @@ static void kvm_init_pmu_info(struct kvm_cpuid2 *cpuid, X86CPU *cpu)
 
     if (IS_INTEL_CPU(env) || IS_ZHAOXIN_CPU(env)) {
         kvm_init_pmu_info_intel(cpuid);
-    } else if (IS_AMD_CPU(env)) {
+    } else if (kvm_pmu_uses_amd_msrs(env)) {
         kvm_init_pmu_info_amd(cpuid, cpu);
     }
 }
@@ -4309,7 +4324,7 @@ static int kvm_put_msrs(X86CPU *cpu, KvmPutState level)
             }
         }
 
-        if (IS_AMD_CPU(env) && pmu_version > 0) {
+        if (kvm_pmu_uses_amd_msrs(env) && pmu_version > 0) {
             uint32_t sel_base = MSR_K7_EVNTSEL0;
             uint32_t ctr_base = MSR_K7_PERFCTR0;
             /*
@@ -4871,7 +4886,7 @@ static int kvm_get_msrs(X86CPU *cpu)
         }
     }
 
-    if (IS_AMD_CPU(env) && pmu_version > 0) {
+    if (kvm_pmu_uses_amd_msrs(env) && pmu_version > 0) {
         uint32_t sel_base = MSR_K7_EVNTSEL0;
         uint32_t ctr_base = MSR_K7_PERFCTR0;
         /*
-- 
2.43.7


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v1 6/9] target/i386: Do not broadcast injected MCEs for Hygon
  2026-07-06  5:55 [PATCH v1 0/9] target/i386: Fix Hygon vendor-specific CPU behavior zhang_wei
                   ` (4 preceding siblings ...)
  2026-07-06  5:55 ` [PATCH v1 5/9] target/i386/kvm: Use AMD PMU MSR paths " zhang_wei
@ 2026-07-06  5:55 ` zhang_wei
  2026-07-06  5:55 ` [PATCH v1 7/9] hw/i386: Apply AMD IOMMU HT GPA hole to Hygon zhang_wei
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 20+ messages in thread
From: zhang_wei @ 2026-07-06  5:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: kvm, Michael S . Tsirkin, Paolo Bonzini, Marcelo Tosatti,
	Tina Zhang

From: Tina Zhang <zhang_wei@open-hieco.net>

cpu_x86_support_mca_broadcast() excludes AMD CPUs because QEMU handles
AMD injected MCEs as local machine checks, not as Intel-style broadcast
MCEs.  Hygon Dhyana missed that exclusion: it is not an AMD vendor CPU
and its family is greater than 6, so QEMU reported MCA broadcast
support.

This affects QEMU's synthetic MCE injection paths.  KVM memory-failure
injection uses this helper to decide whether to set MCE_INJECT_BROADCAST.
HMP 'mce -b' uses it to decide whether a broadcast request is valid.
With a multi-vCPU Dhyana guest, QEMU could fan out an injected MCE to
secondary vCPUs and populate extra bank records.

Linux routes Hygon through the AMD MCE feature initialization path and
does not use Intel/Zhaoxin LMCE broadcast handling for Hygon.  Do not
advertise Intel-style MCA broadcast support for Hygon in QEMU's injected
MCE paths.

This is limited to the MCE broadcast-support decision.  It does not claim
that all Hygon MCE/MCA behavior is identical to AMD.

Signed-off-by: Tina Zhang <zhang_wei@open-hieco.net>
---
 target/i386/helper.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/target/i386/helper.c b/target/i386/helper.c
index 6836214162..0e71b52f13 100644
--- a/target/i386/helper.c
+++ b/target/i386/helper.c
@@ -95,7 +95,11 @@ int cpu_x86_support_mca_broadcast(CPUX86State *env)
     int family = 0;
     int model = 0;
 
-    if (IS_AMD_CPU(env)) {
+    /*
+     * Injected AMD and Hygon MCEs follow the local MCE model; do not use
+     * Intel-style MCA broadcast for these vendors.
+     */
+    if (IS_AMD_CPU(env) || IS_HYGON_CPU(env)) {
         return 0;
     }
 
-- 
2.43.7


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v1 7/9] hw/i386: Apply AMD IOMMU HT GPA hole to Hygon
  2026-07-06  5:55 [PATCH v1 0/9] target/i386: Fix Hygon vendor-specific CPU behavior zhang_wei
                   ` (5 preceding siblings ...)
  2026-07-06  5:55 ` [PATCH v1 6/9] target/i386: Do not broadcast injected MCEs " zhang_wei
@ 2026-07-06  5:55 ` zhang_wei
  2026-07-06  5:55 ` [PATCH v1 8/9] target/i386: Use AMD legacy cache fallback for Hygon zhang_wei
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 20+ messages in thread
From: zhang_wei @ 2026-07-06  5:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: kvm, Michael S . Tsirkin, Paolo Bonzini, Marcelo Tosatti,
	Tina Zhang, Yanjing Zhou

From: Tina Zhang <zhang_wei@open-hieco.net>

QEMU reserves the HyperTransport special GPA range near the 1 TiB
boundary only for AMD vCPUs.  That range is reserved by the AMD IOMMU
GPA layout, and Linux validates VFIO DMA mappings against IOMMU reserved
regions.

If guest RAM, hotplug address space, or 64-bit MMIO windows overlap the
range, VFIO DMA_MAP can fail with -EINVAL or the IOMMU can report faults
such as INVALID_DEVICE_REQUEST.

The Linux AMD IOMMU driver also handles Hygon systems and reserves the HT
range unless the IOMMU advertises FEATURE_HT_RANGE_IGNORE.  Treat Hygon
vCPUs as using the same AMD IOMMU HT GPA-hole layout in QEMU's PC memory
layout code.

This changes the guest physical memory map for Hygon, so gate the new
Hygon behavior with x-hygon-vendor-abi-fixes.  pc-11.0 and older machine
types keep the previous Hygon memory layout, while the existing
enforce_amd_1tb_hole compatibility keeps the old AMD behavior for pc/q35
<= 7.0.

Add functional coverage for Dhyana on the current q35 machine type and
for the pc-q35-11.0 compatibility case.

Signed-off-by: Yanjing Zhou <zhouyanjing@hygon.cn>
Signed-off-by: Tina Zhang <zhang_wei@open-hieco.net>
---
 hw/i386/pc.c                                  | 18 +++++++---
 .../functional/x86_64/test_mem_addr_space.py  | 36 +++++++++++++++++++
 2 files changed, 49 insertions(+), 5 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 11dade642f..4c029d6a4b 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -735,6 +735,12 @@ static hwaddr pc_max_used_gpa(PCMachineState *pcms, uint64_t pci_hole64_size)
 #define AMD_ABOVE_1TB_START  (AMD_HT_END + 1)
 #define AMD_HT_SIZE          (AMD_ABOVE_1TB_START - AMD_HT_START)
 
+static bool x86_cpu_has_amd_iommu_ht_gpa_hole(const X86CPU *cpu)
+{
+    return IS_AMD_CPU(&cpu->env) ||
+           (IS_HYGON_CPU(&cpu->env) && cpu->hygon_vendor_abi_fixes);
+}
+
 void pc_memory_init(PCMachineState *pcms,
                     MemoryRegion *system_memory,
                     MemoryRegion *rom_memory,
@@ -759,12 +765,14 @@ void pc_memory_init(PCMachineState *pcms,
     linux_boot = (machine->kernel_filename != NULL);
 
     /*
-     * The HyperTransport range close to the 1T boundary is unique to AMD
-     * hosts with IOMMUs enabled. Restrict the ram-above-4g relocation
-     * to above 1T to AMD vCPUs only. @enforce_amd_1tb_hole is only false in
-     * older machine types (<= 7.0) for compatibility purposes.
+     * The HyperTransport range close to the 1T boundary is reserved by the
+     * AMD IOMMU GPA layout.  Apply the ram-above-4g relocation only to vCPUs
+     * that use that layout. @enforce_amd_1tb_hole preserves older AMD
+     * machine types (<= 7.0), and x-hygon-vendor-abi-fixes preserves older
+     * Hygon machine types (<= 11.0).
      */
-    if (IS_AMD_CPU(&cpu->env) && pcmc->enforce_amd_1tb_hole) {
+    if (x86_cpu_has_amd_iommu_ht_gpa_hole(cpu) &&
+        pcmc->enforce_amd_1tb_hole) {
         /* Bail out if max possible address does not cross HT range */
         if (pc_max_used_gpa(pcms, pci_hole64_size) >= AMD_HT_START) {
             x86ms->above_4g_mem_start = AMD_ABOVE_1TB_START;
diff --git a/tests/functional/x86_64/test_mem_addr_space.py b/tests/functional/x86_64/test_mem_addr_space.py
index 61b4a190b4..e4b4aee008 100755
--- a/tests/functional/x86_64/test_mem_addr_space.py
+++ b/tests/functional/x86_64/test_mem_addr_space.py
@@ -208,6 +208,24 @@ def test_phybits_low_tcg_q35_71_amd(self):
         self.assertEqual(self.vm.exitcode(), 1, "QEMU exit code should be 1")
         self.assertRegex(self.vm.get_log(), r'phys-bits too low')
 
+    def test_phybits_low_tcg_q35_hygon(self):
+        """
+        Check that Dhyana on the default q35 machine follows the AMD IOMMU
+        HT reserved GPA range on new machine types.
+        """
+        self.ensure_64bit_binary()
+        self.set_machine('q35')
+        self.vm.add_args('-S', '-cpu', 'Dhyana,phys-bits=40',
+                         '-m', '512,slots=1,maxmem=976G',
+                         '-display', 'none',
+                         '-object', 'memory-backend-ram,id=mem1,size=1G',
+                         '-device', 'pc-dimm,id=vm0,memdev=mem1')
+        self.vm.set_qmp_monitor(enabled=False)
+        self.vm.launch()
+        self.vm.wait()
+        self.assertEqual(self.vm.exitcode(), 1, "QEMU exit code should be 1")
+        self.assertRegex(self.vm.get_log(), r'phys-bits too low')
+
     def test_phybits_ok_tcg_q35_70_amd(self):
         """
         Same as q35-7.0 AMD case except that here we check that QEMU can
@@ -225,6 +243,24 @@ def test_phybits_ok_tcg_q35_70_amd(self):
         self.vm.shutdown()
         self.assertNotRegex(self.vm.get_log(), r'phys-bits too low')
 
+    def test_phybits_ok_tcg_q35_110_hygon(self):
+        """
+        Same as the default q35 Dhyana case except that here we check that
+        the q35-11.0 compatibility setting keeps the old memory layout.
+        """
+        self.ensure_64bit_binary()
+        self.set_machine('pc-q35-11.0')
+        self.vm.add_args('-S', '-cpu', 'Dhyana,phys-bits=40',
+                         '-m', '512,slots=1,maxmem=976G',
+                         '-display', 'none',
+                         '-object', 'memory-backend-ram,id=mem1,size=1G',
+                         '-device', 'pc-dimm,id=vm0,memdev=mem1')
+        self.vm.set_qmp_monitor(enabled=False)
+        self.vm.launch()
+        time.sleep(self.DELAY_Q35_BOOT_SEQUENCE)
+        self.vm.shutdown()
+        self.assertNotRegex(self.vm.get_log(), r'phys-bits too low')
+
     def test_phybits_ok_tcg_q35_71_amd(self):
         """
         Same as q35-7.1 AMD case except that here we check that QEMU can
-- 
2.43.7


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v1 8/9] target/i386: Use AMD legacy cache fallback for Hygon
  2026-07-06  5:55 [PATCH v1 0/9] target/i386: Fix Hygon vendor-specific CPU behavior zhang_wei
                   ` (6 preceding siblings ...)
  2026-07-06  5:55 ` [PATCH v1 7/9] hw/i386: Apply AMD IOMMU HT GPA hole to Hygon zhang_wei
@ 2026-07-06  5:55 ` zhang_wei
  2026-07-31  7:08   ` Zhao Liu
  2026-07-06  5:55 ` [PATCH v1 9/9] target/i386: Use AMD ucode-rev default " zhang_wei
  2026-07-22 12:10 ` [PATCH v1 0/9] target/i386: Fix Hygon vendor-specific CPU behavior Tina Zhang
  9 siblings, 1 reply; 20+ messages in thread
From: zhang_wei @ 2026-07-06  5:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: kvm, Michael S . Tsirkin, Paolo Bonzini, Marcelo Tosatti,
	Tina Zhang

From: Tina Zhang <zhang_wei@open-hieco.net>

When legacy-cache=on, x86_cpu_realizefn() builds a hardcoded cache
model.  It selected the AMD legacy cache table only for CPUs with the
AuthenticAMD vendor ID.  Dhyana uses the HygonGenuine vendor ID, so this
explicit compatibility path fell back to QEMU's old Intel legacy cache
table.

The wrong table is visible through AMD extended cache leaves.  With the
Intel legacy table, Dhyana reports 32 KiB, 8-way L1 caches in CPUID
0x80000005 and a 4 MiB, 16-way L2 cache in CPUID 0x80000006.  Linux
uses the AMD/Hygon cache enumeration path for Hygon and reads these AMD
extended cache leaves.

Use the AMD legacy cache table for Hygon in this fallback path when the
new Hygon vendor ABI fixes are enabled.
Keep the old fallback for pc-11.0 and
older machine types through x-hygon-vendor-abi-fixes=false.

The default Dhyana model is unchanged because it provides EPYC cache_info
and therefore defaults legacy-cache to off.  The guest-visible change is
limited to users who explicitly configure legacy-cache=on on new machine
types.

Signed-off-by: Tina Zhang <zhang_wei@open-hieco.net>
---
 target/i386/cpu.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 47f48f4a96..279c9b3ae7 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -10342,7 +10342,8 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
             env->enable_legacy_vendor_cache = true;
         }
 
-        if (IS_AMD_CPU(env)) {
+        if (IS_AMD_CPU(env) ||
+            (IS_HYGON_CPU(env) && cpu->hygon_vendor_abi_fixes)) {
             env->cache_info = legacy_amd_cache_info;
         } else {
             env->cache_info = legacy_intel_cache_info;
-- 
2.43.7


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v1 9/9] target/i386: Use AMD ucode-rev default for Hygon
  2026-07-06  5:55 [PATCH v1 0/9] target/i386: Fix Hygon vendor-specific CPU behavior zhang_wei
                   ` (7 preceding siblings ...)
  2026-07-06  5:55 ` [PATCH v1 8/9] target/i386: Use AMD legacy cache fallback for Hygon zhang_wei
@ 2026-07-06  5:55 ` zhang_wei
  2026-07-22 12:10 ` [PATCH v1 0/9] target/i386: Fix Hygon vendor-specific CPU behavior Tina Zhang
  9 siblings, 0 replies; 20+ messages in thread
From: zhang_wei @ 2026-07-06  5:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: kvm, Michael S . Tsirkin, Paolo Bonzini, Marcelo Tosatti,
	Tina Zhang

From: Tina Zhang <zhang_wei@open-hieco.net>

QEMU currently gives named Hygon Dhyana CPUs the non-AMD default
ucode-rev value, 0x100000000.  That is the Intel/KVM-VMX-shaped
encoding, where the visible revision is in the high 32 bits.

Linux reads MSR 0x8b for Hygon CPUs through the AMD patch-level path,
using MSR_AMD64_PATCH_LEVEL and storing the low 32 bits as
cpuinfo_x86.microcode.  With the old QEMU default, a Dhyana guest sees
microcode revision 0.

Use the AMD/KVM-SVM-shaped default, 0x01000065, for Hygon on this
specific MSR 0x8b default path.  This does not route Hygon through AMD
microcode loading and does not claim that Hygon CPUs are otherwise
identical to AMD CPUs.

Preserve migration ABI through the Hygon vendor ABI fixes property.
pc-11.0 and older machine types leave it off, so they retain the previous
ucode-rev default.  Explicit
user-provided ucode-rev values still override the default.

Add qtest coverage for the new default, the compatibility cases, and an
explicit user override.

Signed-off-by: Tina Zhang <zhang_wei@open-hieco.net>
---
 target/i386/cpu.c                   |  8 ++++++--
 tests/qtest/test-x86-cpuid-compat.c | 19 +++++++++++++++++++
 2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 279c9b3ae7..af1e5f2857 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -10232,10 +10232,14 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
     if (cpu->ucode_rev == 0) {
         /*
          * The default is the same as KVM's. Note that this check
-         * needs to happen after the evenual setting of ucode_rev in
+         * needs to happen after the eventual setting of ucode_rev in
          * accel-specific code in cpu_exec_realizefn.
+         *
+         * Hygon uses the AMD patch-level MSR 0x8b encoding, where the visible
+         * microcode revision is in the low 32 bits.
          */
-        if (IS_AMD_CPU(env)) {
+        if (IS_AMD_CPU(env) ||
+            (IS_HYGON_CPU(env) && cpu->hygon_vendor_abi_fixes)) {
             cpu->ucode_rev = 0x01000065;
         } else {
             cpu->ucode_rev = 0x100000000ULL;
diff --git a/tests/qtest/test-x86-cpuid-compat.c b/tests/qtest/test-x86-cpuid-compat.c
index b7f8834052..06cbf35d76 100644
--- a/tests/qtest/test-x86-cpuid-compat.c
+++ b/tests/qtest/test-x86-cpuid-compat.c
@@ -404,6 +404,25 @@ static const CpuidTestArgs cpuid_tests[] = {
         "486", "xlevel2=0xC0000002,xstore=on",
         NULL, "xlevel2", 0xC0000002,
     },
+    {
+        "x86/cpuid/props/dhyana/ucode-rev/default",
+        "Dhyana", NULL, NULL, "ucode-rev", 0x01000065,
+    },
+    {
+        "x86/cpuid/props/dhyana/ucode-rev/compat-off",
+        "Dhyana", "x-hygon-vendor-abi-fixes=off", NULL,
+        "ucode-rev", 0x100000000LL,
+    },
+    {
+        "x86/cpuid/props/dhyana/ucode-rev/pc-i440fx-11.0",
+        "Dhyana", NULL, "pc-i440fx-11.0",
+        "ucode-rev", 0x100000000LL,
+    },
+    {
+        "x86/cpuid/props/dhyana/ucode-rev/user",
+        "Dhyana", "ucode-rev=0x12345678", NULL,
+        "ucode-rev", 0x12345678,
+    },
 };
 
 /*
-- 
2.43.7


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [PATCH v1 0/9] target/i386: Fix Hygon vendor-specific CPU behavior
  2026-07-06  5:55 [PATCH v1 0/9] target/i386: Fix Hygon vendor-specific CPU behavior zhang_wei
                   ` (8 preceding siblings ...)
  2026-07-06  5:55 ` [PATCH v1 9/9] target/i386: Use AMD ucode-rev default " zhang_wei
@ 2026-07-22 12:10 ` Tina Zhang
  9 siblings, 0 replies; 20+ messages in thread
From: Tina Zhang @ 2026-07-22 12:10 UTC (permalink / raw)
  To: qemu-devel
  Cc: kvm, Michael S . Tsirkin, Paolo Bonzini, Marcelo Tosatti,
	Tina Zhang, Yongwei Xu

Hi,

Just a gentle ping on this series.

This series fixes several Hygon Dhyana vendor-specific CPU behavior gaps 
where QEMU currently keys AMD-compatible paths only on AuthenticAMD.

The guest-visible changes are gated by x-hygon-vendor-abi-fixes and kept 
off for pc-11.0 and older machine types.  The KVM runtime changes do not 
change guest CPU model ABI.

Any comments would be appreciated.

Thanks,
Tina

On 7/6/2026 1:55 PM, zhang_wei@open-hieco.net wrote:
> From: Tina Zhang <zhang_wei@hygon.cn>
> 
> Hygon Dhyana uses the HygonGenuine vendor string, but a number of
> guest-visible and KVM-facing interfaces follow AMD-compatible behavior.
> QEMU currently keys several of these paths only on AuthenticAMD, so Hygon
> guests can see vendor-inconsistent CPUID/MSR state or use the wrong KVM
> PMU/MCE handling paths.
> 
> This series makes those checks explicit for Hygon where appropriate.
> 
> Guest-visible CPU ABI changes are gated by the new
> x-hygon-vendor-abi-fixes property.  The property defaults to true for new
> machine types and is disabled for pc-11.0 and older, so existing machine
> types keep their previous Hygon ABI for migration compatibility.
> 
> The KVM injected-MCE and PMU path changes are not CPUID model table
> changes.  They make QEMU use the AMD-compatible runtime handling that
> Linux/KVM already uses for Hygon.
> 
> The series covers:
> 
>    * AMD CPUID[0x80000001].EDX aliases for Hygon
>    * hiding Intel cache CPUID leaves 2 and 4 for Hygon
>    * hiding IA32_ARCH_CAPABILITIES for Hygon unless old ABI requires it
>    * AMD MCE status encoding for Hygon memory-failure injection
>    * AMD PMU MSR setup/save/restore paths for Hygon
>    * disabling Intel-style MCA broadcast for Hygon injected MCEs
>    * AMD IOMMU HT GPA hole layout for Hygon on new machine types
>    * AMD legacy cache fallback for Hygon when legacy-cache=on
>    * AMD-shaped default ucode-rev value for Hygon
> 
> Tests were added for the Dhyana CPUID/ucode compatibility behavior and
> for the Hygon HT GPA hole memory-layout case.
> 
> Tested with:
> 
>    ninja -C build
> 
>    build/pyvenv/bin/meson test -C build --print-errorlogs \
>        qemu:qtest-i386/test-x86-cpuid-compat \
>        qemu:qtest-x86_64/test-x86-cpuid-compat \
>        qemu:func-x86_64-mem_addr_space
> 
> Tina Zhang (9):
>    target/i386: Sync AMD CPUID aliases for Hygon
>    target/i386: Hide Intel cache CPUID leaves for Hygon
>    target/i386: Hide ARCH_CAPABILITIES for Hygon
>    target/i386/kvm: Use AMD MCE status encoding for Hygon
>    target/i386/kvm: Use AMD PMU MSR paths for Hygon
>    target/i386: Do not broadcast injected MCEs for Hygon
>    hw/i386: Apply AMD IOMMU HT GPA hole to Hygon
>    target/i386: Use AMD legacy cache fallback for Hygon
>    target/i386: Use AMD ucode-rev default for Hygon
> 
>   hw/i386/pc.c                                  | 22 +++--
>   target/i386/cpu.c                             | 86 +++++++++++++----
>   target/i386/cpu.h                             | 12 +++
>   target/i386/helper.c                          |  6 +-
>   target/i386/kvm/kvm.c                         | 36 +++++--
>   .../functional/x86_64/test_mem_addr_space.py  | 36 +++++++
>   tests/qtest/test-x86-cpuid-compat.c           | 95 +++++++++++++++++++
>   7 files changed, 263 insertions(+), 30 deletions(-)
> 


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v1 5/9] target/i386/kvm: Use AMD PMU MSR paths for Hygon
  2026-07-06  5:55 ` [PATCH v1 5/9] target/i386/kvm: Use AMD PMU MSR paths " zhang_wei
@ 2026-07-31  5:55   ` Zhao Liu
  2026-07-31  7:18     ` Tina Zhang
  0 siblings, 1 reply; 20+ messages in thread
From: Zhao Liu @ 2026-07-31  5:55 UTC (permalink / raw)
  To: zhang_wei
  Cc: qemu-devel, kvm, Michael S . Tsirkin, Paolo Bonzini,
	Marcelo Tosatti, Zhao Liu

Hello Tina,

> diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
> index 8e2bfbbe1d..215e0c8f03 100644
> --- a/target/i386/kvm/kvm.c
> +++ b/target/i386/kvm/kvm.c
> @@ -2175,6 +2175,21 @@ static void kvm_init_pmu_info_amd(struct kvm_cpuid2 *cpuid, X86CPU *cpu)
>      }
>  }
>  
> +/*
> + * KVM exposes the AMD PMU CPUID/MSR layout for Hygon guests, so QEMU must
> + * use the AMD PMU setup and MSR state paths for Hygon too.
> + */
> +static bool kvm_pmu_uses_amd_msrs(const CPUX86State *env)
> +{
> +    return IS_AMD_CPU(env) || IS_HYGON_CPU(env);
> +}
> +
> +static bool host_cpu_uses_amd_pmu_msrs(const char *host_vendor)
> +{
> +    return g_str_equal(host_vendor, CPUID_VENDOR_AMD) ||
> +           g_str_equal(host_vendor, CPUID_VENDOR_HYGON);
> +}
>
>  static bool is_host_compat_vendor(CPUX86State *env)
>  {
>      char host_vendor[CPUID_VENDOR_SZ + 1];
> @@ -2191,8 +2206,8 @@ static bool is_host_compat_vendor(CPUX86State *env)
>          return true;
>      }
>
> -    return g_str_equal(host_vendor, CPUID_VENDOR_AMD) &&
> -           IS_AMD_CPU(env);
> +    return host_cpu_uses_amd_pmu_msrs(host_vendor) &&
> +           kvm_pmu_uses_amd_msrs(env);
>  }

It seems to be doing the same thing as the previous Intel & Zhaoxin
compatibility check.

To unify similar checks, how about we abstract them into the "PMU vendor
family"?

For example,

typedef enum {
    X86_PMU_VENDOR_UNKNOWN,
    X86_PMU_VENDOR_INTEL,
    X86_PMU_VENDOR_AMD,
} X86PMUVendor;

static X86PMUVendor x86_cpu_pmu_vendor(const CPUX86State *env)
{
    if (IS_INTEL_CPU(env) || IS_ZHAOXIN_CPU(env)) {
        return X86_PMU_VENDOR_INTEL;
    }
    if (IS_AMD_CPU(env) || IS_HYGON_CPU(env)) {
        return X86_PMU_VENDOR_AMD;
    }
    return X86_PMU_VENDOR_UNKNOWN;
}

static X86PMUVendor x86_host_pmu_vendor(void)
{
    char host_vendor[CPUID_VENDOR_SZ + 1];

    host_cpu_vendor_fms(host_vendor, NULL, NULL, NULL);

    if (g_str_equal(host_vendor, CPUID_VENDOR_INTEL) ||
        g_str_equal(host_vendor, CPUID_VENDOR_ZHAOXIN1) ||
        g_str_equal(host_vendor, CPUID_VENDOR_ZHAOXIN2)) {
        return X86_PMU_VENDOR_INTEL;
    }

    if (g_str_equal(host_vendor, CPUID_VENDOR_AMD) ||
        g_str_equal(host_vendor, CPUID_VENDOR_HYGON)) {
        return X86_PMU_VENDOR_AMD;
    }
    return X86_PMU_VENDOR_UNKNOWN;
}

/*
 * The guest vPMU can be virtualized only when the host and guest's PMU
 * architectures are compatible.
 */
static bool is_host_compat_vendor(CPUX86State *env)
{
    X86PMUVendor guest = x86_cpu_pmu_vendor(env);

    return guest != X86_PMU_VENDOR_UNKNOWN && guest == x86_host_pmu_vendor();
}

>  static void kvm_init_pmu_info(struct kvm_cpuid2 *cpuid, X86CPU *cpu)
> @@ -2222,7 +2237,7 @@ static void kvm_init_pmu_info(struct kvm_cpuid2 *cpuid, X86CPU *cpu)
>  
>      if (IS_INTEL_CPU(env) || IS_ZHAOXIN_CPU(env)) {
>          kvm_init_pmu_info_intel(cpuid);
> -    } else if (IS_AMD_CPU(env)) {
> +    } else if (kvm_pmu_uses_amd_msrs(env)) {
>          kvm_init_pmu_info_amd(cpuid, cpu);
>      }
>  }

Then such CPU check can be replaced with:

    switch (x86_cpu_pmu_vendor(env)) {
    case X86_PMU_VENDOR_INTEL:
        kvm_init_pmu_info_intel(cpuid);
        break;
    case X86_PMU_VENDOR_AMD:
        kvm_init_pmu_info_amd(cpuid, cpu);
        break;
    default:
        g_assert_not_reached();
    }

The latter can also be replaced with "x86_cpu_pmu_vendor(env) ==
X86_PMU_VENDOR_AMD" instead of the "kvm_pmu_uses_amd_msrs(env)" you're
currently using.

What do you think?

Regards,
Zhao

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v1 1/9] target/i386: Sync AMD CPUID aliases for Hygon
  2026-07-06  5:55 ` [PATCH v1 1/9] target/i386: Sync AMD CPUID aliases for Hygon zhang_wei
@ 2026-07-31  7:02   ` Zhao Liu
  2026-07-31  7:50     ` Tina Zhang
  0 siblings, 1 reply; 20+ messages in thread
From: Zhao Liu @ 2026-07-31  7:02 UTC (permalink / raw)
  To: zhang_wei
  Cc: qemu-devel, kvm, Michael S . Tsirkin, Paolo Bonzini,
	Marcelo Tosatti, Zhao Liu

> -GlobalProperty pc_compat_11_0[] = {};
> +GlobalProperty pc_compat_11_0[] = {
> +    { TYPE_X86_CPU, "x-hygon-vendor-abi-fixes", "false" },
> +};

This needs rebase on v11.1 :)

>  const size_t pc_compat_11_0_len = G_N_ELEMENTS(pc_compat_11_0);
>  
>  GlobalProperty pc_compat_10_2[] = {};
> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> index 5805d33ab9..32b8bc9ebd 100644
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c
> @@ -8608,6 +8608,20 @@ uint32_t cpu_x86_virtual_addr_width(CPUX86State *env)
>      }
>  }
>  
> +/*
> + * AMD CPUs define CPUID[0x80000001].EDX aliases for selected CPUID[1].EDX
> + * feature bits.  Hygon Dhyana follows the same extended feature alias rules.
> + * Enable the corrected Hygon behavior only for machine types where Hygon
> + * vendor ABI fixes are on.
> + */
> +static bool x86_cpu_has_amd_cpuid_aliases(const X86CPU *cpu)
> +{
> +    const CPUX86State *env = &cpu->env;
> +
> +    return IS_AMD_CPU(env) ||
> +           (cpu->hygon_vendor_abi_fixes && IS_HYGON_CPU(env));
> +}
> +
>  void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
>                     uint32_t *eax, uint32_t *ebx,
>                     uint32_t *ecx, uint32_t *edx)
> @@ -10147,10 +10161,11 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
>          }
>      }
>  
> -    /* On AMD CPUs, some CPUID[8000_0001].EDX bits must match the bits on
> -     * CPUID[1].EDX.
> +    /*
> +     * CPUs that use AMD-compatible extended CPUID aliases must keep selected
> +     * CPUID[0x80000001].EDX bits synchronized with CPUID[1].EDX.
>       */
> -    if (IS_AMD_CPU(env)) {
> +    if (x86_cpu_has_amd_cpuid_aliases(cpu)) {

Or we can omit this helper ("x86_cpu_has_amd_cpuid_aliases(cpu)") and
instead do the check directly inline?

I think we should have fewer helpers like this, unless the conditional
checks are really lengthy... Since the helpers added for each ABI is
similar, but we can’t consolidate them into a single generic helper
(because while the AMD and Hygon ABIs are basically similar, there are
still differences), having too many similar helpers makes the code seem
fragmented.

> @@ -2461,6 +2467,12 @@ struct ArchCPU {
>       */
>      bool vendor_cpuid_only_v2;
>  
> +    /*
> +     * Enable Hygon vendor ABI fixes for new machine types.  Old machine
> +     * types disable this to preserve guest-visible CPU ABI.
> +     */
> +    bool hygon_vendor_abi_fixes;
> +

Maybe the following comment to emphasize this is a compat option?

/*
 * Compatibility bits for old machine types: if true, apply Hygon
 * vendor-specific ABI fixes.  Old machine types disable this to
 * preserve the guest-visible CPU ABI.
 */

>      /* Only advertise TOPOEXT features that AMD defines */
>      bool amd_topoext_features_only;
>  
> diff --git a/tests/qtest/test-x86-cpuid-compat.c b/tests/qtest/test-x86-cpuid-compat.c
> index 17c0965827..b7f8834052 100644
> --- a/tests/qtest/test-x86-cpuid-compat.c
> +++ b/tests/qtest/test-x86-cpuid-compat.c
> @@ -113,6 +113,21 @@ typedef struct FeatureTestArgs {
>      bool expected_value;
>  } FeatureTestArgs;
>  
> +typedef struct BoolPropTestArgs {
> +    /* Test name */
> +    const char *name;
> +    /* CPU type */
> +    const char *cpu;
> +    /* CPU features (may be NULL) */
> +    const char *cpufeat;
> +    /* machine type (may be NULL to use default machine) */
> +    const char *machine;
> +    /* CPU property to read */
> +    const char *property;
> +    /* expected value of the property */
> +    bool expected_value;
> +} BoolPropTestArgs;

Good test!

Regards,
Zhao


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v1 2/9] target/i386: Hide Intel cache CPUID leaves for Hygon
  2026-07-06  5:55 ` [PATCH v1 2/9] target/i386: Hide Intel cache CPUID leaves " zhang_wei
@ 2026-07-31  7:03   ` Zhao Liu
  0 siblings, 0 replies; 20+ messages in thread
From: Zhao Liu @ 2026-07-31  7:03 UTC (permalink / raw)
  To: zhang_wei
  Cc: qemu-devel, kvm, Michael S . Tsirkin, Paolo Bonzini,
	Marcelo Tosatti

On Mon, Jul 06, 2026 at 01:55:23PM +0800, zhang_wei@open-hieco.net wrote:
> Date: Mon,  6 Jul 2026 13:55:23 +0800
> From: zhang_wei@open-hieco.net
> Subject: [PATCH v1 2/9] target/i386: Hide Intel cache CPUID leaves for Hygon
> X-Mailer: git-send-email 2.43.7
> 
> From: Tina Zhang <zhang_wei@open-hieco.net>
> 
> When x-vendor-cpuid-only is enabled, QEMU suppresses CPUID leaves 2
> and 4 for AuthenticAMD CPUs because those leaves describe Intel cache
> information.  Hygon Dhyana uses the HygonGenuine vendor string, so it
> currently skips that filtering and can expose Intel cache leaves together
> with AMD/Hygon extended cache leaves.
> 
> That is inconsistent guest-visible CPUID: Hygon Dhyana provides cache
> information through the extended cache leaves, so it should not also
> advertise the Intel cache descriptor and deterministic cache parameter
> leaves.
> 
> Apply the same leaf 2 and leaf 4 filtering to Hygon CPUs when Hygon
> vendor ABI fixes are enabled.  The property keeps the old CPUID output
> for pc-11.0 and older machine types.
> 
> Signed-off-by: Tina Zhang <zhang_wei@open-hieco.net>
> ---
>  target/i386/cpu.c | 19 +++++++++++++++++--
>  1 file changed, 17 insertions(+), 2 deletions(-)

Reviewed-by: Zhao Liu <zhao1.liu@intel.com>


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v1 3/9] target/i386: Hide ARCH_CAPABILITIES for Hygon
  2026-07-06  5:55 ` [PATCH v1 3/9] target/i386: Hide ARCH_CAPABILITIES " zhang_wei
@ 2026-07-31  7:05   ` Zhao Liu
  0 siblings, 0 replies; 20+ messages in thread
From: Zhao Liu @ 2026-07-31  7:05 UTC (permalink / raw)
  To: zhang_wei
  Cc: qemu-devel, kvm, Michael S . Tsirkin, Paolo Bonzini,
	Marcelo Tosatti

On Mon, Jul 06, 2026 at 01:55:24PM +0800, zhang_wei@open-hieco.net wrote:
> Date: Mon,  6 Jul 2026 13:55:24 +0800
> From: zhang_wei@open-hieco.net
> Subject: [PATCH v1 3/9] target/i386: Hide ARCH_CAPABILITIES for Hygon
> X-Mailer: git-send-email 2.43.7
> 
> From: Tina Zhang <zhang_wei@open-hieco.net>
> 
> IA32_ARCH_CAPABILITIES is an Intel-defined MSR.  KVM can synthesize the
> CPUID bit and read-only MSR for non-Intel guests, and QEMU already hides
> that interface for AMD CPU models because Windows may not expect it on
> AMD-compatible CPUs.
> 
> Hygon Dhyana uses the HygonGenuine vendor string, so it currently skips
> that AMD filter.  If arch-capabilities=on is requested, QEMU can expose
> CPUID.7.0.EDX[ARCH_CAPABILITIES] and the associated MSR feature word to
> a Hygon guest.
> 
> That creates a vendor-inconsistent CPU ABI: the guest sees an
> AMD-compatible vendor and cache/topology interface, but also sees an
> Intel-specific architectural capabilities MSR.  Guests that choose CPU
> mitigation or feature paths from the vendor can mis-handle that
> combination; Windows is known to be sensitive to ARCH_CAPABILITIES on
> AMD-compatible CPUs.
> 
> Apply the same ARCH_CAPABILITIES hiding rule to Hygon CPUs when Hygon
> vendor ABI fixes are enabled.  Keep arch_cap_always_on as the migration
> escape hatch, and keep the old Hygon CPUID/MSR output for pc-11.0 and
> older machine types via x-hygon-vendor-abi-fixes=false.
> 
> Signed-off-by: Tina Zhang <zhang_wei@open-hieco.net>
> ---
>  target/i386/cpu.c | 33 ++++++++++++++++++++++++---------
>  1 file changed, 24 insertions(+), 9 deletions(-)

Reviewed-by: Zhao Liu <zhao1.liu@intel.com>


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v1 4/9] target/i386/kvm: Use AMD MCE status encoding for Hygon
  2026-07-06  5:55 ` [PATCH v1 4/9] target/i386/kvm: Use AMD MCE status encoding " zhang_wei
@ 2026-07-31  7:06   ` Zhao Liu
  2026-07-31  7:21     ` Tina Zhang
  0 siblings, 1 reply; 20+ messages in thread
From: Zhao Liu @ 2026-07-31  7:06 UTC (permalink / raw)
  To: zhang_wei
  Cc: qemu-devel, kvm, Michael S . Tsirkin, Paolo Bonzini,
	Marcelo Tosatti

> +/*
> + * Use AMD-style MCE status records for QEMU-injected memory failures on
> + * AMD and Hygon CPUs.
> + */
> +static bool kvm_mce_inject_uses_amd_status(const CPUX86State *env)
> +{
> +    return IS_AMD_CPU(env) || IS_HYGON_CPU(env);
> +}
> +
>  static void kvm_mce_inject(X86CPU *cpu, hwaddr paddr, int code)
>  {
>      CPUState *cs = CPU(cpu);
> @@ -707,7 +716,7 @@ static void kvm_mce_inject(X86CPU *cpu, hwaddr paddr, int code)
>      uint64_t mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV;
>      int flags = 0;
>  
> -    if (!IS_AMD_CPU(env)) {
> +    if (!kvm_mce_inject_uses_amd_status(env)) {

Maybe we can check hygon directly here?


Regards,
Zhao

>          status |= MCI_STATUS_S | MCI_STATUS_UC;
>          if (code == BUS_MCEERR_AR) {
>              status |= MCI_STATUS_AR | 0x134;
> -- 
> 2.43.7
> 
> 

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v1 8/9] target/i386: Use AMD legacy cache fallback for Hygon
  2026-07-06  5:55 ` [PATCH v1 8/9] target/i386: Use AMD legacy cache fallback for Hygon zhang_wei
@ 2026-07-31  7:08   ` Zhao Liu
  0 siblings, 0 replies; 20+ messages in thread
From: Zhao Liu @ 2026-07-31  7:08 UTC (permalink / raw)
  To: zhang_wei
  Cc: qemu-devel, kvm, Michael S . Tsirkin, Paolo Bonzini,
	Marcelo Tosatti

On Mon, Jul 06, 2026 at 01:55:29PM +0800, zhang_wei@open-hieco.net wrote:
> Date: Mon,  6 Jul 2026 13:55:29 +0800
> From: zhang_wei@open-hieco.net
> Subject: [PATCH v1 8/9] target/i386: Use AMD legacy cache fallback for Hygon
> X-Mailer: git-send-email 2.43.7
> 
> From: Tina Zhang <zhang_wei@open-hieco.net>
> 
> When legacy-cache=on, x86_cpu_realizefn() builds a hardcoded cache
> model.  It selected the AMD legacy cache table only for CPUs with the
> AuthenticAMD vendor ID.  Dhyana uses the HygonGenuine vendor ID, so this
> explicit compatibility path fell back to QEMU's old Intel legacy cache
> table.
> 
> The wrong table is visible through AMD extended cache leaves.  With the
> Intel legacy table, Dhyana reports 32 KiB, 8-way L1 caches in CPUID
> 0x80000005 and a 4 MiB, 16-way L2 cache in CPUID 0x80000006.  Linux
> uses the AMD/Hygon cache enumeration path for Hygon and reads these AMD
> extended cache leaves.
> 
> Use the AMD legacy cache table for Hygon in this fallback path when the
> new Hygon vendor ABI fixes are enabled.
> Keep the old fallback for pc-11.0 and
> older machine types through x-hygon-vendor-abi-fixes=false.
> 
> The default Dhyana model is unchanged because it provides EPYC cache_info
> and therefore defaults legacy-cache to off.  The guest-visible change is
> limited to users who explicitly configure legacy-cache=on on new machine
> types.
> 
> Signed-off-by: Tina Zhang <zhang_wei@open-hieco.net>
> ---
>  target/i386/cpu.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)

Reviewed-by: Zhao Liu <zhao1.liu@intel.com>


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v1 5/9] target/i386/kvm: Use AMD PMU MSR paths for Hygon
  2026-07-31  5:55   ` Zhao Liu
@ 2026-07-31  7:18     ` Tina Zhang
  0 siblings, 0 replies; 20+ messages in thread
From: Tina Zhang @ 2026-07-31  7:18 UTC (permalink / raw)
  To: Zhao Liu
  Cc: qemu-devel, kvm, Michael S . Tsirkin, Paolo Bonzini,
	Marcelo Tosatti



On 7/31/2026 1:55 PM, Zhao Liu wrote:
> To unify similar checks, how about we abstract them into the "PMU vendor
> family"?

Yes, this makes sense. This is a PMU architecture/layout compatibility
check, not a raw CPU vendor identity check. I'll update this in the next
version.


Thanks,
Tina


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v1 4/9] target/i386/kvm: Use AMD MCE status encoding for Hygon
  2026-07-31  7:06   ` Zhao Liu
@ 2026-07-31  7:21     ` Tina Zhang
  0 siblings, 0 replies; 20+ messages in thread
From: Tina Zhang @ 2026-07-31  7:21 UTC (permalink / raw)
  To: Zhao Liu
  Cc: qemu-devel, kvm, Michael S . Tsirkin, Paolo Bonzini,
	Marcelo Tosatti



On 7/31/2026 3:06 PM, Zhao Liu wrote:
>> +/*
>> + * Use AMD-style MCE status records for QEMU-injected memory failures on
>> + * AMD and Hygon CPUs.
>> + */
>> +static bool kvm_mce_inject_uses_amd_status(const CPUX86State *env)
>> +{
>> +    return IS_AMD_CPU(env) || IS_HYGON_CPU(env);
>> +}
>> +
>>   static void kvm_mce_inject(X86CPU *cpu, hwaddr paddr, int code)
>>   {
>>       CPUState *cs = CPU(cpu);
>> @@ -707,7 +716,7 @@ static void kvm_mce_inject(X86CPU *cpu, hwaddr paddr, int code)
>>       uint64_t mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV;
>>       int flags = 0;
>>   
>> -    if (!IS_AMD_CPU(env)) {
>> +    if (!kvm_mce_inject_uses_amd_status(env)) {
> 
> Maybe we can check hygon directly here?
Yes. Since there is only one user of this helper, keeping the check 
inline is clearer. I'll update it in the next version.


Thanks,
Tina


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v1 1/9] target/i386: Sync AMD CPUID aliases for Hygon
  2026-07-31  7:02   ` Zhao Liu
@ 2026-07-31  7:50     ` Tina Zhang
  0 siblings, 0 replies; 20+ messages in thread
From: Tina Zhang @ 2026-07-31  7:50 UTC (permalink / raw)
  To: Zhao Liu
  Cc: qemu-devel, kvm, Michael S . Tsirkin, Paolo Bonzini,
	Marcelo Tosatti

On 7/31/2026 3:02 PM, Zhao Liu wrote:
>> -GlobalProperty pc_compat_11_0[] = {};
>> +GlobalProperty pc_compat_11_0[] = {
>> +    { TYPE_X86_CPU, "x-hygon-vendor-abi-fixes", "false" },
>> +};
> This needs rebase on v11.1 🙂

Right, I will rebase this on top of v11.1.

>> -    if (IS_AMD_CPU(env)) {
>> +    if (x86_cpu_has_amd_cpuid_aliases(cpu)) {
> Or we can omit this helper ("x86_cpu_has_amd_cpuid_aliases(cpu)") and
> instead do the check directly inline?
> 
> I think we should have fewer helpers like this, unless the conditional
> checks are really lengthy... Since the helpers added for each ABI is
> similar, but we can’t consolidate them into a single generic helper
> (because while the AMD and Hygon ABIs are basically similar, there are
> still differences), having too many similar helpers makes the code seem
> fragmented.

Agreed. The helper is unnecessary for this short condition. I will 
inline the Hygon-gated check in v2 to avoid adding another small 
ABI-specific helper.


> 
>> @@ -2461,6 +2467,12 @@ struct ArchCPU {
>>        */
>>       bool vendor_cpuid_only_v2;
>>   
>> +    /*
>> +     * Enable Hygon vendor ABI fixes for new machine types.  Old machine
>> +     * types disable this to preserve guest-visible CPU ABI.
>> +     */
>> +    bool hygon_vendor_abi_fixes;
>> +
> Maybe the following comment to emphasize this is a compat option?

Yes, that wording is clearer. I will update the comment in v2.

Thanks,
Tina
> 
> /*
>   * Compatibility bits for old machine types: if true, apply Hygon
>   * vendor-specific ABI fixes.  Old machine types disable this to
>   * preserve the guest-visible CPU ABI.
>   */






^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2026-07-31  7:50 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-06  5:55 [PATCH v1 0/9] target/i386: Fix Hygon vendor-specific CPU behavior zhang_wei
2026-07-06  5:55 ` [PATCH v1 1/9] target/i386: Sync AMD CPUID aliases for Hygon zhang_wei
2026-07-31  7:02   ` Zhao Liu
2026-07-31  7:50     ` Tina Zhang
2026-07-06  5:55 ` [PATCH v1 2/9] target/i386: Hide Intel cache CPUID leaves " zhang_wei
2026-07-31  7:03   ` Zhao Liu
2026-07-06  5:55 ` [PATCH v1 3/9] target/i386: Hide ARCH_CAPABILITIES " zhang_wei
2026-07-31  7:05   ` Zhao Liu
2026-07-06  5:55 ` [PATCH v1 4/9] target/i386/kvm: Use AMD MCE status encoding " zhang_wei
2026-07-31  7:06   ` Zhao Liu
2026-07-31  7:21     ` Tina Zhang
2026-07-06  5:55 ` [PATCH v1 5/9] target/i386/kvm: Use AMD PMU MSR paths " zhang_wei
2026-07-31  5:55   ` Zhao Liu
2026-07-31  7:18     ` Tina Zhang
2026-07-06  5:55 ` [PATCH v1 6/9] target/i386: Do not broadcast injected MCEs " zhang_wei
2026-07-06  5:55 ` [PATCH v1 7/9] hw/i386: Apply AMD IOMMU HT GPA hole to Hygon zhang_wei
2026-07-06  5:55 ` [PATCH v1 8/9] target/i386: Use AMD legacy cache fallback for Hygon zhang_wei
2026-07-31  7:08   ` Zhao Liu
2026-07-06  5:55 ` [PATCH v1 9/9] target/i386: Use AMD ucode-rev default " zhang_wei
2026-07-22 12:10 ` [PATCH v1 0/9] target/i386: Fix Hygon vendor-specific CPU behavior Tina Zhang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox