This changes the test for the KVM IPI hypercall API to be skipped if the relevant cpuid feature bit is not set or if the KVM cpuid leaf is missing, rather than the presence of the test device. The latter is an unreliable inference on non-KVM platforms. It also adds a skip report when these tests are skipped. Signed-off-by: Phil Dennis-Jordan <phil@xxxxxxxxxxxxx> --- lib/x86/processor.h | 19 +++++++++++++++++++ x86/apic.c | 9 ++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/lib/x86/processor.h b/lib/x86/processor.h index 44f4fd1e..9a4c0d26 100644 --- a/lib/x86/processor.h +++ b/lib/x86/processor.h @@ -284,6 +284,13 @@ static inline bool is_intel(void) #define X86_FEATURE_VNMI (CPUID(0x8000000A, 0, EDX, 25)) #define X86_FEATURE_AMD_PMU_V2 (CPUID(0x80000022, 0, EAX, 0)) +/* + * Hypervisor specific leaves (KVM, ...) + * See: + * https://kernel.org/doc/html/latest/virt/kvm/x86/cpuid.html + */ +#define X86_KVM_FEATURE_PV_SEND_IPI (CPUID(0x40000001, 0, EAX, 11)) + static inline bool this_cpu_has(u64 feature) { u32 input_eax = feature >> 32; @@ -299,6 +306,18 @@ static inline bool this_cpu_has(u64 feature) return ((*(tmp + (output_reg % 32))) & (1 << bit)); } +static inline bool kvm_feature_flags_supported(void) +{ + struct cpuid c; + + c = cpuid_indexed(0x40000000, 0); + return + c.b == 0x4b4d564b + && c.c == 0x564b4d56 + && c.d == 0x4d + && (c.a >= 0x40000001 || c.a == 0); +} + struct far_pointer32 { u32 offset; u16 selector; diff --git a/x86/apic.c b/x86/apic.c index dd7e7834..525e08fd 100644 --- a/x86/apic.c +++ b/x86/apic.c @@ -30,6 +30,11 @@ static bool is_xapic_enabled(void) return (rdmsr(MSR_IA32_APICBASE) & (APIC_EN | APIC_EXTD)) == APIC_EN; } +static bool is_kvm_ipi_hypercall_supported(void) +{ + return kvm_feature_flags_supported() && this_cpu_has(X86_KVM_FEATURE_PV_SEND_IPI); +} + static void test_lapic_existence(void) { u8 version; @@ -658,8 +663,10 @@ static void test_pv_ipi(void) int ret; unsigned long a0 = 0xFFFFFFFF, a1 = 0, a2 = 0xFFFFFFFF, a3 = 0x0; - if (!test_device_enabled()) + if (!is_kvm_ipi_hypercall_supported()) { + report_skip("PV IPIs testing (No KVM IPI hypercall flag in cpuid)"); return; + } asm volatile("vmcall" : "=a"(ret) :"a"(KVM_HC_SEND_IPI), "b"(a0), "c"(a1), "d"(a2), "S"(a3)); report(!ret, "PV IPIs testing"); -- 2.36.1