diff mbox series

[RFC,v5,1/6] qmp: add QMP command x-debug-query-virtio

Message ID 1616084984-11263-2-git-send-email-jonah.palmer@oracle.com (mailing list archive)
State New, archived
Headers show
Series hmp,qmp: Add some commands to introspect virtio deices | expand

Commit Message

Jonah Palmer March 18, 2021, 4:29 p.m. UTC
From: Laurent Vivier <lvivier@redhat.com>

This new command lists all the instances of VirtIODevice with
their path and virtio type

Signed-off-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Jonah Palmer <jonah.palmer@oracle.com>
---
 hw/virtio/meson.build      |  2 ++
 hw/virtio/virtio-stub.c    | 14 ++++++++++
 hw/virtio/virtio.c         | 28 +++++++++++++++++++
 include/hw/virtio/virtio.h |  1 +
 qapi/meson.build           |  1 +
 qapi/qapi-schema.json      |  1 +
 qapi/virtio.json           | 68 ++++++++++++++++++++++++++++++++++++++++++++++
 tests/qtest/qmp-cmd-test.c |  1 +
 8 files changed, 116 insertions(+)
 create mode 100644 hw/virtio/virtio-stub.c
 create mode 100644 qapi/virtio.json

Comments

Eric Blake March 18, 2021, 8:46 p.m. UTC | #1
On 3/18/21 11:29 AM, Jonah Palmer wrote:
> From: Laurent Vivier <lvivier@redhat.com>
> 
> This new command lists all the instances of VirtIODevice with
> their path and virtio type
> 
> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
> Reviewed-by: Eric Blake <eblake@redhat.com>
> Signed-off-by: Jonah Palmer <jonah.palmer@oracle.com>
> ---

We've missed soft freeze for 6.0, and this feels like a new feature;
therefore...

> +++ b/hw/virtio/virtio.c

>  
> +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 = qapi_enum_parse(&VirtioType_lookup, vdev->name,
> +                                            VIRTIO_TYPE_UNKNOWN, NULL);
> +        node->next = list;
> +        list = node;

This should be updated to use QAPI_LIST_PREPEND rather than open coding.

> +    }
> +
> +    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 b7ece7a..2470e09 100644
> --- a/include/hw/virtio/virtio.h

> +++ b/qapi/virtio.json
> @@ -0,0 +1,68 @@
> +##
> +# = Virtio devices
> +##
> +
> +##
> +# @VirtioType:
> +#
> +# An enumeration of Virtio device types.
> +#
> +# Since: 6.0

...this now needs to reference 6.1.

> +##
> +{ 'enum': 'VirtioType',
> +  'data': [ 'unknown', 'virtio-9p', 'virtio-blk', 'virtio-serial',
> +            'virtio-gpu', 'virtio-input', 'virtio-net', 'virtio-scsi',
> +            'vhost-user-fs', 'vhost-vsock', 'virtio-balloon', 'virtio-crypto',
> +            'virtio-iommu', 'virtio-pmem', 'virtio-rng' ]
> +}
> +
> +##
> +# @VirtioInfo:
> +#
> +# Information about a given VirtIODevice
> +#
> +# @path: VirtIO device canonical path.
> +#
> +# @type: VirtIO device type.
> +#
> +# Since: 6.0

