]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[hyperv] Check for required features
authorMichael Brown <mcb30@ipxe.org>
Thu, 19 Feb 2015 14:47:07 +0000 (14:47 +0000)
committerMichael Brown <mcb30@ipxe.org>
Fri, 20 Feb 2015 11:00:52 +0000 (11:00 +0000)
Other hypervisors (e.g. KVM) may provide an unusable subset of the
Hyper-V features, and our attempts to use these non-existent features
cause the guest to reboot.

Fix by explicitly checking for the Hyper-V features that we use.

Reported-by: Ján ONDREJ (SAL) <ondrejj@salstar.sk>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/arch/x86/drivers/hyperv/hyperv.c
src/arch/x86/drivers/hyperv/hyperv.h

index d911dcba800bf3e78cdcd3afa09d0943de9f297f..ff5e4987b7108d68ca9fba5a17b053b576853e4c 100644 (file)
@@ -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;
 }
 
index 94bdb8a8617e9b7015becf1d1fccf68ad5b03b3c..d1733d6cd6cfaa59c7d5c6ca89b1a224982972bf 100644 (file)
@@ -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