diff mbox series

[v8,4/8] qmp: add QMP command x-debug-virtio-status

Message ID 1635334909-31614-5-git-send-email-jonah.palmer@oracle.com (mailing list archive)
State New, archived
Headers show
Series hmp,qmp: Add commands to introspect virtio devices | expand

Commit Message

Jonah Palmer Oct. 27, 2021, 11:41 a.m. UTC
From: Laurent Vivier <lvivier@redhat.com>

This new command shows the status of a VirtIODevice, including
its corresponding vhost device status (if active).

Next patch will improve output by decoding feature bits, including
vhost device's feature bits (backend, protocol, acked, and features).
Also will decode status bits of a VirtIODevice.

Next patch will also suppress the vhost device field from displaying
if no vhost device is active for a given VirtIODevice.

Signed-off-by: Jonah Palmer <jonah.palmer@oracle.com>
---
 hw/virtio/virtio-stub.c |   5 +
 hw/virtio/virtio.c      |  96 ++++++++++++++++++
 qapi/virtio.json        | 255 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 356 insertions(+)

Comments

Markus Armbruster Nov. 4, 2021, 3:37 p.m. UTC | #1
Jonah Palmer <jonah.palmer@oracle.com> writes:

> From: Laurent Vivier <lvivier@redhat.com>
>
> This new command shows the status of a VirtIODevice, including
> its corresponding vhost device status (if active).
>
> Next patch will improve output by decoding feature bits, including
> vhost device's feature bits (backend, protocol, acked, and features).
> Also will decode status bits of a VirtIODevice.
>
> Next patch will also suppress the vhost device field from displaying
> if no vhost device is active for a given VirtIODevice.
>
> Signed-off-by: Jonah Palmer <jonah.palmer@oracle.com>
> ---

[...]

> diff --git a/qapi/virtio.json b/qapi/virtio.json
> index 4490c2c..656a26f 100644
> --- a/qapi/virtio.json
> +++ b/qapi/virtio.json
> @@ -65,3 +65,258 @@
>  ##
>  
>  { 'command': 'x-debug-query-virtio', 'returns': ['VirtioInfo'] }
> +
> +##
> +# @VirtioStatusEndianness:
> +#
> +# Enumeration of endianness for VirtioDevice
> +#
> +# Since: 6.2
> +##
> +
> +{ 'enum': 'VirtioStatusEndianness',
> +  'data': [ 'unknown', 'little', 'big' ]
> +}
> +
> +##
> +# @VhostStatus:
> +#
> +# Information about a vhost device. This information will only be
> +# displayed if the vhost device is active.
> +#
> +# @n-mem-sections: vhost_dev n_mem_sections
> +#
> +# @n-tmp-sections: vhost_dev n_tmp_sections
> +#
> +# @nvqs: vhost_dev nvqs. This is the number of virtqueues being used
> +#        by the vhost device.
> +#
> +# @vq-index: vhost_dev vq_index
> +#
> +# @features: vhost_dev features
> +#
> +# @acked-features: vhost_dev acked_features
> +#
> +# @backend-features: vhost_dev backend_features
> +#
> +# @protocol-features: vhost_dev protocol_features
> +#
> +# @max-queues: vhost_dev max_queues
> +#
> +# @backend-cap: vhost_dev backend_cap
> +#
> +# @log-enabled: vhost_dev log_enabled flag
> +#
> +# @log-size: vhost_dev log_size
> +#
> +# Since: 6.2
> +#
> +##
> +
> +{ 'struct': 'VhostStatus',
> +    'data': {
> +        'n-mem-sections': 'int',
> +        'n-tmp-sections': 'int',

Odd indentation.  Better

   { 'struct': 'VhostStatus',
     'data': {
         'n-mem-sections': 'int',
         'n-tmp-sections': 'int',

or

   { 'struct': 'VhostStatus',
     'data': { 'n-mem-sections': 'int',
               'n-tmp-sections': 'int',

More of the same below, and possibly in other patches.  I'm not going to
point it out again.

> +        'nvqs': 'uint32',
> +        'vq-index': 'int',
> +        'features': 'uint64',
> +        'acked-features': 'uint64',
> +        'backend-features': 'uint64',
> +        'protocol-features': 'uint64',
> +        'max-queues': 'uint64',
> +        'backend-cap': 'uint64',
> +        'log-enabled': 'bool',
> +        'log-size': 'uint64'
> +    }
> +}

I can't tell whether these are all needed.  Got to trust virtio experts
there.

I'm not checking the schema types match the data sources' C types.  I
hope you did :)

More of the same below, and possibly in other patches.  I'm not going to
point it out again.

> +
> +##
> +# @VirtioStatus:
> +#
> +# Full status of the virtio device with most VirtIODevice members.
> +# Also includes the full status of the corresponding vhost device
> +# if the vhost device is active.
> +#
> +# @name: VirtIODevice name
> +#
> +# @device-id: VirtIODevice ID
> +#
> +# @vhost-started: VirtIODevice vhost_started flag
> +#
> +# @guest-features: VirtIODevice guest_features
> +#
> +# @host-features: VirtIODevice host_features
> +#
> +# @backend-features: VirtIODevice backend_features
> +#
> +# @device-endian: VirtIODevice device_endian
> +#
> +# @num-vqs: VirtIODevice virtqueue count. This is the number of active
> +#           virtqueues being used by the VirtIODevice.
> +#
> +# @status: VirtIODevice configuration status (e.g. DRIVER_OK,
> +#          FEATURES_OK, DRIVER, etc.)
> +#
> +# @isr: VirtIODevice ISR
> +#
> +# @queue-sel: VirtIODevice queue_sel
> +#
> +# @vm-running: VirtIODevice vm_running flag
> +#
> +# @broken: VirtIODevice broken flag
> +#
> +# @disabled: VirtIODevice disabled flag
> +#
> +# @use-started: VirtIODevice use_started flag
> +#
> +# @started: VirtIODevice started flag
> +#
> +# @start-on-kick: VirtIODevice start_on_kick flag
> +#
> +# @disable-legacy-check: VirtIODevice disabled_legacy_check flag
> +#
> +# @bus-name: VirtIODevice bus_name
> +#
> +# @use-guest-notifier-mask: VirtIODevice use_guest_notifier_mask flag
> +#
> +# @vhost-dev: corresponding vhost device info for a given VirtIODevice
> +#
> +# Since: 6.2
> +#
> +##
> +
> +{ 'struct': 'VirtioStatus',
> +    'data': {
> +        'name': 'str',
> +        'device-id': 'uint16',
> +        'vhost-started': 'bool',
> +        'guest-features': 'uint64',
> +        'host-features': 'uint64',
> +        'backend-features': 'uint64',
> +        'device-endian': 'VirtioStatusEndianness',
> +        'num-vqs': 'int',
> +        'status': 'uint8',
> +        'isr': 'uint8',
> +        'queue-sel': 'uint16',
> +        'vm-running': 'bool',
> +        'broken': 'bool',
> +        'disabled': 'bool',
> +        'use-started': 'bool',
> +        'started': 'bool',
> +        'start-on-kick': 'bool',
> +        'disable-legacy-check': 'bool',
> +        'bus-name': 'str',
> +        'use-guest-notifier-mask': 'bool',
> +        'vhost-dev': 'VhostStatus'
> +    }
> +}
> +
> +##
> +# @x-debug-virtio-status:
> +#
> +# Poll for a comprehensive status of a given virtio device
> +#
> +# @path: Canonical QOM path of the VirtIODevice
> +#
> +# Returns: VirtioStatus of the virtio device
> +#
> +# Since: 6.2
> +#
> +# Examples:
> +#
> +# 1. Poll for the status of virtio-crypto (no vhost-crypto active)
> +#
> +# -> { "execute": "x-debug-virtio-status",
> +#      "arguments": {
> +#          "path": "/machine/peripheral/crypto0/virtio-backend"
> +#      }
> +#    }
> +# <- { "return": {
> +#          "device-endian": "little",
> +#          "bus-name": "",
> +#          "disable-legacy-check": false,
> +#          "name": "virtio-crypto",
> +#          "started": true,
> +#          "device-id": 20,
> +#          "vhost-dev": {
> +#               "n-tmp-sections": 0,
> +#               "n-mem-sections": 0,
> +#               "max-queues": 0,
> +#               "backend-cap": 0,
> +#               "log-size": 0,
> +#               "backend-features": 0,
> +#               "nvqs": 0,
> +#               "protocol-features": 0,
> +#               "vq-index": 0,
> +#               "log-enabled": false,
> +#               "acked-features": 0,
> +#               "features": 0
> +#          },
> +#          "backend-features": 0,
> +#          "start-on-kick": false,
> +#          "isr": 1,
> +#          "broken": false,
> +#          "status": 15,
> +#          "num-vqs": 2,
> +#          "guest-features": 5100273664,
> +#          "host-features": 6325010432,
> +#          "use-guest-notifier-mask": true,
> +#          "vm-running": true,
> +#          "queue-sel": 1,
> +#          "disabled": false,
> +#          "vhost-started": false,
> +#          "use-started": true
> +#      }
> +#    }
> +#
> +# 2. Poll for the status of virtio-net (vhost-net is active)
> +#
> +# -> { "execute": "x-debug-virtio-status",
> +#      "arguments": {
> +#          "path": "/machine/peripheral-anon/device[1]/virtio-backend"
> +#      }
> +#    }
> +# <- { "return": {
> +#          "device-endian": "little",
> +#          "bus-name": "",
> +#          "disabled-legacy-check": false,
> +#          "name": "virtio-net",
> +#          "started": true,
> +#          "device-id": 1,
> +#          "vhost-dev": {
> +#               "n-tmp-sections": 4,
> +#               "n-mem-sections": 4,
> +#               "max-queues": 1,
> +#               "backend-cap": 2,
> +#               "log-size": 0,
> +#               "backend-features": 0,
> +#               "nvqs": 2,
> +#               "protocol-features": 0,
> +#               "vq-index": 0,
> +#               "log-enabled": false,
> +#               "acked-features": 5100306432,
> +#               "features": 13908344832
> +#          },
> +#          "backend-features": 6337593319,
> +#          "start-on-kick": false,
> +#          "isr": 1,
> +#          "broken": false,
> +#          "status": 15,
> +#          "num-vqs": 3,
> +#          "guest-features": 5111807911,
> +#          "host-features": 6337593319,
> +#          "use-guest-notifier-mask": true,
> +#          "vm-running": true,
> +#          "queue-sel": 2,
> +#          "disabled": false,
> +#          "vhost-started": true,
> +#          "use-started": true
> +#      }
> +#    }
> +#
> +##
> +
> +{ 'command': 'x-debug-virtio-status',
> +  'data': { 'path': 'str' },
> +  'returns': 'VirtioStatus'
> +}

Unstable commands now need to be marked with

     'features': [ 'unstable' ]

If you do that, the QAPI generator will demand documentation.  So add
   
   # Features:
   # @unstable: This command is meant for debugging.

You may want to grep for examples.  See also commit 9fb49daabf "qapi:
Mark unstable QMP parts with feature 'unstable'".

Hmm, this command starts with x-debug-virtio-, wheras the one added in
the previous commit starts with x-debug-query-virtio-.

By conventions, commands that just return information on FOO are named
query-FOO.  I recommend an x-query-virtio- prefix for your query
commands.  We can leave their purpose (debug) to documentation.
Jonah Palmer Nov. 5, 2021, 8:36 a.m. UTC | #2
On 11/4/21 11:37, Markus Armbruster wrote:
> Jonah Palmer<jonah.palmer@oracle.com>  writes:
>
>> From: Laurent Vivier<lvivier@redhat.com>
>>
>> This new command shows the status of a VirtIODevice, including
>> its corresponding vhost device status (if active).
>>
>> Next patch will improve output by decoding feature bits, including
>> vhost device's feature bits (backend, protocol, acked, and features).
>> Also will decode status bits of a VirtIODevice.
>>
>> Next patch will also suppress the vhost device field from displaying
>> if no vhost device is active for a given VirtIODevice.
>>
>> Signed-off-by: Jonah Palmer<jonah.palmer@oracle.com>
>> ---
> [...]
>
>> diff --git a/qapi/virtio.json b/qapi/virtio.json
>> index 4490c2c..656a26f 100644
>> --- a/qapi/virtio.json
>> +++ b/qapi/virtio.json
>> @@ -65,3 +65,258 @@
>>   ##
>>   
>>   { 'command': 'x-debug-query-virtio', 'returns': ['VirtioInfo'] }
>> +
>> +##
>> +# @VirtioStatusEndianness:
>> +#
>> +# Enumeration of endianness for VirtioDevice
>> +#
>> +# Since: 6.2
>> +##
>> +
>> +{ 'enum': 'VirtioStatusEndianness',
>> +  'data': [ 'unknown', 'little', 'big' ]
>> +}
>> +
>> +##
>> +# @VhostStatus:
>> +#
>> +# Information about a vhost device. This information will only be
>> +# displayed if the vhost device is active.
>> +#
>> +# @n-mem-sections: vhost_dev n_mem_sections
>> +#
>> +# @n-tmp-sections: vhost_dev n_tmp_sections
>> +#
>> +# @nvqs: vhost_dev nvqs. This is the number of virtqueues being used
>> +#        by the vhost device.
>> +#
>> +# @vq-index: vhost_dev vq_index
>> +#
>> +# @features: vhost_dev features
>> +#
>> +# @acked-features: vhost_dev acked_features
>> +#
>> +# @backend-features: vhost_dev backend_features
>> +#
>> +# @protocol-features: vhost_dev protocol_features
>> +#
>> +# @max-queues: vhost_dev max_queues
>> +#
>> +# @backend-cap: vhost_dev backend_cap
>> +#
>> +# @log-enabled: vhost_dev log_enabled flag
>> +#
>> +# @log-size: vhost_dev log_size
>> +#
>> +# Since: 6.2
>> +#
>> +##
>> +
>> +{ 'struct': 'VhostStatus',
>> +    'data': {
>> +        'n-mem-sections': 'int',
>> +        'n-tmp-sections': 'int',
> Odd indentation.  Better
>
>     { 'struct': 'VhostStatus',
>       'data': {
>           'n-mem-sections': 'int',
>           'n-tmp-sections': 'int',
>
> or
>
>     { 'struct': 'VhostStatus',
>       'data': { 'n-mem-sections': 'int',
>                 'n-tmp-sections': 'int',
>
> More of the same below, and possibly in other patches.  I'm not going to
> point it out again.

Gotcha, I'll use this format in the .json file. Will change it to this for
all relevant patches.

>
>> +        'nvqs': 'uint32',
>> +        'vq-index': 'int',
>> +        'features': 'uint64',
>> +        'acked-features': 'uint64',
>> +        'backend-features': 'uint64',
>> +        'protocol-features': 'uint64',
>> +        'max-queues': 'uint64',
>> +        'backend-cap': 'uint64',
>> +        'log-enabled': 'bool',
>> +        'log-size': 'uint64'
>> +    }
>> +}
> I can't tell whether these are all needed.  Got to trust virtio experts
> there.

Not sure either, I just included whatever I could include.

>
> I'm not checking the schema types match the data sources' C types.  I
> hope you did :)

Yes c:

>
> More of the same below, and possibly in other patches.  I'm not going to
> point it out again.
>
>> +
>> +##
>> +# @VirtioStatus:
>> +#
>> +# Full status of the virtio device with most VirtIODevice members.
>> +# Also includes the full status of the corresponding vhost device
>> +# if the vhost device is active.
>> +#
>> +# @name: VirtIODevice name
>> +#
>> +# @device-id: VirtIODevice ID
>> +#
>> +# @vhost-started: VirtIODevice vhost_started flag
>> +#
>> +# @guest-features: VirtIODevice guest_features
>> +#
>> +# @host-features: VirtIODevice host_features
>> +#
>> +# @backend-features: VirtIODevice backend_features
>> +#
>> +# @device-endian: VirtIODevice device_endian
>> +#
>> +# @num-vqs: VirtIODevice virtqueue count. This is the number of active
>> +#           virtqueues being used by the VirtIODevice.
>> +#
>> +# @status: VirtIODevice configuration status (e.g. DRIVER_OK,
>> +#          FEATURES_OK, DRIVER, etc.)
>> +#
>> +# @isr: VirtIODevice ISR
>> +#
>> +# @queue-sel: VirtIODevice queue_sel
>> +#
>> +# @vm-running: VirtIODevice vm_running flag
>> +#
>> +# @broken: VirtIODevice broken flag
>> +#
>> +# @disabled: VirtIODevice disabled flag
>> +#
>> +# @use-started: VirtIODevice use_started flag
>> +#
>> +# @started: VirtIODevice started flag
>> +#
>> +# @start-on-kick: VirtIODevice start_on_kick flag
>> +#
>> +# @disable-legacy-check: VirtIODevice disabled_legacy_check flag
>> +#
>> +# @bus-name: VirtIODevice bus_name
>> +#
>> +# @use-guest-notifier-mask: VirtIODevice use_guest_notifier_mask flag
>> +#
>> +# @vhost-dev: corresponding vhost device info for a given VirtIODevice
>> +#
>> +# Since: 6.2
>> +#
>> +##
>> +
>> +{ 'struct': 'VirtioStatus',
>> +    'data': {
>> +        'name': 'str',
>> +        'device-id': 'uint16',
>> +        'vhost-started': 'bool',
>> +        'guest-features': 'uint64',
>> +        'host-features': 'uint64',
>> +        'backend-features': 'uint64',
>> +        'device-endian': 'VirtioStatusEndianness',
>> +        'num-vqs': 'int',
>> +        'status': 'uint8',
>> +        'isr': 'uint8',
>> +        'queue-sel': 'uint16',
>> +        'vm-running': 'bool',
>> +        'broken': 'bool',
>> +        'disabled': 'bool',
>> +        'use-started': 'bool',
>> +        'started': 'bool',
>> +        'start-on-kick': 'bool',
>> +        'disable-legacy-check': 'bool',
>> +        'bus-name': 'str',
>> +        'use-guest-notifier-mask': 'bool',
>> +        'vhost-dev': 'VhostStatus'
>> +    }
>> +}
>> +
>> +##
>> +# @x-debug-virtio-status:
>> +#
>> +# Poll for a comprehensive status of a given virtio device
>> +#
>> +# @path: Canonical QOM path of the VirtIODevice
>> +#
>> +# Returns: VirtioStatus of the virtio device
>> +#
>> +# Since: 6.2
>> +#
>> +# Examples:
>> +#
>> +# 1. Poll for the status of virtio-crypto (no vhost-crypto active)
>> +#
>> +# -> { "execute": "x-debug-virtio-status",
>> +#      "arguments": {
>> +#          "path": "/machine/peripheral/crypto0/virtio-backend"
>> +#      }
>> +#    }
>> +# <- { "return": {
>> +#          "device-endian": "little",
>> +#          "bus-name": "",
>> +#          "disable-legacy-check": false,
>> +#          "name": "virtio-crypto",
>> +#          "started": true,
>> +#          "device-id": 20,
>> +#          "vhost-dev": {
>> +#               "n-tmp-sections": 0,
>> +#               "n-mem-sections": 0,
>> +#               "max-queues": 0,
>> +#               "backend-cap": 0,
>> +#               "log-size": 0,
>> +#               "backend-features": 0,
>> +#               "nvqs": 0,
>> +#               "protocol-features": 0,
>> +#               "vq-index": 0,
>> +#               "log-enabled": false,
>> +#               "acked-features": 0,
>> +#               "features": 0
>> +#          },
>> +#          "backend-features": 0,
>> +#          "start-on-kick": false,
>> +#          "isr": 1,
>> +#          "broken": false,
>> +#          "status": 15,
>> +#          "num-vqs": 2,
>> +#          "guest-features": 5100273664,
>> +#          "host-features": 6325010432,
>> +#          "use-guest-notifier-mask": true,
>> +#          "vm-running": true,
>> +#          "queue-sel": 1,
>> +#          "disabled": false,
>> +#          "vhost-started": false,
>> +#          "use-started": true
>> +#      }
>> +#    }
>> +#
>> +# 2. Poll for the status of virtio-net (vhost-net is active)
>> +#
>> +# -> { "execute": "x-debug-virtio-status",
>> +#      "arguments": {
>> +#          "path": "/machine/peripheral-anon/device[1]/virtio-backend"
>> +#      }
>> +#    }
>> +# <- { "return": {
>> +#          "device-endian": "little",
>> +#          "bus-name": "",
>> +#          "disabled-legacy-check": false,
>> +#          "name": "virtio-net",
>> +#          "started": true,
>> +#          "device-id": 1,
>> +#          "vhost-dev": {
>> +#               "n-tmp-sections": 4,
>> +#               "n-mem-sections": 4,
>> +#               "max-queues": 1,
>> +#               "backend-cap": 2,
>> +#               "log-size": 0,
>> +#               "backend-features": 0,
>> +#               "nvqs": 2,
>> +#               "protocol-features": 0,
>> +#               "vq-index": 0,
>> +#               "log-enabled": false,
>> +#               "acked-features": 5100306432,
>> +#               "features": 13908344832
>> +#          },
>> +#          "backend-features": 6337593319,
>> +#          "start-on-kick": false,
>> +#          "isr": 1,
>> +#          "broken": false,
>> +#          "status": 15,
>> +#          "num-vqs": 3,
>> +#          "guest-features": 5111807911,
>> +#          "host-features": 6337593319,
>> +#          "use-guest-notifier-mask": true,
>> +#          "vm-running": true,
>> +#          "queue-sel": 2,
>> +#          "disabled": false,
>> +#          "vhost-started": true,
>> +#          "use-started": true
>> +#      }
>> +#    }
>> +#
>> +##
>> +
>> +{ 'command': 'x-debug-virtio-status',
>> +  'data': { 'path': 'str' },
>> +  'returns': 'VirtioStatus'
>> +}
> Unstable commands now need to be marked with
>
>       'features': [ 'unstable' ]
>
> If you do that, the QAPI generator will demand documentation.  So add
>     
>     # Features:
>     # @unstable: This command is meant for debugging.
>
> You may want to grep for examples.  See also commit 9fb49daabf "qapi:
> Mark unstable QMP parts with feature 'unstable'".

Got it. I will add this in for all 'x-' related commands.

>
> Hmm, this command starts with x-debug-virtio-, wheras the one added in
> the previous commit starts with x-debug-query-virtio-.
>
> By conventions, commands that just return information on FOO are named
> query-FOO.  I recommend an x-query-virtio- prefix for your query
> commands.  We can leave their purpose (debug) to documentation.

Sure thing! I'll make this change.

>
Jonah
diff mbox series

Patch

diff --git a/hw/virtio/virtio-stub.c b/hw/virtio/virtio-stub.c
index d4a88f5..ddb592f 100644
--- a/hw/virtio/virtio-stub.c
+++ b/hw/virtio/virtio-stub.c
@@ -12,3 +12,8 @@  VirtioInfoList *qmp_x_debug_query_virtio(Error **errp)
 {
     return qmp_virtio_unsupported(errp);
 }
+
+VirtioStatus *qmp_x_debug_virtio_status(const char* path, Error **errp)
+{
+    return qmp_virtio_unsupported(errp);
+}
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index ad17be7..8d13d27 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -3933,6 +3933,102 @@  VirtioInfoList *qmp_x_debug_query_virtio(Error **errp)
     return list;
 }
 
+static VirtIODevice *virtio_device_find(const char *path)
+{
+    VirtIODevice *vdev;
+
+    QTAILQ_FOREACH(vdev, &virtio_list, next) {
+        DeviceState *dev = DEVICE(vdev);
+
+        if (strcmp(dev->canonical_path, path) != 0) {
+            continue;
+        }
+        return vdev;
+    }
+
+    return NULL;
+}
+
+VirtioStatus *qmp_x_debug_virtio_status(const char *path, Error **errp)
+{
+    VirtIODevice *vdev;
+    VirtioStatus *status;
+
+    vdev = virtio_device_find(path);
+    if (vdev == NULL) {
+        error_setg(errp, "Path %s is not a VirtIO device", path);
+        return NULL;
+    }
+
+    status = g_new0(VirtioStatus, 1);
+    status->vhost_dev = g_new0(VhostStatus, 1);
+    status->name = g_strdup(vdev->name);
+    status->device_id = vdev->device_id;
+    status->vhost_started = vdev->vhost_started;
+    status->guest_features = vdev->guest_features;
+    status->host_features = vdev->host_features;
+    status->backend_features = vdev->backend_features;
+
+    switch (vdev->device_endian) {
+    case VIRTIO_DEVICE_ENDIAN_LITTLE:
+        status->device_endian = VIRTIO_STATUS_ENDIANNESS_LITTLE;
+        break;
+    case VIRTIO_DEVICE_ENDIAN_BIG:
+        status->device_endian = VIRTIO_STATUS_ENDIANNESS_BIG;
+        break;
+    default:
+        status->device_endian = VIRTIO_STATUS_ENDIANNESS_UNKNOWN;
+        break;
+    }
+
+    status->num_vqs = virtio_get_num_queues(vdev);
+    status->status = vdev->status;
+    status->isr = vdev->isr;
+    status->queue_sel = vdev->queue_sel;
+    status->vm_running = vdev->vm_running;
+    status->broken = vdev->broken;
+    status->disabled = vdev->disabled;
+    status->use_started = vdev->use_started;
+    status->started = vdev->started;
+    status->start_on_kick = vdev->start_on_kick;
+    status->disable_legacy_check = vdev->disable_legacy_check;
+    status->bus_name = g_strdup(vdev->bus_name);
+    status->use_guest_notifier_mask = vdev->use_guest_notifier_mask;
+
+    if (vdev->vhost_started) {
+        VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
+        struct vhost_dev *hdev = vdc->get_vhost(vdev);
+
+        status->vhost_dev->n_mem_sections = hdev->n_mem_sections;
+        status->vhost_dev->n_tmp_sections = hdev->n_tmp_sections;
+        status->vhost_dev->nvqs = hdev->nvqs;
+        status->vhost_dev->vq_index = hdev->vq_index;
+        status->vhost_dev->features = hdev->features;
+        status->vhost_dev->acked_features = hdev->acked_features;
+        status->vhost_dev->backend_features = hdev->backend_features;
+        status->vhost_dev->protocol_features = hdev->protocol_features;
+        status->vhost_dev->max_queues = hdev->max_queues;
+        status->vhost_dev->backend_cap = hdev->backend_cap;
+        status->vhost_dev->log_enabled = hdev->log_enabled;
+        status->vhost_dev->log_size = hdev->log_size;
+    } else {
+        status->vhost_dev->n_mem_sections = 0;
+        status->vhost_dev->n_tmp_sections = 0;
+        status->vhost_dev->nvqs = 0;
+        status->vhost_dev->vq_index = 0;
+        status->vhost_dev->features = 0;
+        status->vhost_dev->acked_features = 0;
+        status->vhost_dev->backend_features = 0;
+        status->vhost_dev->protocol_features = 0;
+        status->vhost_dev->max_queues = 0;
+        status->vhost_dev->backend_cap = 0;
+        status->vhost_dev->log_enabled = false;
+        status->vhost_dev->log_size = 0;
+    }
+
+    return status;
+}
+
 static const TypeInfo virtio_device_info = {
     .name = TYPE_VIRTIO_DEVICE,
     .parent = TYPE_DEVICE,
diff --git a/qapi/virtio.json b/qapi/virtio.json
index 4490c2c..656a26f 100644
--- a/qapi/virtio.json
+++ b/qapi/virtio.json
@@ -65,3 +65,258 @@ 
 ##
 
 { 'command': 'x-debug-query-virtio', 'returns': ['VirtioInfo'] }
+
+##
+# @VirtioStatusEndianness:
+#
+# Enumeration of endianness for VirtioDevice
+#
+# Since: 6.2
+##
+
+{ 'enum': 'VirtioStatusEndianness',
+  'data': [ 'unknown', 'little', 'big' ]
+}
+
+##
+# @VhostStatus:
+#
+# Information about a vhost device. This information will only be
+# displayed if the vhost device is active.
+#
+# @n-mem-sections: vhost_dev n_mem_sections
+#
+# @n-tmp-sections: vhost_dev n_tmp_sections
+#
+# @nvqs: vhost_dev nvqs. This is the number of virtqueues being used
+#        by the vhost device.
+#
+# @vq-index: vhost_dev vq_index
+#
+# @features: vhost_dev features
+#
+# @acked-features: vhost_dev acked_features
+#
+# @backend-features: vhost_dev backend_features
+#
+# @protocol-features: vhost_dev protocol_features
+#
+# @max-queues: vhost_dev max_queues
+#
+# @backend-cap: vhost_dev backend_cap
+#
+# @log-enabled: vhost_dev log_enabled flag
+#
+# @log-size: vhost_dev log_size
+#
+# Since: 6.2
+#
+##
+
+{ 'struct': 'VhostStatus',
+    'data': {
+        'n-mem-sections': 'int',
+        'n-tmp-sections': 'int',
+        'nvqs': 'uint32',
+        'vq-index': 'int',
+        'features': 'uint64',
+        'acked-features': 'uint64',
+        'backend-features': 'uint64',
+        'protocol-features': 'uint64',
+        'max-queues': 'uint64',
+        'backend-cap': 'uint64',
+        'log-enabled': 'bool',
+        'log-size': 'uint64'
+    }
+}
+
+##
+# @VirtioStatus:
+#
+# Full status of the virtio device with most VirtIODevice members.
+# Also includes the full status of the corresponding vhost device
+# if the vhost device is active.
+#
+# @name: VirtIODevice name
+#
+# @device-id: VirtIODevice ID
+#
+# @vhost-started: VirtIODevice vhost_started flag
+#
+# @guest-features: VirtIODevice guest_features
+#
+# @host-features: VirtIODevice host_features
+#
+# @backend-features: VirtIODevice backend_features
+#
+# @device-endian: VirtIODevice device_endian
+#
+# @num-vqs: VirtIODevice virtqueue count. This is the number of active
+#           virtqueues being used by the VirtIODevice.
+#
+# @status: VirtIODevice configuration status (e.g. DRIVER_OK,
+#          FEATURES_OK, DRIVER, etc.)
+#
+# @isr: VirtIODevice ISR
+#
+# @queue-sel: VirtIODevice queue_sel
+#
+# @vm-running: VirtIODevice vm_running flag
+#
+# @broken: VirtIODevice broken flag
+#
+# @disabled: VirtIODevice disabled flag
+#
+# @use-started: VirtIODevice use_started flag
+#
+# @started: VirtIODevice started flag
+#
+# @start-on-kick: VirtIODevice start_on_kick flag
+#
+# @disable-legacy-check: VirtIODevice disabled_legacy_check flag
+#
+# @bus-name: VirtIODevice bus_name
+#
+# @use-guest-notifier-mask: VirtIODevice use_guest_notifier_mask flag
+#
+# @vhost-dev: corresponding vhost device info for a given VirtIODevice
+#
+# Since: 6.2
+#
+##
+
+{ 'struct': 'VirtioStatus',
+    'data': {
+        'name': 'str',
+        'device-id': 'uint16',
+        'vhost-started': 'bool',
+        'guest-features': 'uint64',
+        'host-features': 'uint64',
+        'backend-features': 'uint64',
+        'device-endian': 'VirtioStatusEndianness',
+        'num-vqs': 'int',
+        'status': 'uint8',
+        'isr': 'uint8',
+        'queue-sel': 'uint16',
+        'vm-running': 'bool',
+        'broken': 'bool',
+        'disabled': 'bool',
+        'use-started': 'bool',
+        'started': 'bool',
+        'start-on-kick': 'bool',
+        'disable-legacy-check': 'bool',
+        'bus-name': 'str',
+        'use-guest-notifier-mask': 'bool',
+        'vhost-dev': 'VhostStatus'
+    }
+}
+
+##
+# @x-debug-virtio-status:
+#
+# Poll for a comprehensive status of a given virtio device
+#
+# @path: Canonical QOM path of the VirtIODevice
+#
+# Returns: VirtioStatus of the virtio device
+#
+# Since: 6.2
+#
+# Examples:
+#
+# 1. Poll for the status of virtio-crypto (no vhost-crypto active)
+#
+# -> { "execute": "x-debug-virtio-status",
+#      "arguments": {
+#          "path": "/machine/peripheral/crypto0/virtio-backend"
+#      }
+#    }
+# <- { "return": {
+#          "device-endian": "little",
+#          "bus-name": "",
+#          "disable-legacy-check": false,
+#          "name": "virtio-crypto",
+#          "started": true,
+#          "device-id": 20,
+#          "vhost-dev": {
+#               "n-tmp-sections": 0,
+#               "n-mem-sections": 0,
+#               "max-queues": 0,
+#               "backend-cap": 0,
+#               "log-size": 0,
+#               "backend-features": 0,
+#               "nvqs": 0,
+#               "protocol-features": 0,
+#               "vq-index": 0,
+#               "log-enabled": false,
+#               "acked-features": 0,
+#               "features": 0
+#          },
+#          "backend-features": 0,
+#          "start-on-kick": false,
+#          "isr": 1,
+#          "broken": false,
+#          "status": 15,
+#          "num-vqs": 2,
+#          "guest-features": 5100273664,
+#          "host-features": 6325010432,
+#          "use-guest-notifier-mask": true,
+#          "vm-running": true,
+#          "queue-sel": 1,
+#          "disabled": false,
+#          "vhost-started": false,
+#          "use-started": true
+#      }
+#    }
+#
+# 2. Poll for the status of virtio-net (vhost-net is active)
+#
+# -> { "execute": "x-debug-virtio-status",
+#      "arguments": {
+#          "path": "/machine/peripheral-anon/device[1]/virtio-backend"
+#      }
+#    }
+# <- { "return": {
+#          "device-endian": "little",
+#          "bus-name": "",
+#          "disabled-legacy-check": false,
+#          "name": "virtio-net",
+#          "started": true,
+#          "device-id": 1,
+#          "vhost-dev": {
+#               "n-tmp-sections": 4,
+#               "n-mem-sections": 4,
+#               "max-queues": 1,
+#               "backend-cap": 2,
+#               "log-size": 0,
+#               "backend-features": 0,
+#               "nvqs": 2,
+#               "protocol-features": 0,
+#               "vq-index": 0,
+#               "log-enabled": false,
+#               "acked-features": 5100306432,
+#               "features": 13908344832
+#          },
+#          "backend-features": 6337593319,
+#          "start-on-kick": false,
+#          "isr": 1,
+#          "broken": false,
+#          "status": 15,
+#          "num-vqs": 3,
+#          "guest-features": 5111807911,
+#          "host-features": 6337593319,
+#          "use-guest-notifier-mask": true,
+#          "vm-running": true,
+#          "queue-sel": 2,
+#          "disabled": false,
+#          "vhost-started": true,
+#          "use-started": true
+#      }
+#    }
+#
+##
+
+{ 'command': 'x-debug-virtio-status',
+  'data': { 'path': 'str' },
+  'returns': 'VirtioStatus'
+}