Hygon architecture uses VMMCALL as guest hypercall instruction. Now,
the test like "fix hypercall" uses VMCALL and then results in test
failure.
Utilize the Hygon-specific flag to identify if the test is running on
Hygon CPU and alter the instruction of hypercall if needed.
Signed-off-by: Zhiquan Li <zhiquan_li@163.com>
---
tools/testing/selftests/kvm/lib/x86/processor.c | 3 ++-
tools/testing/selftests/kvm/x86/fix_hypercall_test.c | 2 +-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/kvm/lib/x86/processor.c b/tools/testing/selftests/kvm/lib/x86/processor.c
index bbd3336f22eb..64f9ecd2387d 100644
--- a/tools/testing/selftests/kvm/lib/x86/processor.c
+++ b/tools/testing/selftests/kvm/lib/x86/processor.c
@@ -1229,7 +1229,8 @@ const struct kvm_cpuid_entry2 *get_cpuid_entry(const struct kvm_cpuid2 *cpuid,
"1: vmmcall\n\t" \
"2:" \
: "=a"(r) \
- : [use_vmmcall] "r" (host_cpu_is_amd), inputs); \
+ : [use_vmmcall] "r" \
+ (host_cpu_is_amd || host_cpu_is_hygon), inputs); \
\
r; \
})
diff --git a/tools/testing/selftests/kvm/x86/fix_hypercall_test.c b/tools/testing/selftests/kvm/x86/fix_hypercall_test.c
index 762628f7d4ba..0377ab5b1238 100644
--- a/tools/testing/selftests/kvm/x86/fix_hypercall_test.c
+++ b/tools/testing/selftests/kvm/x86/fix_hypercall_test.c
@@ -52,7 +52,7 @@ static void guest_main(void)
if (host_cpu_is_intel) {
native_hypercall_insn = vmx_vmcall;
other_hypercall_insn = svm_vmmcall;
- } else if (host_cpu_is_amd) {
+ } else if (host_cpu_is_amd || host_cpu_is_hygon) {
native_hypercall_insn = svm_vmmcall;
other_hypercall_insn = vmx_vmcall;
} else {
--
2.43.0
On Mon, Feb 09, 2026, Zhiquan Li wrote:
> Hygon architecture uses VMMCALL as guest hypercall instruction. Now,
> the test like "fix hypercall" uses VMCALL and then results in test
> failure.
>
> Utilize the Hygon-specific flag to identify if the test is running on
> Hygon CPU and alter the instruction of hypercall if needed.
>
> Signed-off-by: Zhiquan Li <zhiquan_li@163.com>
> ---
> tools/testing/selftests/kvm/lib/x86/processor.c | 3 ++-
> tools/testing/selftests/kvm/x86/fix_hypercall_test.c | 2 +-
> 2 files changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/tools/testing/selftests/kvm/lib/x86/processor.c b/tools/testing/selftests/kvm/lib/x86/processor.c
> index bbd3336f22eb..64f9ecd2387d 100644
> --- a/tools/testing/selftests/kvm/lib/x86/processor.c
> +++ b/tools/testing/selftests/kvm/lib/x86/processor.c
> @@ -1229,7 +1229,8 @@ const struct kvm_cpuid_entry2 *get_cpuid_entry(const struct kvm_cpuid2 *cpuid,
> "1: vmmcall\n\t" \
> "2:" \
> : "=a"(r) \
> - : [use_vmmcall] "r" (host_cpu_is_amd), inputs); \
> + : [use_vmmcall] "r" \
> + (host_cpu_is_amd || host_cpu_is_hygon), inputs); \
Rather than play a constant game of whack-a-mole and end up with a huge number of
"host_cpu_is_amd || host_cpu_is_hygon" checks, I would prefer to add (in addition
to host_cpu_is_hygon) a "host_cpu_is_amd_compatible" flag.
E.g. slotted in after patch 1, something like this:
---
tools/testing/selftests/kvm/include/x86/processor.h | 1 +
tools/testing/selftests/kvm/lib/x86/processor.c | 8 ++++++--
tools/testing/selftests/kvm/x86/fix_hypercall_test.c | 2 +-
tools/testing/selftests/kvm/x86/msrs_test.c | 2 +-
tools/testing/selftests/kvm/x86/xapic_state_test.c | 2 +-
5 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/tools/testing/selftests/kvm/include/x86/processor.h b/tools/testing/selftests/kvm/include/x86/processor.h
index 1338de7111e7..40e3deb64812 100644
--- a/tools/testing/selftests/kvm/include/x86/processor.h
+++ b/tools/testing/selftests/kvm/include/x86/processor.h
@@ -22,6 +22,7 @@
extern bool host_cpu_is_intel;
extern bool host_cpu_is_amd;
extern bool host_cpu_is_hygon;
+extern bool host_cpu_is_amd_compatible;
extern uint64_t guest_tsc_khz;
#ifndef MAX_NR_CPUID_ENTRIES
diff --git a/tools/testing/selftests/kvm/lib/x86/processor.c b/tools/testing/selftests/kvm/lib/x86/processor.c
index f6b1c5324931..7b7fd2ad148f 100644
--- a/tools/testing/selftests/kvm/lib/x86/processor.c
+++ b/tools/testing/selftests/kvm/lib/x86/processor.c
@@ -24,6 +24,7 @@ vm_vaddr_t exception_handlers;
bool host_cpu_is_amd;
bool host_cpu_is_intel;
bool host_cpu_is_hygon;
+bool host_cpu_is_amd_compatible;
bool is_forced_emulation_enabled;
uint64_t guest_tsc_khz;
@@ -794,6 +795,7 @@ void kvm_arch_vm_post_create(struct kvm_vm *vm, unsigned int nr_vcpus)
sync_global_to_guest(vm, host_cpu_is_intel);
sync_global_to_guest(vm, host_cpu_is_amd);
sync_global_to_guest(vm, host_cpu_is_hygon);
+ sync_global_to_guest(vm, host_cpu_is_amd_compatible);
sync_global_to_guest(vm, is_forced_emulation_enabled);
sync_global_to_guest(vm, pmu_errata_mask);
@@ -1350,7 +1352,8 @@ const struct kvm_cpuid_entry2 *get_cpuid_entry(const struct kvm_cpuid2 *cpuid,
"1: vmmcall\n\t" \
"2:" \
: "=a"(r) \
- : [use_vmmcall] "r" (host_cpu_is_amd), inputs); \
+ : [use_vmmcall] "r" (host_cpu_is_amd_compatible), \
+ inputs); \
\
r; \
})
@@ -1391,7 +1394,7 @@ unsigned long vm_compute_max_gfn(struct kvm_vm *vm)
max_gfn = (1ULL << (guest_maxphyaddr - vm->page_shift)) - 1;
/* Avoid reserved HyperTransport region on AMD processors. */
- if (!host_cpu_is_amd)
+ if (!host_cpu_is_amd_compatible)
return max_gfn;
/* On parts with <40 physical address bits, the area is fully hidden */
@@ -1427,6 +1430,7 @@ void kvm_selftest_arch_init(void)
host_cpu_is_intel = this_cpu_is_intel();
host_cpu_is_amd = this_cpu_is_amd();
host_cpu_is_hygon = this_cpu_is_hygon();
+ host_cpu_is_amd_compatible = host_cpu_is_amd || host_cpu_is_hygon;
is_forced_emulation_enabled = kvm_is_forced_emulation_enabled();
kvm_init_pmu_errata();
diff --git a/tools/testing/selftests/kvm/x86/fix_hypercall_test.c b/tools/testing/selftests/kvm/x86/fix_hypercall_test.c
index 762628f7d4ba..00b6e85735dd 100644
--- a/tools/testing/selftests/kvm/x86/fix_hypercall_test.c
+++ b/tools/testing/selftests/kvm/x86/fix_hypercall_test.c
@@ -52,7 +52,7 @@ static void guest_main(void)
if (host_cpu_is_intel) {
native_hypercall_insn = vmx_vmcall;
other_hypercall_insn = svm_vmmcall;
- } else if (host_cpu_is_amd) {
+ } else if (host_cpu_is_amd_compatible) {
native_hypercall_insn = svm_vmmcall;
other_hypercall_insn = vmx_vmcall;
} else {
diff --git a/tools/testing/selftests/kvm/x86/msrs_test.c b/tools/testing/selftests/kvm/x86/msrs_test.c
index 40d918aedce6..4c97444fdefe 100644
--- a/tools/testing/selftests/kvm/x86/msrs_test.c
+++ b/tools/testing/selftests/kvm/x86/msrs_test.c
@@ -81,7 +81,7 @@ static u64 fixup_rdmsr_val(u32 msr, u64 want)
* is supposed to emulate that behavior based on guest vendor model
* (which is the same as the host vendor model for this test).
*/
- if (!host_cpu_is_amd)
+ if (!host_cpu_is_amd_compatible)
return want;
switch (msr) {
diff --git a/tools/testing/selftests/kvm/x86/xapic_state_test.c b/tools/testing/selftests/kvm/x86/xapic_state_test.c
index 3b4814c55722..0c5e12f5f14e 100644
--- a/tools/testing/selftests/kvm/x86/xapic_state_test.c
+++ b/tools/testing/selftests/kvm/x86/xapic_state_test.c
@@ -248,7 +248,7 @@ int main(int argc, char *argv[])
* drops writes, AMD does not). Account for the errata when checking
* that KVM reads back what was written.
*/
- x.has_xavic_errata = host_cpu_is_amd &&
+ x.has_xavic_errata = host_cpu_is_amd_compatible &&
get_kvm_amd_param_bool("avic");
vcpu_clear_cpuid_feature(x.vcpu, X86_FEATURE_X2APIC);
base-commit: 391774310e7309b5a1ee12fac9264e95b1d4a6ee
--
© 2016 - 2026 Red Hat, Inc.