and throughout the series (I'll quit pointing it out)

> +##
> +# @x-debug-query-virtio:
> +#
> +# Return the list of all VirtIO devices
> +#
> +# Returns: list of @VirtioInfo
> +#
> +# Since: 6.0
> +#
> +# Example:
> +#
> +# -> { "execute": "x-debug-query-virtio" }

That said, adding an 'x-' experimental feature is NOT locking us down,
so if some maintainer still wants to include this in -rc1 on the grounds
that it will help debugging other things, rather than pushing it out to
6.1 as a new feature, then keeping things as 6.0 is tolerable in that
border-line case.  (If it misses -rc1, then I will become more adamant
that it does not belong in 6.0)
Jonah Palmer March 23, 2021, 7:29 a.m. UTC | #2
On 3/18/21 4:46 PM, Eric Blake wrote:
> On 3/18/21 11:29 AM, Jonah Palmer wrote:
>> From: Laurent Vivier <lvivier@redhat.com>
>>
>> This new command lists all the instances of VirtIODevice with
>> their path and virtio type
>>
>> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
>> Reviewed-by: Eric Blake <eblake@redhat.com>
>> Signed-off-by: Jonah Palmer <jonah.palmer@oracle.com>
>> ---
> We've missed soft freeze for 6.0, and this feels like a new feature;
> therefore...
>
>> +++ b/hw/virtio/virtio.c
>>   
>> +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 = qapi_enum_parse(&VirtioType_lookup, vdev->name,
>> +                                            VIRTIO_TYPE_UNKNOWN, NULL);
>> +        node->next = list;
>> +        list = node;
> This should be updated to use QAPI_LIST_PREPEND rather than open coding.

Ok! I'll update this.

>
>> +    }
>> +
>> +    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 b7ece7a..2470e09 100644
>> --- a/include/hw/virtio/virtio.h
>> +++ b/qapi/virtio.json
>> @@ -0,0 +1,68 @@
>> +##
>> +# = Virtio devices
>> +##
>> +
>> +##
>> +# @VirtioType:
>> +#
>> +# An enumeration of Virtio device types.
>> +#
>> +# Since: 6.0
> ...this now needs to reference 6.1.

And these!

