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 the vendor CPU ABI compat gate is 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 Reviewed-by: Zhao Liu --- 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 ad94fa755c..569ef785ca 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 + * the corrected vendor CPU ABI is 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)); +} + /* * CPUID leaves 2 and 4 describe Intel cache information. AMD CPUs use * extended cache leaves instead, and Hygon Dhyana follows that AMD/Hygon -- 2.43.7