From: Nadav Amit <nadav.amit@xxxxxxxxx> KVM knows to emulate both vmcall and vmmcall regardless of the actual architecture. Native hardware does not behave this way. Based on the availability of test-device, figure out that the test is run on non-KVM environment, and if so, run vmcall/vmmcall based on the actual architecture. Signed-off-by: Nadav Amit <nadav.amit@xxxxxxxxx> --- lib/x86/processor.h | 8 ++++++++ x86/hypercall.c | 31 +++++++++++++++++++++++-------- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/lib/x86/processor.h b/lib/x86/processor.h index abc04b0..517ee70 100644 --- a/lib/x86/processor.h +++ b/lib/x86/processor.h @@ -118,6 +118,14 @@ static inline u8 cpuid_maxphyaddr(void) return raw_cpuid(0x80000008, 0).a & 0xff; } +static inline bool is_intel(void) +{ + struct cpuid c = cpuid(0); + u32 name[4] = {c.b, c.d, c.c }; + + return strcmp((char *)name, "GenuineIntel") == 0; +} + #define CPUID(a, b, c, d) ((((unsigned long long) a) << 32) | (b << 16) | \ (c << 8) | d) diff --git a/x86/hypercall.c b/x86/hypercall.c index 28760e3..a02ee33 100644 --- a/x86/hypercall.c +++ b/x86/hypercall.c @@ -2,6 +2,7 @@ #include "vm.h" #include "desc.h" #include "alloc_page.h" +#include "fwcfg.h" #define KVM_HYPERCALL_INTEL ".byte 0x0f,0x01,0xc1" #define KVM_HYPERCALL_AMD ".byte 0x0f,0x01,0xd9" @@ -51,10 +52,18 @@ test_edge(void) int main(int ac, char **av) { - kvm_hypercall0_intel(-1u); - printf("Hypercall via VMCALL: OK\n"); - kvm_hypercall0_amd(-1u); - printf("Hypercall via VMMCALL: OK\n"); + bool test_vmcall = !no_test_device || is_intel(); + bool test_vmmcall = !no_test_device || !is_intel(); + + if (test_vmcall) { + kvm_hypercall0_intel(-1u); + printf("Hypercall via VMCALL: OK\n"); + } + + if (test_vmmcall) { + kvm_hypercall0_amd(-1u); + printf("Hypercall via VMMCALL: OK\n"); + } #ifdef __x86_64__ setup_vm(); @@ -70,12 +79,18 @@ int main(int ac, char **av) topmost[4093] = 0x0f; topmost[4094] = 0x01; topmost[4095] = 0xc1; - report(test_edge(), - "VMCALL on edge of canonical address space (intel)"); + + if (test_vmcall) { + report(test_edge(), + "VMCALL on edge of canonical address space (intel)"); + } topmost[4095] = 0xd9; - report(test_edge(), - "VMMCALL on edge of canonical address space (AMD)"); + + if (test_vmmcall) { + report(test_edge(), + "VMMCALL on edge of canonical address space (AMD)"); + } #endif return report_summary(); -- 2.25.1