>
>> +##
>> +{ 'enum': 'VirtioType',
>> +  'data': [ 'unknown', 'virtio-9p', 'virtio-blk', 'virtio-serial',
>> +            'virtio-gpu', 'virtio-input', 'virtio-net', 'virtio-scsi',
>> +            'vhost-user-fs', 'vhost-vsock', 'virtio-balloon', 'virtio-crypto',
>> +            'virtio-iommu', 'virtio-pmem', 'virtio-rng' ]
>> +}
>> +
>> +##
>> +# @VirtioInfo:
>> +#
>> +# Information about a given VirtIODevice
>> +#
>> +# @path: VirtIO device canonical path.
>> +#
>> +# @type: VirtIO device type.
>> +#
>> +# Since: 6.0
> and throughout the series (I'll quit pointing it out)
>
>> +##
>> +# @x-debug-query-virtio:
>> +#
>> +# Return the list of all VirtIO devices
>> +#
>> +# Returns: list of @VirtioInfo
>> +#
>> +# Since: 6.0
>> +#
>> +# Example:
>> +#
>> +# -> { "execute": "x-debug-query-virtio" }
> That said, adding an 'x-' experimental feature is NOT locking us down,
> so if some maintainer still wants to include this in -rc1 on the grounds
> that it will help debugging other things, rather than pushing it out to
> 6.1 as a new feature, then keeping things as 6.0 is tolerable in that
> border-line case.  (If it misses -rc1, then I will become more adamant
> that it does not belong in 6.0)

Right, this patch is not at all urgent for 6.0. I just wanted to send this out to get
a review.

Best,
Jonah

>
Dr. David Alan Gilbert March 24, 2021, 6:31 p.m. UTC | #3
* Jonah Palmer (jonah.palmer@oracle.com) wrote:
> From: Laurent Vivier <lvivier@redhat.com>
> 

<snip>

> --- /dev/null
> +++ b/qapi/virtio.json
> @@ -0,0 +1,68 @@
> +##
> +# = Virtio devices
> +##
> +
> +##
> +# @VirtioType:
> +#
> +# An enumeration of Virtio device types.
> +#
> +# Since: 6.0
> +##
> +{ 'enum': 'VirtioType',
> +  'data': [ 'unknown', 'virtio-9p', 'virtio-blk', 'virtio-serial',
> +            'virtio-gpu', 'virtio-input', 'virtio-net', 'virtio-scsi',
> +            'vhost-user-fs', 'vhost-vsock', 'virtio-balloon', 'virtio-crypto',
> +            'virtio-iommu', 'virtio-pmem', 'virtio-rng' ]

Can we make this be a complete list that's in the same order as include/standard-headers/linux/virtio_ids.h
then if we add a few asserts somewhere to make sure we don't screwup, we
don't need to do any translation.

Dave

> +}
> +
> +##
> +# @VirtioInfo:
> +#
> +# Information about a given VirtIODevice
> +#
> +# @path: VirtIO device canonical path.
> +#
> +# @type: VirtIO device type.
> +#
> +# Since: 6.0
> +#
> +##
> +{ 'struct': 'VirtioInfo',
> +  'data': {
> +    'path': 'str',
> +    'type': 'VirtioType'
> +  }
> +}
> +
> +##
> +# @x-debug-query-virtio:
> +#
> +# Return the list of all VirtIO devices
> +#
> +# Returns: list of @VirtioInfo
> +#
> +# Since: 6.0
> +#
> +# Example:
> +#
> +# -> { "execute": "x-debug-query-virtio" }
> +# <- { "return": [
> +#        {
> +#            "path": "/machine/peripheral-anon/device[3]/virtio-backend",
> +#            "type": "virtio-net"
> +#        },
> +#        {
> +#            "path": "/machine/peripheral-anon/device[1]/virtio-backend",
> +#            "type": "virtio-serial"
> +#        },
> +#        {
> +#            "path": "/machine/peripheral-anon/device[0]/virtio-backend",
> +#            "type": "virtio-blk"
> +#        }
> +#      ]
> +#    }
> +#
> +##
> +
> +{ 'command': 'x-debug-query-virtio', 'returns': ['VirtioInfo'] }
> diff --git a/tests/qtest/qmp-cmd-test.c b/tests/qtest/qmp-cmd-test.c
> index 1c7186e..8f0ae20 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 */
> -- 
> 1.8.3.1
>
Jonah Palmer June 2, 2021, 10:23 a.m. UTC | #4
On 3/24/21 2:31 PM, Dr. David Alan Gilbert wrote:
> * Jonah Palmer (jonah.palmer@oracle.com) wrote:
>> From: Laurent Vivier <lvivier@redhat.com>
>>
> <snip>
>
>> --- /dev/null
>> +++ b/qapi/virtio.json
>> @@ -0,0 +1,68 @@
>> +##
>> +# = Virtio devices
>> +##
>> +
>> +##
>> +# @VirtioType:
>> +#
>> +# An enumeration of Virtio device types.
>> +#
>> +# Since: 6.0
>> +##
>> +{ 'enum': 'VirtioType',
>> +  'data': [ 'unknown', 'virtio-9p', 'virtio-blk', 'virtio-serial',
>> +            'virtio-gpu', 'virtio-input', 'virtio-net', 'virtio-scsi',
>> +            'vhost-user-fs', 'vhost-vsock', 'virtio-balloon', 'virtio-crypto',
>> +            'virtio-iommu', 'virtio-pmem', 'virtio-rng' ]
> Can we make this be a complete list that's in the same order as include/standard-headers/linux/virtio_ids.h
> then if we add a few asserts somewhere to make sure we don't screwup, we
> don't need to do any translation.
>
> Dave

Hi Dave. Just so I understand correctly, you would like me to add all of the entries in the given order?
E.g. including 'virtio-rpmsg', ..., 'virtio-mac80211-wlan', etc.? Or just the supported virtio types in
the order as it's shown in virtio_ids.h?

Many of these devices may not be supported for introspection.

Jonah

>
>> +}
>> +
>> +##
>> +# @VirtioInfo:
>> +#
>> +# Information about a given VirtIODevice
>> +#
>> +# @path: VirtIO device canonical path.
>> +#
>> +# @type: VirtIO device type.
>> +#
>> +# Since: 6.0
>> +#
>> +##
>> +{ 'struct': 'VirtioInfo',
>> +  'data': {
>> +    'path': 'str',
>> +    'type': 'VirtioType'
>> +  }
>> +}
>> +
>> +##
>> +# @x-debug-query-virtio:
>> +#
>> +# Return the list of all VirtIO devices
>> +#
>> +# Returns: list of @VirtioInfo
>> +#
>> +# Since: 6.0
>> +#
>> +# Example:
>> +#
>> +# -> { "execute": "x-debug-query-virtio" }
>> +# <- { "return": [
>> +#        {
>> +#            "path": "/machine/peripheral-anon/device[3]/virtio-backend",
>> +#            "type": "virtio-net"
>> +#        },
>> +#        {
>> +#            "path": "/machine/peripheral-anon/device[1]/virtio-backend",
>> +#            "type": "virtio-serial"
>> +#        },
>> +#        {
>> +#            "path": "/machine/peripheral-anon/device[0]/virtio-backend",
>> +#            "type": "virtio-blk"
>> +#        }
>> +#      ]
>> +#    }
>> +#
>> +##
>> +
>> +{ 'command': 'x-debug-query-virtio', 'returns': ['VirtioInfo'] }
>> diff --git a/tests/qtest/qmp-cmd-test.c b/tests/qtest/qmp-cmd-test.c
>> index 1c7186e..8f0ae20 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 */
>> -- 
>> 1.8.3.1
>>
Dr. David Alan Gilbert June 2, 2021, 11:28 a.m. UTC | #5
* Jonah Palmer (jonah.palmer@oracle.com) wrote:
> 
> On 3/24/21 2:31 PM, Dr. David Alan Gilbert wrote:
> > * Jonah Palmer (jonah.palmer@oracle.com) wrote:
> > > From: Laurent Vivier <lvivier@redhat.com>
> > > 
> > <snip>
> > 
> > > --- /dev/null
> > > +++ b/qapi/virtio.json
> > > @@ -0,0 +1,68 @@
> > > +##
> > > +# = Virtio devices
> > > +##
> > > +
> > > +##
> > > +# @VirtioType:
> > > +#
> > > +# An enumeration of Virtio device types.
> > > +#
> > > +# Since: 6.0
> > > +##
> > > +{ 'enum': 'VirtioType',
> > > +  'data': [ 'unknown', 'virtio-9p', 'virtio-blk', 'virtio-serial',
> > > +            'virtio-gpu', 'virtio-input', 'virtio-net', 'virtio-scsi',
> > > +            'vhost-user-fs', 'vhost-vsock', 'virtio-balloon', 'virtio-crypto',
> > > +            'virtio-iommu', 'virtio-pmem', 'virtio-rng' ]
> > Can we make this be a complete list that's in the same order as include/standard-headers/linux/virtio_ids.h
> > then if we add a few asserts somewhere to make sure we don't screwup, we
> > don't need to do any translation.
> > 
> > Dave
> 
> Hi Dave. Just so I understand correctly, you would like me to add all of the entries in the given order?
> E.g. including 'virtio-rpmsg', ..., 'virtio-mac80211-wlan', etc.? Or just the supported virtio types in
> the order as it's shown in virtio_ids.h?
>
> Many of these devices may not be supported for introspection.

Make that list all of the types, and keep it in the same order as the
header with the same gaps (including one at the start); so that that the QAPI generated enum values
for 'VirtioType' match the virtio_ids constants; that way you never have
to convert between the qapi number and the header number.
(Whenever we do a convert, sooner or later we screwup the convert and
end up with numbers that don't match!)

As you say, only some have support for introspection; so you just need
to check for support rather than doing a mapping.

Dave

> Jonah
> 
> > 
> > > +}
> > > +
> > > +##
> > > +# @VirtioInfo:
> > > +#
> > > +# Information about a given VirtIODevice
> > > +#
> > > +# @path: VirtIO device canonical path.
> > > +#
> > > +# @type: VirtIO device type.
> > > +#
> > > +# Since: 6.0
> > > +#
> > > +##
> > > +{ 'struct': 'VirtioInfo',
> > > +  'data': {
> > > +    'path': 'str',
> > > +    'type': 'VirtioType'
> > > +  }
> > > +}
> > > +
> > > +##
> > > +# @x-debug-query-virtio:
> > > +#
> > > +# Return the list of all VirtIO devices
> > > +#
> > > +# Returns: list of @VirtioInfo
> > > +#
> > > +# Since: 6.0
> > > +#
> > > +# Example:
> > > +#
> > > +# -> { "execute": "x-debug-query-virtio" }
> > > +# <- { "return": [
> > > +#        {
> > > +#            "path": "/machine/peripheral-anon/device[3]/virtio-backend",
> > > +#            "type": "virtio-net"
> > > +#        },
> > > +#        {
> > > +#            "path": "/machine/peripheral-anon/device[1]/virtio-backend",
> > > +#            "type": "virtio-serial"
> > > +#        },
> > > +#        {
> > > +#            "path": "/machine/peripheral-anon/device[0]/virtio-backend",
> > > +#            "type": "virtio-blk"
> > > +#        }
> > > +#      ]
> > > +#    }
> > > +#
> > > +##
> > > +
> > > +{ 'command': 'x-debug-query-virtio', 'returns': ['VirtioInfo'] }
> > > diff --git a/tests/qtest/qmp-cmd-test.c b/tests/qtest/qmp-cmd-test.c
> > > index 1c7186e..8f0ae20 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 */
> > > -- 
> > > 1.8.3.1
> > >
diff mbox series

Patch

diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build
index fbff9bc..81dc4c9 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 1fd1917..0e12561 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 "exec/address-spaces.h"
@@ -30,6 +32,8 @@ 
 #include "sysemu/runstate.h"
 #include "standard-headers/linux/virtio_ids.h"
 
+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
@@ -3673,6 +3677,7 @@  static void virtio_device_realize(DeviceState *dev, Error **errp)
 
     vdev->listener.commit = virtio_memory_listener_commit;
     memory_listener_register(&vdev->listener, vdev->dma_as);
+    QTAILQ_INSERT_TAIL(&virtio_list, vdev, next);
 }
 
 static void virtio_device_unrealize(DeviceState *dev)
@@ -3687,6 +3692,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;
 }
