diff --git a/hw/hyperv/hv-balloon.c b/hw/hyperv/hv-balloon.c index ade283335a..3a9ef07691 100644 --- a/hw/hyperv/hv-balloon.c +++ b/hw/hyperv/hv-balloon.c @@ -366,7 +366,7 @@ static void hv_balloon_unballoon_posting(HvBalloon *balloon, StateDesc *stdesc) PageRangeTree dtree; uint64_t *dctr; bool our_range; - struct dm_unballoon_request *ur; + g_autofree struct dm_unballoon_request *ur = NULL; size_t ur_size = sizeof(*ur) + sizeof(ur->range_array[0]); PageRange range; bool bret; @@ -388,8 +388,7 @@ static void hv_balloon_unballoon_posting(HvBalloon *balloon, StateDesc *stdesc) assert(dtree.t); assert(dctr); - ur = alloca(ur_size); - memset(ur, 0, ur_size); + ur = g_malloc0(ur_size); ur->hdr.type = DM_UNBALLOON_REQUEST; ur->hdr.size = ur_size; ur->hdr.trans_id = balloon->trans_id; @@ -514,8 +513,8 @@ ret_idle: static void hv_balloon_hot_add_rb_wait(HvBalloon *balloon, StateDesc *stdesc) { VMBusChannel *chan = hv_balloon_get_channel(balloon); - struct dm_hot_add *ha; - size_t ha_size = sizeof(*ha) + sizeof(ha->range); + struct dm_hot_add_with_region *ha; + size_t ha_size = sizeof(*ha); assert(balloon->state == S_HOT_ADD_RB_WAIT); @@ -531,8 +530,8 @@ static void hv_balloon_hot_add_posting(HvBalloon *balloon, StateDesc *stdesc) PageRange *hot_add_range = &balloon->hot_add_range; uint64_t *current_count = &balloon->ha_current_count; VMBusChannel *chan = hv_balloon_get_channel(balloon); - struct dm_hot_add *ha; - size_t ha_size = sizeof(*ha) + sizeof(ha->range); + g_autofree struct dm_hot_add_with_region *ha = NULL; + size_t ha_size = sizeof(*ha); union dm_mem_page_range *ha_region; uint64_t align, chunk_max_size; ssize_t ret; @@ -560,9 +559,8 @@ static void hv_balloon_hot_add_posting(HvBalloon *balloon, StateDesc *stdesc) */ *current_count = MIN(hot_add_range->count, chunk_max_size); - ha = alloca(ha_size); - ha_region = &(&ha->range)[1]; - memset(ha, 0, ha_size); + ha = g_malloc0(ha_size); + ha_region = &ha->region; ha->hdr.type = DM_MEM_HOT_ADD_REQUEST; ha->hdr.size = ha_size; ha->hdr.trans_id = balloon->trans_id; diff --git a/hw/hyperv/hyperv.c b/hw/hyperv/hyperv.c index 6c4a18dd0e..3ea54ba818 100644 --- a/hw/hyperv/hyperv.c +++ b/hw/hyperv/hyperv.c @@ -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; +} diff --git a/hw/hyperv/vmbus.c b/hw/hyperv/vmbus.c index 380239af2c..f33afeeea2 100644 --- a/hw/hyperv/vmbus.c +++ b/hw/hyperv/vmbus.c @@ -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")); } diff --git a/include/hw/hyperv/dynmem-proto.h b/include/hw/hyperv/dynmem-proto.h index a657786a94..68b8b606f2 100644 --- a/include/hw/hyperv/dynmem-proto.h +++ b/include/hw/hyperv/dynmem-proto.h @@ -328,7 +328,8 @@ struct dm_unballoon_response { /* * Hot add request message. Message sent from the host to the guest. * - * mem_range: Memory range to hot add. + * range: Memory range to hot add. + * region: Explicit hot add memory region for guest to use. Optional. * */ @@ -337,6 +338,12 @@ struct dm_hot_add { union dm_mem_page_range range; } QEMU_PACKED; +struct dm_hot_add_with_region { + struct dm_header hdr; + union dm_mem_page_range range; + union dm_mem_page_range region; +} QEMU_PACKED; + /* * Hot add response message. * This message is sent by the guest to report the status of a hot add request. diff --git a/include/hw/hyperv/hyperv.h b/include/hw/hyperv/hyperv.h index 015c3524b1..d717b4e13d 100644 --- a/include/hw/hyperv/hyperv.h +++ b/include/hw/hyperv/hyperv.h @@ -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 diff --git a/target/i386/kvm/hyperv-stub.c b/target/i386/kvm/hyperv-stub.c index 778ed782e6..3263dcf05d 100644 --- a/target/i386/kvm/hyperv-stub.c +++ b/target/i386/kvm/hyperv-stub.c @@ -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) +{ +} diff --git a/target/i386/kvm/hyperv.c b/target/i386/kvm/hyperv.c index 6825c89af3..f2a3fe650a 100644 --- a/target/i386/kvm/hyperv.c +++ b/target/i386/kvm/hyperv.c @@ -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(); +} diff --git a/target/i386/kvm/hyperv.h b/target/i386/kvm/hyperv.h index 67543296c3..e3982c8f4d 100644 --- a/target/i386/kvm/hyperv.h +++ b/target/i386/kvm/hyperv.h @@ -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 diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c index 42970ab046..e68cbe9293 100644 --- a/target/i386/kvm/kvm.c +++ b/target/i386/kvm/kvm.c @@ -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; }