All new accounts created on Gitlab now require administrator approval. If you invite any collaborators, please let Flux staff know so they can approve the accounts.

Commit 4cae4d5a authored by Marcel Apfelbaum's avatar Marcel Apfelbaum Committed by Peter Maydell

hmp: fix regression of HMP device_del auto-completion

The commits:
 - 6a1fa9f5 (monitor: add del completion for peripheral device)
 - 66e56b13 (qdev: add qdev_build_hotpluggable_device_list helper)

cause a QEMU crash when trying to use HMP device_del auto-completion.
It can be easily reproduced by:
    <qemu-bin> -enable-kvm  ~/images/fedora.qcow2 -monitor stdio -device virtio-net-pci,id=vnet

    (qemu) device_del
    /home/mapfelba/git/upstream/qemu/hw/core/qdev.c:941:qdev_build_hotpluggable_device_list: Object 0x7f6ce04e4fe0 is not an instance of type device
    Aborted (core dumped)

The root cause is qdev_build_hotpluggable_device_list going recursively over
all peripherals and their children assuming all are devices. It doesn't work
since PCI devices have at least on child which is a memory region (bus master).

Solved by observing that all devices appear as direct children of
/machine/peripheral container. No need of going recursively
over all the children.
Signed-off-by: default avatarMarcel Apfelbaum <>
Reported-by: default avatarGal Hammer <>
Reviewed-by: default avatarIgor Mammedov <>
Signed-off-by: default avatarPeter Maydell <>
parent 490309fc
......@@ -935,7 +935,7 @@ void qdev_alias_all_properties(DeviceState *target, Object *source)
} while (class != object_class_by_name(TYPE_DEVICE));
int qdev_build_hotpluggable_device_list(Object *obj, void *opaque)
static int qdev_add_hotpluggable_device(Object *obj, void *opaque)
GSList **list = opaque;
DeviceState *dev = DEVICE(obj);
......@@ -944,10 +944,18 @@ int qdev_build_hotpluggable_device_list(Object *obj, void *opaque)
*list = g_slist_append(*list, dev);
object_child_foreach(obj, qdev_build_hotpluggable_device_list, opaque);
return 0;
GSList *qdev_build_hotpluggable_device_list(Object *peripheral)
GSList *list = NULL;
object_child_foreach(peripheral, qdev_add_hotpluggable_device, &list);
return list;
static bool device_get_realized(Object *obj, Error **errp)
DeviceState *dev = DEVICE(obj);
......@@ -365,7 +365,7 @@ extern int qdev_hotplug;
char *qdev_get_dev_path(DeviceState *dev);
int qdev_build_hotpluggable_device_list(Object *obj, void *opaque);
GSList *qdev_build_hotpluggable_device_list(Object *peripheral);
void qbus_set_hotplug_handler(BusState *bus, DeviceState *handler,
Error **errp);
......@@ -4321,17 +4321,14 @@ void object_add_completion(ReadLineState *rs, int nb_args, const char *str)
static void peripheral_device_del_completion(ReadLineState *rs,
const char *str, size_t len)
Object *peripheral;
GSList *list = NULL, *item;
Object *peripheral = container_get(qdev_get_machine(), "/peripheral");
GSList *list, *item;
peripheral = object_resolve_path("/machine/peripheral/", NULL);
if (peripheral == NULL) {
list = qdev_build_hotpluggable_device_list(peripheral);
if (!list) {
object_child_foreach(peripheral, qdev_build_hotpluggable_device_list,
for (item = list; item; item = g_slist_next(item)) {
DeviceState *dev = item->data;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment