diff --git a/src/add-ons/kernel/bus_managers/hyperv/arch/x86/VMBus_x86.cpp b/src/add-ons/kernel/bus_managers/hyperv/arch/x86/VMBus_x86.cpp index 5d3556236f..ae60f54d5d 100644 --- a/src/add-ons/kernel/bus_managers/hyperv/arch/x86/VMBus_x86.cpp +++ b/src/add-ons/kernel/bus_managers/hyperv/arch/x86/VMBus_x86.cpp @@ -37,6 +37,17 @@ vmbus_detect_hyperv() return B_ERROR; } + // Check for required Hyper-V features + // Some hypervisors claim to be Hyper-V, but may not actually implement all features + get_cpuid(&cpuInfo, IA32_CPUID_LEAF_HV_FEAT_ID, 0); + TRACE("Hyper-V features: %08" B_PRIX32 ":%08" B_PRIX32 ":%08" B_PRIX32 ":%08" B_PRIX32 "\n", + cpuInfo.regs.eax, cpuInfo.regs.ebx, cpuInfo.regs.ecx, cpuInfo.regs.edx); + if ((cpuInfo.regs.eax & HV_CPUID_EAX_REQUIRED_FEATURES) == 0 + || (cpuInfo.regs.ebx & HV_CPUID_EBX_REQUIRED_FEATURES) == 0) { + TRACE("Missing required Hyper-V features\n"); + return B_ERROR; + } + #ifdef TRACE_HYPERV get_cpuid(&cpuInfo, IA32_CPUID_LEAF_HV_SYS_ID, 0); TRACE("Hyper-V version: %d.%d.%d [SP%d]\n", cpuInfo.regs.ebx >> 16, cpuInfo.regs.ebx & 0xFFFF, diff --git a/src/add-ons/kernel/bus_managers/hyperv/arch/x86/hyperv_cpu.h b/src/add-ons/kernel/bus_managers/hyperv/arch/x86/hyperv_cpu.h index 2025a12e13..06829f285d 100644 --- a/src/add-ons/kernel/bus_managers/hyperv/arch/x86/hyperv_cpu.h +++ b/src/add-ons/kernel/bus_managers/hyperv/arch/x86/hyperv_cpu.h @@ -18,6 +18,32 @@ // Hyper-V signature "Hv#1" #define HV_CPUID_INTERFACE_ID 0x31237648 +// Hyper-V x86 features from feature CPUID leaf, eax register +// https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/tlfs/datatypes/hv_partition_privilege_mask +#define HV_CPUID_FEATURE_VP_RUNTIME (1 << 0) +#define HV_CPUID_FEATURE_TIME_REF_COUNTER (1 << 1) +#define HV_CPUID_FEATURE_SYNIC (1 << 2) +#define HV_CPUID_FEATURE_SYNTIMER (1 << 3) +#define HV_CPUID_FEATURE_APIC (1 << 4) +#define HV_CPUID_FEATURE_HYPERCALL (1 << 5) +#define HV_CPUID_FEATURE_VP_INDEX (1 << 6) +#define HV_CPUID_FEATURE_RESET (1 << 7) +#define HV_CPUID_FEATURE_STATS (1 << 8) +#define HV_CPUID_FEATURE_REFERENCE_TSC (1 << 9) +#define HV_CPUID_FEATURE_GUEST_IDLE (1 << 10) +#define HV_CPUID_FEATURE_FREQUENCY (1 << 11) +#define HV_CPUID_FEATURE_REENLIGHTMENT (1 << 13) + +// Hyper-V x86 features from feature CPUID leaf, ebx register +#define HV_CPUID_FEATURE_HYPERCALL_POST_MESSAGE (1 << 4) +#define HV_CPUID_FEATURE_HYPERCALL_SIGNAL_EVENT (1 << 5) + +// Required feature bits for VMBus operation +#define HV_CPUID_EAX_REQUIRED_FEATURES (HV_CPUID_FEATURE_SYNIC | HV_CPUID_FEATURE_SYNTIMER \ + | HV_CPUID_FEATURE_HYPERCALL) +#define HV_CPUID_EBX_REQUIRED_FEATURES (HV_CPUID_FEATURE_HYPERCALL_POST_MESSAGE \ + | HV_CPUID_FEATURE_HYPERCALL_SIGNAL_EVENT) + // MSR registers #define IA32_MSR_HV_GUEST_OS_ID 0x40000000 #define IA32_MSR_HV_HYPERCALL 0x40000001