vmbus: Print a warning when enabled without the recommended set of features

Some Windows versions crash at boot or fail to enable the VMBus device if
they don't see the expected set of Hyper-V features (enlightenments).

Since this provides poor user experience let's warn user if the VMBus
device is enabled without the recommended set of Hyper-V features.

The recommended set is the minimum set of Hyper-V features required to make
the VMBus device work properly in Windows Server versions 2016, 2019 and
2022.

Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Maciej S. Szmigiero <maciej.szmigiero@oracle.com>
master
Maciej S. Szmigiero 2024-01-25 15:12:41 +01:00
parent 546987284a
commit 6093637b4d
7 changed files with 40 additions and 0 deletions

View File

@ -951,3 +951,15 @@ uint64_t hyperv_syndbg_query_options(void)
return msg.u.query_options.options;
}
static bool vmbus_recommended_features_enabled;
bool hyperv_are_vmbus_recommended_features_enabled(void)
{
return vmbus_recommended_features_enabled;
}
void hyperv_set_vmbus_recommended_features_enabled(void)
{
vmbus_recommended_features_enabled = true;
}

View File

@ -2631,6 +2631,12 @@ static void vmbus_bridge_realize(DeviceState *dev, Error **errp)
return;
}
if (!hyperv_are_vmbus_recommended_features_enabled()) {
warn_report("VMBus enabled without the recommended set of Hyper-V features: "
"hv-stimer, hv-vapic and hv-runtime. "
"Some Windows versions might not boot or enable the VMBus device");
}
bridge->bus = VMBUS(qbus_new(TYPE_VMBUS, dev, "vmbus"));
}

View File

@ -139,4 +139,8 @@ typedef struct HvSynDbgMsg {
} HvSynDbgMsg;
typedef uint16_t (*HvSynDbgHandler)(void *context, HvSynDbgMsg *msg);
void hyperv_set_syndbg_handler(HvSynDbgHandler handler, void *context);
bool hyperv_are_vmbus_recommended_features_enabled(void);
void hyperv_set_vmbus_recommended_features_enabled(void);
#endif

View File

@ -52,3 +52,7 @@ void hyperv_x86_synic_reset(X86CPU *cpu)
void hyperv_x86_synic_update(X86CPU *cpu)
{
}
void hyperv_x86_set_vmbus_recommended_features_enabled(void)
{
}

View File

@ -149,3 +149,8 @@ int kvm_hv_handle_exit(X86CPU *cpu, struct kvm_hyperv_exit *exit)
return -1;
}
}
void hyperv_x86_set_vmbus_recommended_features_enabled(void)
{
hyperv_set_vmbus_recommended_features_enabled();
}

View File

@ -26,4 +26,6 @@ int hyperv_x86_synic_add(X86CPU *cpu);
void hyperv_x86_synic_reset(X86CPU *cpu);
void hyperv_x86_synic_update(X86CPU *cpu);
void hyperv_x86_set_vmbus_recommended_features_enabled(void);
#endif

View File

@ -1650,6 +1650,13 @@ static int hyperv_init_vcpu(X86CPU *cpu)
}
}
/* Skip SynIC and VP_INDEX since they are hard deps already */
if (hyperv_feat_enabled(cpu, HYPERV_FEAT_STIMER) &&
hyperv_feat_enabled(cpu, HYPERV_FEAT_VAPIC) &&
hyperv_feat_enabled(cpu, HYPERV_FEAT_RUNTIME)) {
hyperv_x86_set_vmbus_recommended_features_enabled();
}
return 0;
}