On 11/4/21 11:15, Markus Armbruster wrote: > Jonah Palmer writes: > >> From: Laurent Vivier >> >> This new command lists all the instances of VirtIODevice with >> their QOM paths and virtio type/name. >> >> Signed-off-by: Jonah Palmer >> --- >> hw/virtio/meson.build | 2 ++ >> hw/virtio/virtio-stub.c | 14 ++++++++++ >> hw/virtio/virtio.c | 27 +++++++++++++++++++ >> include/hw/virtio/virtio.h | 1 + >> qapi/meson.build | 1 + >> qapi/qapi-schema.json | 1 + >> qapi/virtio.json | 67 ++++++++++++++++++++++++++++++++++++++++++++++ >> tests/qtest/qmp-cmd-test.c | 1 + >> 8 files changed, 114 insertions(+) >> create mode 100644 hw/virtio/virtio-stub.c >> create mode 100644 qapi/virtio.json >> >> diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build >> index 521f7d6..d893f5f 100644 >> --- a/hw/virtio/meson.build >> +++ b/hw/virtio/meson.build >> @@ -6,8 +6,10 @@ softmmu_virtio_ss.add(when: 'CONFIG_VHOST', if_false: files('vhost-stub.c')) >> >> softmmu_ss.add_all(when: 'CONFIG_VIRTIO', if_true: softmmu_virtio_ss) >> softmmu_ss.add(when: 'CONFIG_VIRTIO', if_false: files('vhost-stub.c')) >> +softmmu_ss.add(when: 'CONFIG_VIRTIO', if_false: files('virtio-stub.c')) >> >> softmmu_ss.add(when: 'CONFIG_ALL', if_true: files('vhost-stub.c')) >> +softmmu_ss.add(when: 'CONFIG_ALL', if_true: files('virtio-stub.c')) >> >> virtio_ss = ss.source_set() >> virtio_ss.add(files('virtio.c')) >> diff --git a/hw/virtio/virtio-stub.c b/hw/virtio/virtio-stub.c >> new file mode 100644 >> index 0000000..d4a88f5 >> --- /dev/null >> +++ b/hw/virtio/virtio-stub.c >> @@ -0,0 +1,14 @@ >> +#include "qemu/osdep.h" >> +#include "qapi/error.h" >> +#include "qapi/qapi-commands-virtio.h" >> + >> +static void *qmp_virtio_unsupported(Error **errp) >> +{ >> + error_setg(errp, "Virtio is disabled"); >> + return NULL; >> +} >> + >> +VirtioInfoList *qmp_x_debug_query_virtio(Error **errp) >> +{ >> + return qmp_virtio_unsupported(errp); >> +} >> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c >> index 7050bd5..ad17be7 100644 >> --- a/hw/virtio/virtio.c >> +++ b/hw/virtio/virtio.c >> @@ -13,6 +13,8 @@ >> >> #include "qemu/osdep.h" >> #include "qapi/error.h" >> +#include "qapi/qapi-commands-virtio.h" >> +#include "qapi/qapi-visit-virtio.h" >> #include "cpu.h" >> #include "trace.h" >> #include "qemu/error-report.h" >> @@ -29,6 +31,9 @@ >> #include "sysemu/runstate.h" >> #include "standard-headers/linux/virtio_ids.h" >> >> +/* QAPI list of VirtIODevices */ >> +static QTAILQ_HEAD(, VirtIODevice) virtio_list; >> + >> /* >> * The alignment to use between consumer and producer parts of vring. >> * x86 pagesize again. This is the default, used by transports like PCI >> @@ -3709,6 +3714,7 @@ static void virtio_device_realize(DeviceState *dev, Error **errp) >> vdev->listener.commit = virtio_memory_listener_commit; >> vdev->listener.name = "virtio"; >> memory_listener_register(&vdev->listener, vdev->dma_as); >> + QTAILQ_INSERT_TAIL(&virtio_list, vdev, next); >> } >> >> static void virtio_device_unrealize(DeviceState *dev) >> @@ -3723,6 +3729,7 @@ static void virtio_device_unrealize(DeviceState *dev) >> vdc->unrealize(dev); >> } >> >> + QTAILQ_REMOVE(&virtio_list, vdev, next); >> g_free(vdev->bus_name); >> vdev->bus_name = NULL; >> } >> @@ -3896,6 +3903,8 @@ static void virtio_device_class_init(ObjectClass *klass, void *data) >> vdc->stop_ioeventfd = virtio_device_stop_ioeventfd_impl; >> >> vdc->legacy_features |= VIRTIO_LEGACY_FEATURES; >> + >> + QTAILQ_INIT(&virtio_list); >> } >> >> bool virtio_device_ioeventfd_enabled(VirtIODevice *vdev) >> @@ -3906,6 +3915,24 @@ bool virtio_device_ioeventfd_enabled(VirtIODevice *vdev) >> return virtio_bus_ioeventfd_enabled(vbus); >> } >> >> +VirtioInfoList *qmp_x_debug_query_virtio(Error **errp) >> +{ >> + VirtioInfoList *list = NULL; >> + VirtioInfoList *node; >> + VirtIODevice *vdev; >> + >> + QTAILQ_FOREACH(vdev, &virtio_list, next) { >> + DeviceState *dev = DEVICE(vdev); >> + node = g_new0(VirtioInfoList, 1); >> + node->value = g_new(VirtioInfo, 1); >> + node->value->path = g_strdup(dev->canonical_path); >> + node->value->type = g_strdup(vdev->name); >> + QAPI_LIST_PREPEND(list, node->value); >> + } >> + >> + return list; >> +} >> + >> static const TypeInfo virtio_device_info = { >> .name = TYPE_VIRTIO_DEVICE, >> .parent = TYPE_DEVICE, >> diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h >> index 105b98c..eceaafc 100644 >> --- a/include/hw/virtio/virtio.h >> +++ b/include/hw/virtio/virtio.h >> @@ -110,6 +110,7 @@ struct VirtIODevice >> bool use_guest_notifier_mask; >> AddressSpace *dma_as; >> QLIST_HEAD(, VirtQueue) *vector_queues; >> + QTAILQ_ENTRY(VirtIODevice) next; >> }; >> >> struct VirtioDeviceClass { >> diff --git a/qapi/meson.build b/qapi/meson.build >> index c356a38..df5662e 100644 >> --- a/qapi/meson.build >> +++ b/qapi/meson.build >> @@ -45,6 +45,7 @@ qapi_all_modules = [ >> 'sockets', >> 'trace', >> 'transaction', >> + 'virtio', >> 'yank', >> ] >> if have_system >> diff --git a/qapi/qapi-schema.json b/qapi/qapi-schema.json >> index 4912b97..1512ada 100644 >> --- a/qapi/qapi-schema.json >> +++ b/qapi/qapi-schema.json >> @@ -93,3 +93,4 @@ >> { 'include': 'audio.json' } >> { 'include': 'acpi.json' } >> { 'include': 'pci.json' } >> +{ 'include': 'virtio.json' } >> diff --git a/qapi/virtio.json b/qapi/virtio.json >> new file mode 100644 >> index 0000000..4490c2c >> --- /dev/null >> +++ b/qapi/virtio.json >> @@ -0,0 +1,67 @@ >> +# -*- Mode: Python -*- >> +# vim: filetype=python >> +# >> + >> +## >> +# = Virtio devices >> +## >> + >> +## >> +# @VirtioInfo: >> +# >> +# Basic information about a given VirtIODevice including the device >> +# canonical QOM path as well as the name of the device. > Is the part starting with "including" worth its keep? Probably not. Sometimes I'm just unnecessarily verbose. Plus it's pretty obvious once you look at the fields below. Will trim this. > >> +# >> +# @path: VirtIO device canonical QOM path > I'd prefer "the device's canonical QOM path". Ok, will do! > >> +# >> +# @type: VirtIO device name >> +# >> +# Since: 6.2 > If this series misses 6.2, which seems likely, you'll have to adjust the > since tags. Yup, will keep that in mind! > >> +# >> +## >> +{ 'struct': 'VirtioInfo', >> + 'data': { >> + 'path': 'str', >> + 'type': 'str' >> + } >> +} >> + >> +## >> +# @x-debug-query-virtio: >> +# >> +# Returns a list of all initalized VirtIO devices > What's an uninitialized VirtIO device? Oops. I think this should really be "Returns a list of all realized VirtIO devices". All devices that are realized are added to virtio_list and all devices that unrealized are removed from virtio_list. I'll change this to "Returns a list of all realized VirtIO devices". > >> +# >> +# Returns: list of gathered @VirtioInfo devices >> +# >> +# Since: 6.2 >> +# >> +# Example: >> +# >> +# -> { "execute": "x-debug-query-virtio" } >> +# <- { "return": [ >> +# { >> +# "path": "/machine/peripheral-anon/device[4]/virtio-backend", >> +# "type": "virtio-input" >> +# }, >> +# { >> +# "path": "/machine/peripheral/crypto0/virtio-backend", >> +# "type": "virtio-crypto" >> +# }, >> +# { >> +# "path": "/machine/peripheral-anon/device[2]/virtio-backend", >> +# "type": "virtio-scsi" >> +# }, >> +# { >> +# "path": "/machine/peripheral-anon/device[1]/virtio-backend", >> +# "type": "virtio-net" >> +# }, >> +# { >> +# "path": "/machine/peripheral-anon/device[0]/virtio-backend", >> +# "type": "virtio-serial" >> +# } >> +# ] >> +# } >> +# >> +## >> + >> +{ 'command': 'x-debug-query-virtio', 'returns': ['VirtioInfo'] } >> diff --git a/tests/qtest/qmp-cmd-test.c b/tests/qtest/qmp-cmd-test.c >> index 1af2f74..62c6cc4 100644 >> --- a/tests/qtest/qmp-cmd-test.c >> +++ b/tests/qtest/qmp-cmd-test.c >> @@ -95,6 +95,7 @@ static bool query_is_ignored(const char *cmd) >> "query-gic-capabilities", /* arm */ >> /* Success depends on target-specific build configuration: */ >> "query-pci", /* CONFIG_PCI */ >> + "x-debug-query-virtio", /* CONFIG_VIRTIO */ >> /* Success depends on launching SEV guest */ >> "query-sev-launch-measure", >> /* Success depends on Host or Hypervisor SEV support */ Jonah