diff --git a/src/arch/x86/drivers/hyperv/hyperv.c b/src/arch/x86/drivers/hyperv/hyperv.c index d911dcba8..ff5e4987b 100644 --- a/src/arch/x86/drivers/hyperv/hyperv.c +++ b/src/arch/x86/drivers/hyperv/hyperv.c @@ -150,6 +150,8 @@ static int hv_check_hv ( struct hv_hypervisor *hv ) { uint32_t discard_ebx; uint32_t discard_ecx; uint32_t discard_edx; + uint32_t available; + uint32_t permissions; /* Check for presence of a hypervisor (not necessarily Hyper-V) */ x86_features ( &features ); @@ -167,6 +169,30 @@ static int hv_check_hv ( struct hv_hypervisor *hv ) { return -ENODEV; } + /* Check that required features and privileges are available */ + cpuid ( HV_CPUID_FEATURES, &available, &permissions, &discard_ecx, + &discard_edx ); + if ( ! ( available & HV_FEATURES_AVAIL_HYPERCALL_MSR ) ) { + DBGC ( hv, "HV %p has no hypercall MSRs (features %08x:%08x)\n", + hv, available, permissions ); + return -ENODEV; + } + if ( ! ( available & HV_FEATURES_AVAIL_SYNIC_MSR ) ) { + DBGC ( hv, "HV %p has no SynIC MSRs (features %08x:%08x)\n", + hv, available, permissions ); + return -ENODEV; + } + if ( ! ( permissions & HV_FEATURES_PERM_POST_MESSAGES ) ) { + DBGC ( hv, "HV %p cannot post messages (features %08x:%08x)\n", + hv, available, permissions ); + return -EACCES; + } + if ( ! ( permissions & HV_FEATURES_PERM_SIGNAL_EVENTS ) ) { + DBGC ( hv, "HV %p cannot signal events (features %08x:%08x)", + hv, available, permissions ); + return -EACCES; + } + return 0; } diff --git a/src/arch/x86/drivers/hyperv/hyperv.h b/src/arch/x86/drivers/hyperv/hyperv.h index 94bdb8a86..d1733d6cd 100644 --- a/src/arch/x86/drivers/hyperv/hyperv.h +++ b/src/arch/x86/drivers/hyperv/hyperv.h @@ -18,6 +18,21 @@ FILE_LICENCE ( GPL2_OR_LATER ); /** Get hypervisor identification */ #define HV_CPUID_HYPERVISOR_ID 0x40000002UL +/** Get hypervisor features */ +#define HV_CPUID_FEATURES 0x40000003UL + +/** SynIC MSRs are available */ +#define HV_FEATURES_AVAIL_SYNIC_MSR 0x00000004UL + +/** Hypercall MSRs are available */ +#define HV_FEATURES_AVAIL_HYPERCALL_MSR 0x00000020UL + +/** Guest may post messages */ +#define HV_FEATURES_PERM_POST_MESSAGES 0x00000010UL + +/** Guest may signal events */ +#define HV_FEATURES_PERM_SIGNAL_EVENTS 0x00000020UL + /** Guest OS identity MSR */ #define HV_X64_MSR_GUEST_OS_ID 0x40000000UL