@@ -3844,6 +3850,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)
@@ -3854,6 +3862,26 @@  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 = qapi_enum_parse(&VirtioType_lookup, vdev->name,
+                                            VIRTIO_TYPE_UNKNOWN, NULL);
+        node->next = list;
+        list = node;
+    }
+
+    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 b7ece7a..2470e09 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -108,6 +108,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 0652569..1ffad95 100644
--- a/qapi/meson.build
+++ b/qapi/meson.build
@@ -43,6 +43,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 3441c9a..ed000ea 100644
--- a/qapi/qapi-schema.json
+++ b/qapi/qapi-schema.json
@@ -90,5 +90,6 @@ 
 { 'include': 'misc.json' }
 { 'include': 'misc-target.json' }
 { 'include': 'audio.json' }
+{ 'include': 'virtio.json' }
 { 'include': 'acpi.json' }
 { 'include': 'pci.json' }
diff --git a/qapi/virtio.json b/qapi/virtio.json
new file mode 100644
index 0000000..0fbe542
--- /dev/null
+++ b/qapi/virtio.json
@@ -0,0 +1,68 @@ 
+##
+# = Virtio devices
+##
+
+##
+# @VirtioType:
+#
+# An enumeration of Virtio device types.
+#
+# Since: 6.0
+##
+{ 'enum': 'VirtioType',
+  'data': [ 'unknown', 'virtio-9p', 'virtio-blk', 'virtio-serial',
+            'virtio-gpu', 'virtio-input', 'virtio-net', 'virtio-scsi',
+            'vhost-user-fs', 'vhost-vsock', 'virtio-balloon', 'virtio-crypto',
+            'virtio-iommu', 'virtio-pmem', 'virtio-rng' ]
+}
+
+##
+# @VirtioInfo:
+#
+# Information about a given VirtIODevice
+#
+# @path: VirtIO device canonical path.
+#
+# @type: VirtIO device type.
+#
+# Since: 6.0
+#
+##
+{ 'struct': 'VirtioInfo',
+  'data': {
+    'path': 'str',
+    'type': 'VirtioType'
+  }
+}
+
+##
+# @x-debug-query-virtio:
+#
+# Return the list of all VirtIO devices
+#
+# Returns: list of @VirtioInfo
+#
+# Since: 6.0
+#
+# Example:
+#
+# -> { "execute": "x-debug-query-virtio" }
+# <- { "return": [
+#        {
+#            "path": "/machine/peripheral-anon/device[3]/virtio-backend",
+#            "type": "virtio-net"
+#        },
+#        {
+#            "path": "/machine/peripheral-anon/device[1]/virtio-backend",
+#            "type": "virtio-serial"
+#        },
+#        {
+#            "path": "/machine/peripheral-anon/device[0]/virtio-backend",
+#            "type": "virtio-blk"
+#        }
+#      ]
+#    }
+#
+##
+
+{ 'command': 'x-debug-query-virtio', 'returns': ['VirtioInfo'] }
diff --git a/tests/qtest/qmp-cmd-test.c b/tests/qtest/qmp-cmd-test.c
index 1c7186e..8f0ae20 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 */