[PATCH v15 0/6] hmp,qmp: Add commands to introspect virtio devices

Jonah Palmer posted 6 patches 1 year, 8 months ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/1660220684-24909-1-git-send-email-jonah.palmer@oracle.com
Maintainers: "Dr. David Alan Gilbert" <dgilbert@redhat.com>, "Michael S. Tsirkin" <mst@redhat.com>, Markus Armbruster <armbru@redhat.com>, Michael Roth <michael.roth@amd.com>, Eric Blake <eblake@redhat.com>, Thomas Huth <thuth@redhat.com>, Laurent Vivier <lvivier@redhat.com>, Paolo Bonzini <pbonzini@redhat.com>
hmp-commands-info.hx       |   70 +++
hw/virtio/meson.build      |    2 +
hw/virtio/virtio-stub.c    |   42 ++
hw/virtio/virtio.c         | 1032 ++++++++++++++++++++++++++++++++++++
include/hw/virtio/vhost.h  |    3 +
include/hw/virtio/virtio.h |    6 +
include/monitor/hmp.h      |    5 +
monitor/hmp-cmds.c         |  310 +++++++++++
qapi/meson.build           |    1 +
qapi/qapi-schema.json      |    1 +
qapi/virtio.json           |  954 +++++++++++++++++++++++++++++++++
tests/qtest/qmp-cmd-test.c |    1 +
12 files changed, 2427 insertions(+)
create mode 100644 hw/virtio/virtio-stub.c
create mode 100644 qapi/virtio.json
[PATCH v15 0/6] hmp,qmp: Add commands to introspect virtio devices
Posted by Jonah Palmer 1 year, 8 months ago
This series introduces new QMP/HMP commands to dump the status of a
virtio device at different levels.

[Jonah: Rebasing from previous patchset from Apr. 1 (v14). Original patches
 are by Laurent Vivier from May 2020.

 I sincerely apologize for the *massive* delay in getting this latest v15
 series out. It was a perferct storm of other more pressing issues, time off,
 and trying to understand why I was seeing this 30 feature bit in my PCI virtio
 devices. Please see patch 3/6 for more explanation on this issue.

 Rebase from v14 to v15 includes: adding the missing sign-off-by from the poster,
 renaming & moving all virtio device feature map definitions to hw/virtio/virtio.c,
 including brief descriptions for all status & feature bits, a new virtio device
 feature map defined for virtio-rng, and mappings for virtio/vhost-vsock,
 virtio-iommu, virtio-mem, and virtio transport features updated with their
 newest feature bits. Most of these changes can be found in patch 3/6.

 And again, sorry for the long wait on this.]


1. List available virtio devices in the machine

HMP Form:

    info virtio

    Example:

        (qemu) info virtio
        /machine/peripheral-anon/device[2]/virtio-backend [virtio-scsi]
        /machine/peripheral/vsock0/virtio-backend [vhost-vsock]
        /machine/peripheral/crypto0/virtio-backend [virtio-crypto]
        /machine/peripheral-anon/device[1]/virtio-backend [virtio-net]
        /machine/peripheral-anon/device[0]/virtio-backend [virtio-serial]

QMP Form:

    { 'command': 'x-query-virtio',
      'returns': ['VirtioInfo'],
      'features': [ 'unstable' ] }

    Example:

        -> { "execute": "x-query-virtio" }
        <- { "return": [
                 {
                     "name": "virtio-scsi",
                     "path": "/machine/peripheral-anon/device[2]/virtio-backend"
                 },
                 {
                     "name": "vhost-vsock",
                     "path": "/machine/peripheral/vsock0/virtio-backend"
                 },
                 {
                     "name": "virtio-crypto",
                     "path": "/machine/peripheral/crypto0/virtio-backend"
                 },
                 {
                     "name": "virtio-net",
                     "path": "/machine/peripheral-anon/device[1]/virtio-backend"
                 },
                 {
                     "name": "virtio-serial",
                     "path": "/machine/peripheral-anon/device[0]/virtio-backend"
                 }
             ]
           }

2. Display status of a given virtio device

HMP Form:

    info virtio-status <path>

    Example:

        (qemu) info virtio-status /machine/peripheral/vsock0/virtio-backend
        /machine/peripheral/vsock0/virtio-backend:
          device_name:             vhost-vsock (vhost)
          device_id:               19
          vhost_started:           true
          bus_name:                (null)
          broken:                  false
          disabled:                false
          disable_legacy_check:    false
          started:                 true
          use_started:             true
          start_on_kick:           false
          use_guest_notifier_mask: true
          vm_running:              true
          num_vqs:                 3
          queue_sel:               2
          isr:                     0
          endianness:              little
          status:
        	VIRTIO_CONFIG_S_ACKNOWLEDGE: Valid virtio device found,
	        VIRTIO_CONFIG_S_DRIVER: Guest OS compatible with device,
	        VIRTIO_CONFIG_S_FEATURES_OK: Feature negotiation complete,
	        VIRTIO_CONFIG_S_DRIVER_OK: Driver setup and ready
          Guest features:
	        VIRTIO_RING_F_EVENT_IDX: Used & avail. event fields enabled,
	        VIRTIO_RING_F_INDIRECT_DESC: Indirect descriptors supported,
	        VIRTIO_F_VERSION_1: Device compliant for v1 spec (legacy)
          Host features:
	        VIRTIO_RING_F_EVENT_IDX: Used & avail. event fields enabled,
	        VIRTIO_RING_F_INDIRECT_DESC: Indirect descriptors supported,
	        VIRTIO_F_VERSION_1: Device compliant for v1 spec (legacy),
	        VIRTIO_F_ANY_LAYOUT: Device accepts arbitrary desc. layouts,
	        VIRTIO_F_NOTIFY_ON_EMPTY: Notify when device runs out of avail. descs. on VQ
	        VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features negotiation supported
          Backend features:

          VHost:
              nvqs:           2
              vq_index:       0
              max_queues:     0
              n_mem_sections: 4
              n_tmp_sections: 4
              backend_cap:    0
              log_enabled:    false
              log_size:       0
              Features:
	          VIRTIO_RING_F_EVENT_IDX: Used & avail. event fields enabled,
	          VIRTIO_RING_F_INDIRECT_DESC: Indirect descriptors supported,
	          VIRTIO_F_VERSION_1: Device compliant for v1 spec (legacy),
	          VIRTIO_F_ANY_LAYOUT: Device accepts arbitrary desc. layouts,
	          VIRTIO_F_NOTIFY_ON_EMPTY: Notify when device runs out of avail. descs. on VQ
	          VHOST_F_LOG_ALL: Logging write descriptors supported
              Acked features:
	          VIRTIO_RING_F_EVENT_IDX: Used & avail. event fields enabled,
	          VIRTIO_RING_F_INDIRECT_DESC: Indirect descriptors supported,
	          VIRTIO_F_VERSION_1: Device compliant for v1 spec (legacy)
              Backend features:

              Protocol features:

QMP Form:

    { 'command': 'x-query-virtio-status',
      'data': { 'path': 'str' },
      'returns': 'VirtioStatus',
      'features': [ 'unstable' ] }

    Example:

        -> { "execute": "x-query-virtio-status",
             "arguments": { "path": "/machine/peripheral/vsock0/virtio-backend" }
           }
        <- { "return": {
                 "device-endian": "little",
                 "bus-name": "",
                 "disable-legacy-check": false,
                 "name": "vhost-vsock",
                 "started": true,
                 "device-id": 19,
                 "vhost-dev": {
                     "n-tmp-sections": 4,
                     "n-mem-sections": 4,
                     "max-queues": 0,
                     "backend-cap": 0,
                     "log-size": 0,
                     "backend-features": {
                         "dev-features": [
                         ],
                         "transports": [
                         ]
                     },
                     "nvqs": 2,
                     "protocol-features": {
                         "protocols": [
                         ]
                     },
                     "vq-index": 0,
                     "log-enabled": false,
                     "acked-features": {
                         "dev-features": [
                         ],
                         "transports": [
                             "VIRTIO_RING_F_EVENT_IDX: Used & avail. event fields enabled",
                             "VIRTIO_RING_F_INDIRECT_DESC: Indirect descriptors supported",
                             "VIRTIO_F_VERSION_1: Device compliant for v1 spec (legacy)"
                         ]
                     },
                     "features": {
                         "dev-features": [
                             "VHOST_F_LOG_ALL: Logging write descriptors supported"
                         ],
                         "transports": [
                             "VIRTIO_RING_F_EVENT_IDX: Used & avail. event fields enabled",
                             "VIRTIO_RING_F_INDIRECT_DESC: Indirect descriptors supported",
                             "VIRTIO_F_VERSION_1: Device compliant for v1 spec (legacy)",
                             "VIRTIO_F_ANY_LAYOUT: Device accepts arbitrary desc. layouts",
                             "VIRTIO_F_NOTIFY_ON_EMPTY: Notify when device runs out of avail. descs. on VQ"
                         ]
                     }
                 },
                 "backend-features": {
                     "dev-features": [
                     ],
                     "transports": [
                     ]
                 },
                 "start-on-kick": false,
                 "isr": 0,
                 "broken": false,
                 "status": {
                     "statuses": [
                         "VIRTIO_CONFIG_S_ACKNOWLEDGE: Valid virtio device found",
                         "VIRTIO_CONFIG_S_DRIVER: Guest OS compatible with device",
                         "VIRTIO_CONFIG_S_FEATURES_OK: Feature negotiation complete",
                         "VIRTIO_CONFIG_S_DRIVER_OK: Driver setup and ready"
                     ]
                 },
                 "num-vqs": 3,
                 "guest-features": {
                     "dev-features": [
                     ],
                     "transports": [
                         "VIRTIO_RING_F_EVENT_IDX: Used & avail. event fields enabled",
                         "VIRTIO_RING_F_INDIRECT_DESC: Indirect descriptors supported",
                         "VIRTIO_F_VERSION_1: Device compliant for v1 spec (legacy)"
                     ]
                 },
                 "host-features": {
                     "dev-features": [
                         "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features negotiation supported"
                     ],
                     "transports": [
                         "VIRTIO_RING_F_EVENT_IDX: Used & avail. event fields enabled",
                         "VIRTIO_RING_F_INDIRECT_DESC: Indirect descriptors supported",
                         "VIRTIO_F_VERSION_1: Device compliant for v1 spec (legacy)",
                         "VIRTIO_F_ANY_LAYOUT: Device accepts arbitrary desc. layouts",
                         "VIRTIO_F_NOTIFY_ON_EMPTY: Notify when device runs out of avail. descs. on VQ"
                     ]
                 },
                 "use-guest-notifier-mask": true,
                 "vm-running": true,
                 "queue-sel": 2,
                 "disabled": false,
                 "vhost-started": true,
                 "use-started": true
             }
           }

3. Display status of a given virtio queue

HMP Form:

    info virtio-queue-status <path> <queue>

    Example:

        (qemu) info virtio-queue-status /machine/peripheral-anon/device[1]/virtio-backend 2
        /machine/peripheral-anon/device[1]/virtio-backend:
          device_name:          virtio-net
          queue_index:          2
          inuse:                0
          used_idx:             15
          signalled_used:       15
          signalled_used_valid: true
          VRing:
            num:          64
            num_default:  64
            align:        4096
            desc:         0x000000011e15c000
            avail:        0x000000011e15c400
            used:         0x000000011e15c4c0

QMP Form:

    { 'command': 'x-query-virtio-queue-status',
      'data': { 'path': 'str', 'queue': 'uint16' },
      'returns': 'VirtQueueStatus',
      'features': [ 'unstable' ] }

    Example:

        -> { "execute": "x-query-virtio-queue-status",
             "arguments": { "path": "/machine/peripheral-anon/device[1]/virtio-backend",
                            "queue": 2 }
           }
        <- { "return": {
                 "signalled-used": 15,
                 "inuse": 0,
                 "name": "virtio-net",
                 "vring-align": 4096,
                 "vring-desc": 4814004224,
                 "signalled-used-valid": true,
                 "vring-num-default": 64,
                 "vring-avail": 4814005248,
                 "queue-index": 2,
                 "vring-used": 4814005440,
                 "used-idx": 15,
                 "vring-num": 64
             }
           }

4. Display status of a given vhost queue

HMP Form:

    info virtio-vhost-queue-status <path> <queue>

    Example:

        (qemu) info virtio-vhost-queue-status /machine/peripheral-anon/device[1]/virtio-backend 1
        /machine/peripheral-anon/device[1]/virtio-backend:
          device_name:          virtio-net (vhost)
          kick:                 0
          call:                 0
          VRing:
            num:         256
            desc:        0x00007f804df5a000
            desc_phys:   0x000000013315a000
            desc_size:   4096
            avail:       0x00007f804df5b000
            avail_phys:  0x000000013315b000
            avail_size:  518
            used:        0x00007f804df5b240
            used_phys:   0x000000013315b240
            used_size:   2054

QMP Form:

    { 'command': 'x-query-virtio-vhost-queue-status',
      'data': { 'path': 'str', 'queue': 'uint16' },
      'returns': 'VirtVhostQueueStatus',
      'features': [ 'unstable' ] }

    Example:

        -> { "execute": "x-query-virtio-vhost-queue-status",
             "arguments": { "path": "/machine/peripheral-anon/device[1]/virtio-backend",
                            "queue": 1 }
           }
        <- { "return": {
                 "avail-phys": 4803538944,
                 "name": "virtio-net",
                 "used-phys": 4803539520,
                 "avail-size": 518,
                 "desc-size": 4096,
                 "used-size": 2054,
                 "desc": 140186477404160,
                 "num": 256,
                 "call": 0,
                 "avail": 140186477408256,
                 "desc-phys": 4803534848,
                 "used": 140186477408832,
                 "kick": 0
             }
           }

5. Display an element of a given virtio queue

HMP Form:

    info virtio-queue-element <path> <queue> [index]

    Example:

        Dump the information of the head element of the third queue of virtio-scsi:

        (qemu) info virtio-queue-element /machine/peripheral-anon/device[2]/virtio-backend 2
        /machine/peripheral-anon/device[2]/virtio-backend:
          device_name: virtio-scsi
          index:   0
          desc:
            descs:
                addr 0x128890000 len 12288 (write),
                addr 0x128880000 len 65536 (write, next),
                addr 0x128870000 len 65536 (write, next),
                addr 0x128860000 len 65536 (write, next),
                addr 0x128850000 len 65536 (write, next),
                addr 0x128840000 len 65536 (write, next),
                addr 0x128830000 len 65536 (write, next),
                addr 0x128820000 len 65536 (write, next),
                addr 0x128810000 len 65536 (write, next),
                addr 0x128800000 len 65536 (write, next),
                addr 0x116bf3000 len 53248 (write, next),
                addr 0x116be3000 len 65536 (write, next),
                addr 0x116bd3000 len 65536 (write, next),
                addr 0x116bc3000 len 65536 (write, next),
                addr 0x116bb3000 len 65536 (write, next),
                addr 0x116ba3000 len 65536 (write, next),
                addr 0x116b93000 len 65536 (write, next),
                addr 0x116b83000 len 65536 (write, next),
                addr 0x116b73000 len 65536 (write, next),
                addr 0x116b63000 len 65536 (write, next),
                addr 0x116b53000 len 65536 (write, next),
                addr 0x126e9763b len 108 (write, next),
                addr 0x9af8dae7222881a2 len 51 (next)
          avail:
            flags: 0
            idx:   600
            ring:  0
          used:
            flags: 0
            idx:   600

QMP Form:

    { 'command': 'x-query-virtio-queue-element',
      'data': { 'path': 'str', 'queue': 'uint16', '*index': 'uint16' },
      'returns': 'VirtioQueueElement',
      'features': [ 'unstable' ] }

    Example:

        -> { "execute": "x-query-virtio-queue-element",
             "arguments": { "path": "/machine/peripheral-anon/device[2]/virtio-backend",
                            "queue": 2 }
           }
        <- { "return": {
                 "index": 1,
                 "name": "virtio-scsi",
                 "descs": [
                     {
                         "flags": ["write"],
                         "len": 65536,
                         "addr": 4852740096
                     },
                     {
                         "flags": ["write", "next"],
                         "len": 65536,
                         "addr": 4852674560
                     },
                     {
                         "flags": ["write", "next"],
                         "len": 65536,
                         "addr": 4852609024
                     },
                     {
                         "flags": ["write", "next"],
                         "len": 65536,
                         "addr": 4852543488
                     },
                     {
                         "flags": ["write", "next"],
                         "len": 65536,
                         "addr": 4852477952
                     },
                     {
                         "flags": ["write", "next"],
                         "len": 65536,
                         "addr": 4852412416
                     },
                     {
                         "flags": ["write", "next"],
                         "len": 65536,
                         "addr": 4852346880
                     },
                     {
                         "flags": ["write", "next"],
                         "len": 65536,
                         "addr": 4852281344
                     },
                     {
                         "flags": ["write", "next"],
                         "len": 65536,
                         "addr": 4852215808
                     },
                     {
                         "flags": ["write", "next"],
                         "len": 65536,
                         "addr": 4852150272
                     },
                     {
                         "flags": ["write", "next"],
                         "len": 65536,
                         "addr": 4852084736
                     },
                     {
                         "flags": ["write", "next"],
                         "len": 65536,
                         "addr": 4852019200
                     },
                     {
                         "flags": ["write", "next"],
                         "len": 65536,
                         "addr": 4851953664
                     },
                     {
                         "flags": ["write", "next"],
                         "len": 65536,
                         "addr": 4851888128
                     },
                     {
                         "flags": ["write", "next"],
                         "len": 65536,
                         "addr": 4851822592
                     },
                     {
                         "flags": ["write", "next"],
                         "len": 65536,
                         "addr": 4851757056
                     },
                     {
                         "flags": ["write", "next"],
                         "len": 65536,
                         "addr": 4851691520
                     },
                     {
                         "flags": ["write", "next"],
                         "len": 65536,
                         "addr": 4851625984
                     },
                     {
                         "flags": ["write", "next"],
                         "len": 65536,
                         "addr": 4851560448
                     },
                     {
                         "flags": ["write", "next"],
                         "len": 65536,
                         "addr": 4851494912
                     },
                     {
                         "flags": ["write", "next"],
                         "len": 108,
                         "addr": 4801325435
                     },
                     {
                         "flags": ["next"],
                         "len": 51,
                         "addr": 12075758188190198449
                     }
                 ],
                 "avail": {
                     "idx": 922,
                     "flags": 0,
                     "ring": 1
                 },
                 "used": {
                     "idx": 922,
                     "flags": 0
                 }
             }
           }

v15: added missing sign-off in patches
     rebased for upstream (Qemu 7.1)
     minor reformatting to examples in qapi/virtio.json
     virtio device feature maps moved to hw/virtio/virtio.c
     virtio device feature maps renamed (less generic)
     virtio device feature maps now include brief description of feature
     virtio device status map now include brief description of status
     new feature bits added to mappings for virtio/vhost-vsock,
     virtio-iommu, & virtio-mem
     new virtio transport feature bit added to mapping
     new virtio device feature map defined for virtio-rng

v14: move definition of 'gpu_map' to virtio-gpu.c
     add new 'context-init' virtio-gpu feature
     created new feature map 'i2c_map' for vhost-user-i2c
     fixed casting error for cross-Win64 builds

v13: minor text edit in qapi/virtio.json

v12: minor reformatting for monitor/hmp-cmds.c
     use PRI types in virtio hmp monitor printfs

v11: minor reformatting in virtio.json
     added synchronicity check when querying virtio devices

v10: rebased for upstream (Qemu 7.0)
     reformat virtio.json for better consistency
     removed all enums from virtio.json; replaced with string literals
     removed @ndescs from VirtioQueueElement
     removed examples in hmp-commands-info.hx (to fix 'inconsistent
     literal block quoting' error from Sphinx)

v9: rebased for upstream (Qemu 6.3)
    change QMP command prefixes from 'x-debug-virtio' to
    'x-query-virtio'
    add 'unstable' feature to all 'x-query-virtio' prefixed
    QMP commands
    fix odd indentation for qapi/virtio.json
    device features support for virtio-mem
    move HMP sub-commands under 'virtio' top level to 'info'
    top level

v8: add assert in virtio_id_to_name() to make sure we're
    not returning NULL
    minor documentation additions to qapi/virtio.json
    add virtio introspection support for vhost-user-rng

v7: rebased for upstream (Qemu 6.2)
    add ability to map between numberic device ID and
    string device ID (name) for virtio devices
    add get_vhost() callback function for VirtIODevices
    expose more fields of VirtIODevice
    expose fields of vhost devices
    decode vhost user protocol features
    decode VirtIODevice configuration statuses
    vhost support for displaying virtio queue statuses
    vhost support for displaying vhost queue statuses
    expose driver and device areas when introspecting a
    virtio queue element
    changed patch attribution

v6: rebased for upstream (Qemu 6.1)
    add all virtio/vhost types in same order as
    include/standard-headers/linux/virtio_ids.h
    use QAPI_LIST_PREPEND in qmp_x_debug_query_virtio rather than open
    coding

v5: rebased for upstream
    add device name, used index, and relative indicies to virtio queue-status
    HMP command
    add device name to virtio queue-status QMP command
    add new virtio device features

v4: re-send series as v3 didn't reach qemu-devel

v3: use qapi_free_VirtioInfoList() on the head of the list, not on the tail.
    Prefix the QMP commands with 'x-debug-'

v2: introduce VirtioType enum
    use an enum for the endianness
    change field names to stick to naming convertions (s/_/-/)
    add a patch to decode feature bits
    don't check if the queue is empty to allow display of old elements
    use enum for desc flags
    manage indirect desc
    decode device features in the HMP command

Laurent Vivier (6):
  qmp: add QMP command x-query-virtio
  qmp: add QMP command x-query-virtio-status
  qmp: decode feature & status bits in virtio-status
  qmp: add QMP commands for virtio/vhost queue-status
  qmp: add QMP command x-query-virtio-queue-element
  hmp: add virtio commands

 hmp-commands-info.hx       |   70 +++
 hw/virtio/meson.build      |    2 +
 hw/virtio/virtio-stub.c    |   42 ++
 hw/virtio/virtio.c         | 1032 ++++++++++++++++++++++++++++++++++++
 include/hw/virtio/vhost.h  |    3 +
 include/hw/virtio/virtio.h |    6 +
 include/monitor/hmp.h      |    5 +
 monitor/hmp-cmds.c         |  310 +++++++++++
 qapi/meson.build           |    1 +
 qapi/qapi-schema.json      |    1 +
 qapi/virtio.json           |  954 +++++++++++++++++++++++++++++++++
 tests/qtest/qmp-cmd-test.c |    1 +
 12 files changed, 2427 insertions(+)
 create mode 100644 hw/virtio/virtio-stub.c
 create mode 100644 qapi/virtio.json

-- 
2.31.1
Re: [PATCH v15 0/6] hmp,qmp: Add commands to introspect virtio devices
Posted by Jonah Palmer 1 year, 6 months ago
Hey Michael, when you get the chance, could you review these patches for me? Specifically patch 3/6, as that has the majority of the changes made for this series. Thanks!

Jonah
________________________________
From: Jonah Palmer
Sent: Thursday, August 11, 2022 8:26 AM
To: qemu-devel@nongnu.org <qemu-devel@nongnu.org>
Cc: mst@redhat.com <mst@redhat.com>; qemu_oss@crudebyte.com <qemu_oss@crudebyte.com>; kraxel@redhat.com <kraxel@redhat.com>; Si-Wei Liu <si-wei.liu@oracle.com>; Joao Martins <joao.m.martins@oracle.com>; eblake@redhat.com <eblake@redhat.com>; qemu-block@nongnu.org <qemu-block@nongnu.org>; david@redhat.com <david@redhat.com>; armbru@redhat.com <armbru@redhat.com>; arei.gonglei@huawei.com <arei.gonglei@huawei.com>; marcandre.lureau@redhat.com <marcandre.lureau@redhat.com>; lvivier@redhat.com <lvivier@redhat.com>; thuth@redhat.com <thuth@redhat.com>; michael.roth@amd.com <michael.roth@amd.com>; groug@kaod.org <groug@kaod.org>; dgilbert@redhat.com <dgilbert@redhat.com>; eric.auger@redhat.com <eric.auger@redhat.com>; stefanha@redhat.com <stefanha@redhat.com>; Boris Ostrovsky <boris.ostrovsky@oracle.com>; kwolf@redhat.com <kwolf@redhat.com>; mathieu.poirier@linaro.org <mathieu.poirier@linaro.org>; raphael.norwitz@nutanix.com <raphael.norwitz@nutanix.com>; pbonzini@redhat.com <pbonzini@redhat.com>
Subject: [PATCH v15 0/6] hmp,qmp: Add commands to introspect virtio devices

This series introduces new QMP/HMP commands to dump the status of a
virtio device at different levels.

[Jonah: Rebasing from previous patchset from Apr. 1 (v14). Original patches
 are by Laurent Vivier from May 2020.

 I sincerely apologize for the *massive* delay in getting this latest v15
 series out. It was a perferct storm of other more pressing issues, time off,
 and trying to understand why I was seeing this 30 feature bit in my PCI virtio
 devices. Please see patch 3/6 for more explanation on this issue.

 Rebase from v14 to v15 includes: adding the missing sign-off-by from the poster,
 renaming & moving all virtio device feature map definitions to hw/virtio/virtio.c,
 including brief descriptions for all status & feature bits, a new virtio device
 feature map defined for virtio-rng, and mappings for virtio/vhost-vsock,
 virtio-iommu, virtio-mem, and virtio transport features updated with their
 newest feature bits. Most of these changes can be found in patch 3/6.

 And again, sorry for the long wait on this.]


1. List available virtio devices in the machine

HMP Form:

    info virtio

    Example:

        (qemu) info virtio
        /machine/peripheral-anon/device[2]/virtio-backend [virtio-scsi]
        /machine/peripheral/vsock0/virtio-backend [vhost-vsock]
        /machine/peripheral/crypto0/virtio-backend [virtio-crypto]
        /machine/peripheral-anon/device[1]/virtio-backend [virtio-net]
        /machine/peripheral-anon/device[0]/virtio-backend [virtio-serial]

QMP Form:

    { 'command': 'x-query-virtio',
      'returns': ['VirtioInfo'],
      'features': [ 'unstable' ] }

    Example:

        -> { "execute": "x-query-virtio" }
        <- { "return": [
                 {
                     "name": "virtio-scsi",
                     "path": "/machine/peripheral-anon/device[2]/virtio-backend"
                 },
                 {
                     "name": "vhost-vsock",
                     "path": "/machine/peripheral/vsock0/virtio-backend"
                 },
                 {
                     "name": "virtio-crypto",
                     "path": "/machine/peripheral/crypto0/virtio-backend"
                 },
                 {
                     "name": "virtio-net",
                     "path": "/machine/peripheral-anon/device[1]/virtio-backend"
                 },
                 {
                     "name": "virtio-serial",
                     "path": "/machine/peripheral-anon/device[0]/virtio-backend"
                 }
             ]
           }

2. Display status of a given virtio device

HMP Form:

    info virtio-status <path>

    Example:

        (qemu) info virtio-status /machine/peripheral/vsock0/virtio-backend
        /machine/peripheral/vsock0/virtio-backend:
          device_name:             vhost-vsock (vhost)
          device_id:               19
          vhost_started:           true
          bus_name:                (null)
          broken:                  false
          disabled:                false
          disable_legacy_check:    false
          started:                 true
          use_started:             true
          start_on_kick:           false
          use_guest_notifier_mask: true
          vm_running:              true
          num_vqs:                 3
          queue_sel:               2
          isr:                     0
          endianness:              little
          status:
         VIRTIO_CONFIG_S_ACKNOWLEDGE: Valid virtio device found,
                VIRTIO_CONFIG_S_DRIVER: Guest OS compatible with device,
                VIRTIO_CONFIG_S_FEATURES_OK: Feature negotiation complete,
                VIRTIO_CONFIG_S_DRIVER_OK: Driver setup and ready
          Guest features:
                VIRTIO_RING_F_EVENT_IDX: Used & avail. event fields enabled,
                VIRTIO_RING_F_INDIRECT_DESC: Indirect descriptors supported,
                VIRTIO_F_VERSION_1: Device compliant for v1 spec (legacy)
          Host features:
                VIRTIO_RING_F_EVENT_IDX: Used & avail. event fields enabled,
                VIRTIO_RING_F_INDIRECT_DESC: Indirect descriptors supported,
                VIRTIO_F_VERSION_1: Device compliant for v1 spec (legacy),
                VIRTIO_F_ANY_LAYOUT: Device accepts arbitrary desc. layouts,
                VIRTIO_F_NOTIFY_ON_EMPTY: Notify when device runs out of avail. descs. on VQ
                VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features negotiation supported
          Backend features:

          VHost:
              nvqs:           2
              vq_index:       0
              max_queues:     0
              n_mem_sections: 4
              n_tmp_sections: 4
              backend_cap:    0
              log_enabled:    false
              log_size:       0
              Features:
                  VIRTIO_RING_F_EVENT_IDX: Used & avail. event fields enabled,
                  VIRTIO_RING_F_INDIRECT_DESC: Indirect descriptors supported,
                  VIRTIO_F_VERSION_1: Device compliant for v1 spec (legacy),
                  VIRTIO_F_ANY_LAYOUT: Device accepts arbitrary desc. layouts,
                  VIRTIO_F_NOTIFY_ON_EMPTY: Notify when device runs out of avail. descs. on VQ
                  VHOST_F_LOG_ALL: Logging write descriptors supported
              Acked features:
                  VIRTIO_RING_F_EVENT_IDX: Used & avail. event fields enabled,
                  VIRTIO_RING_F_INDIRECT_DESC: Indirect descriptors supported,
                  VIRTIO_F_VERSION_1: Device compliant for v1 spec (legacy)
              Backend features:

              Protocol features:

QMP Form:

    { 'command': 'x-query-virtio-status',
      'data': { 'path': 'str' },
      'returns': 'VirtioStatus',
      'features': [ 'unstable' ] }

    Example:

        -> { "execute": "x-query-virtio-status",
             "arguments": { "path": "/machine/peripheral/vsock0/virtio-backend" }
           }
        <- { "return": {
                 "device-endian": "little",
                 "bus-name": "",
                 "disable-legacy-check": false,
                 "name": "vhost-vsock",
                 "started": true,
                 "device-id": 19,
                 "vhost-dev": {
                     "n-tmp-sections": 4,
                     "n-mem-sections": 4,
                     "max-queues": 0,
                     "backend-cap": 0,
                     "log-size": 0,
                     "backend-features": {
                         "dev-features": [
                         ],
                         "transports": [
                         ]
                     },
                     "nvqs": 2,
                     "protocol-features": {
                         "protocols": [
                         ]
                     },
                     "vq-index": 0,
                     "log-enabled": false,
                     "acked-features": {
                         "dev-features": [
                         ],
                         "transports": [
                             "VIRTIO_RING_F_EVENT_IDX: Used & avail. event fields enabled",
                             "VIRTIO_RING_F_INDIRECT_DESC: Indirect descriptors supported",
                             "VIRTIO_F_VERSION_1: Device compliant for v1 spec (legacy)"
                         ]
                     },
                     "features": {
                         "dev-features": [
                             "VHOST_F_LOG_ALL: Logging write descriptors supported"
                         ],
                         "transports": [
                             "VIRTIO_RING_F_EVENT_IDX: Used & avail. event fields enabled",
                             "VIRTIO_RING_F_INDIRECT_DESC: Indirect descriptors supported",
                             "VIRTIO_F_VERSION_1: Device compliant for v1 spec (legacy)",
                             "VIRTIO_F_ANY_LAYOUT: Device accepts arbitrary desc. layouts",
                             "VIRTIO_F_NOTIFY_ON_EMPTY: Notify when device runs out of avail. descs. on VQ"
                         ]
                     }
                 },
                 "backend-features": {
                     "dev-features": [
                     ],
                     "transports": [
                     ]
                 },
                 "start-on-kick": false,
                 "isr": 0,
                 "broken": false,
                 "status": {
                     "statuses": [
                         "VIRTIO_CONFIG_S_ACKNOWLEDGE: Valid virtio device found",
                         "VIRTIO_CONFIG_S_DRIVER: Guest OS compatible with device",
                         "VIRTIO_CONFIG_S_FEATURES_OK: Feature negotiation complete",
                         "VIRTIO_CONFIG_S_DRIVER_OK: Driver setup and ready"
                     ]
                 },
                 "num-vqs": 3,
                 "guest-features": {
                     "dev-features": [
                     ],
                     "transports": [
                         "VIRTIO_RING_F_EVENT_IDX: Used & avail. event fields enabled",
                         "VIRTIO_RING_F_INDIRECT_DESC: Indirect descriptors supported",
                         "VIRTIO_F_VERSION_1: Device compliant for v1 spec (legacy)"
                     ]
                 },
                 "host-features": {
                     "dev-features": [
                         "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features negotiation supported"
                     ],
                     "transports": [
                         "VIRTIO_RING_F_EVENT_IDX: Used & avail. event fields enabled",
                         "VIRTIO_RING_F_INDIRECT_DESC: Indirect descriptors supported",
                         "VIRTIO_F_VERSION_1: Device compliant for v1 spec (legacy)",
                         "VIRTIO_F_ANY_LAYOUT: Device accepts arbitrary desc. layouts",
                         "VIRTIO_F_NOTIFY_ON_EMPTY: Notify when device runs out of avail. descs. on VQ"
                     ]
                 },
                 "use-guest-notifier-mask": true,
                 "vm-running": true,
                 "queue-sel": 2,
                 "disabled": false,
                 "vhost-started": true,
                 "use-started": true
             }
           }

3. Display status of a given virtio queue

HMP Form:

    info virtio-queue-status <path> <queue>

    Example:

        (qemu) info virtio-queue-status /machine/peripheral-anon/device[1]/virtio-backend 2
        /machine/peripheral-anon/device[1]/virtio-backend:
          device_name:          virtio-net
          queue_index:          2
          inuse:                0
          used_idx:             15
          signalled_used:       15
          signalled_used_valid: true
          VRing:
            num:          64
            num_default:  64
            align:        4096
            desc:         0x000000011e15c000
            avail:        0x000000011e15c400
            used:         0x000000011e15c4c0

QMP Form:

    { 'command': 'x-query-virtio-queue-status',
      'data': { 'path': 'str', 'queue': 'uint16' },
      'returns': 'VirtQueueStatus',
      'features': [ 'unstable' ] }

    Example:

        -> { "execute": "x-query-virtio-queue-status",
             "arguments": { "path": "/machine/peripheral-anon/device[1]/virtio-backend",
                            "queue": 2 }
           }
        <- { "return": {
                 "signalled-used": 15,
                 "inuse": 0,
                 "name": "virtio-net",
                 "vring-align": 4096,
                 "vring-desc": 4814004224,
                 "signalled-used-valid": true,
                 "vring-num-default": 64,
                 "vring-avail": 4814005248,
                 "queue-index": 2,
                 "vring-used": 4814005440,
                 "used-idx": 15,
                 "vring-num": 64
             }
           }

4. Display status of a given vhost queue

HMP Form:

    info virtio-vhost-queue-status <path> <queue>

    Example:

        (qemu) info virtio-vhost-queue-status /machine/peripheral-anon/device[1]/virtio-backend 1
        /machine/peripheral-anon/device[1]/virtio-backend:
          device_name:          virtio-net (vhost)
          kick:                 0
          call:                 0
          VRing:
            num:         256
            desc:        0x00007f804df5a000
            desc_phys:   0x000000013315a000
            desc_size:   4096
            avail:       0x00007f804df5b000
            avail_phys:  0x000000013315b000
            avail_size:  518
            used:        0x00007f804df5b240
            used_phys:   0x000000013315b240
            used_size:   2054

QMP Form:

    { 'command': 'x-query-virtio-vhost-queue-status',
      'data': { 'path': 'str', 'queue': 'uint16' },
      'returns': 'VirtVhostQueueStatus',
      'features': [ 'unstable' ] }

    Example:

        -> { "execute": "x-query-virtio-vhost-queue-status",
             "arguments": { "path": "/machine/peripheral-anon/device[1]/virtio-backend",
                            "queue": 1 }
           }
        <- { "return": {
                 "avail-phys": 4803538944,
                 "name": "virtio-net",
                 "used-phys": 4803539520,
                 "avail-size": 518,
                 "desc-size": 4096,
                 "used-size": 2054,
                 "desc": 140186477404160,
                 "num": 256,
                 "call": 0,
                 "avail": 140186477408256,
                 "desc-phys": 4803534848,
                 "used": 140186477408832,
                 "kick": 0
             }
           }

5. Display an element of a given virtio queue

HMP Form:

    info virtio-queue-element <path> <queue> [index]

    Example:

        Dump the information of the head element of the third queue of virtio-scsi:

        (qemu) info virtio-queue-element /machine/peripheral-anon/device[2]/virtio-backend 2
        /machine/peripheral-anon/device[2]/virtio-backend:
          device_name: virtio-scsi
          index:   0
          desc:
            descs:
                addr 0x128890000 len 12288 (write),
                addr 0x128880000 len 65536 (write, next),
                addr 0x128870000 len 65536 (write, next),
                addr 0x128860000 len 65536 (write, next),
                addr 0x128850000 len 65536 (write, next),
                addr 0x128840000 len 65536 (write, next),
                addr 0x128830000 len 65536 (write, next),
                addr 0x128820000 len 65536 (write, next),
                addr 0x128810000 len 65536 (write, next),
                addr 0x128800000 len 65536 (write, next),
                addr 0x116bf3000 len 53248 (write, next),
                addr 0x116be3000 len 65536 (write, next),
                addr 0x116bd3000 len 65536 (write, next),
                addr 0x116bc3000 len 65536 (write, next),
                addr 0x116bb3000 len 65536 (write, next),
                addr 0x116ba3000 len 65536 (write, next),
                addr 0x116b93000 len 65536 (write, next),
                addr 0x116b83000 len 65536 (write, next),
                addr 0x116b73000 len 65536 (write, next),
                addr 0x116b63000 len 65536 (write, next),
                addr 0x116b53000 len 65536 (write, next),
                addr 0x126e9763b len 108 (write, next),
                addr 0x9af8dae7222881a2 len 51 (next)
          avail:
            flags: 0
            idx:   600
            ring:  0
          used:
            flags: 0
            idx:   600

QMP Form:

    { 'command': 'x-query-virtio-queue-element',
      'data': { 'path': 'str', 'queue': 'uint16', '*index': 'uint16' },
      'returns': 'VirtioQueueElement',
      'features': [ 'unstable' ] }

    Example:

        -> { "execute": "x-query-virtio-queue-element",
             "arguments": { "path": "/machine/peripheral-anon/device[2]/virtio-backend",
                            "queue": 2 }
           }
        <- { "return": {
                 "index": 1,
                 "name": "virtio-scsi",
                 "descs": [
                     {
                         "flags": ["write"],
                         "len": 65536,
                         "addr": 4852740096
                     },
                     {
                         "flags": ["write", "next"],
                         "len": 65536,
                         "addr": 4852674560
                     },
                     {
                         "flags": ["write", "next"],
                         "len": 65536,
                         "addr": 4852609024
                     },
                     {
                         "flags": ["write", "next"],
                         "len": 65536,
                         "addr": 4852543488
                     },
                     {
                         "flags": ["write", "next"],
                         "len": 65536,
                         "addr": 4852477952
                     },
                     {
                         "flags": ["write", "next"],
                         "len": 65536,
                         "addr": 4852412416
                     },
                     {
                         "flags": ["write", "next"],
                         "len": 65536,
                         "addr": 4852346880
                     },
                     {
                         "flags": ["write", "next"],
                         "len": 65536,
                         "addr": 4852281344
                     },
                     {
                         "flags": ["write", "next"],
                         "len": 65536,
                         "addr": 4852215808
                     },
                     {
                         "flags": ["write", "next"],
                         "len": 65536,
                         "addr": 4852150272
                     },
                     {
                         "flags": ["write", "next"],
                         "len": 65536,
                         "addr": 4852084736
                     },
                     {
                         "flags": ["write", "next"],
                         "len": 65536,
                         "addr": 4852019200
                     },
                     {
                         "flags": ["write", "next"],
                         "len": 65536,
                         "addr": 4851953664
                     },
                     {
                         "flags": ["write", "next"],
                         "len": 65536,
                         "addr": 4851888128
                     },
                     {
                         "flags": ["write", "next"],
                         "len": 65536,
                         "addr": 4851822592
                     },
                     {
                         "flags": ["write", "next"],
                         "len": 65536,
                         "addr": 4851757056
                     },
                     {
                         "flags": ["write", "next"],
                         "len": 65536,
                         "addr": 4851691520
                     },
                     {
                         "flags": ["write", "next"],
                         "len": 65536,
                         "addr": 4851625984
                     },
                     {
                         "flags": ["write", "next"],
                         "len": 65536,
                         "addr": 4851560448
                     },
                     {
                         "flags": ["write", "next"],
                         "len": 65536,
                         "addr": 4851494912
                     },
                     {
                         "flags": ["write", "next"],
                         "len": 108,
                         "addr": 4801325435
                     },
                     {
                         "flags": ["next"],
                         "len": 51,
                         "addr": 12075758188190198449
                     }
                 ],
                 "avail": {
                     "idx": 922,
                     "flags": 0,
                     "ring": 1
                 },
                 "used": {
                     "idx": 922,
                     "flags": 0
                 }
             }
           }

v15: added missing sign-off in patches
     rebased for upstream (Qemu 7.1)
     minor reformatting to examples in qapi/virtio.json
     virtio device feature maps moved to hw/virtio/virtio.c
     virtio device feature maps renamed (less generic)
     virtio device feature maps now include brief description of feature
     virtio device status map now include brief description of status
     new feature bits added to mappings for virtio/vhost-vsock,
     virtio-iommu, & virtio-mem
     new virtio transport feature bit added to mapping
     new virtio device feature map defined for virtio-rng

v14: move definition of 'gpu_map' to virtio-gpu.c
     add new 'context-init' virtio-gpu feature
     created new feature map 'i2c_map' for vhost-user-i2c
     fixed casting error for cross-Win64 builds

v13: minor text edit in qapi/virtio.json

v12: minor reformatting for monitor/hmp-cmds.c
     use PRI types in virtio hmp monitor printfs

v11: minor reformatting in virtio.json
     added synchronicity check when querying virtio devices

v10: rebased for upstream (Qemu 7.0)
     reformat virtio.json for better consistency
     removed all enums from virtio.json; replaced with string literals
     removed @ndescs from VirtioQueueElement
     removed examples in hmp-commands-info.hx (to fix 'inconsistent
     literal block quoting' error from Sphinx)

v9: rebased for upstream (Qemu 6.3)
    change QMP command prefixes from 'x-debug-virtio' to
    'x-query-virtio'
    add 'unstable' feature to all 'x-query-virtio' prefixed
    QMP commands
    fix odd indentation for qapi/virtio.json
    device features support for virtio-mem
    move HMP sub-commands under 'virtio' top level to 'info'
    top level

v8: add assert in virtio_id_to_name() to make sure we're
    not returning NULL
    minor documentation additions to qapi/virtio.json
    add virtio introspection support for vhost-user-rng

v7: rebased for upstream (Qemu 6.2)
    add ability to map between numberic device ID and
    string device ID (name) for virtio devices
    add get_vhost() callback function for VirtIODevices
    expose more fields of VirtIODevice
    expose fields of vhost devices
    decode vhost user protocol features
    decode VirtIODevice configuration statuses
    vhost support for displaying virtio queue statuses
    vhost support for displaying vhost queue statuses
    expose driver and device areas when introspecting a
    virtio queue element
    changed patch attribution

v6: rebased for upstream (Qemu 6.1)
    add all virtio/vhost types in same order as
    include/standard-headers/linux/virtio_ids.h
    use QAPI_LIST_PREPEND in qmp_x_debug_query_virtio rather than open
    coding

v5: rebased for upstream
    add device name, used index, and relative indicies to virtio queue-status
    HMP command
    add device name to virtio queue-status QMP command
    add new virtio device features

v4: re-send series as v3 didn't reach qemu-devel

v3: use qapi_free_VirtioInfoList() on the head of the list, not on the tail.
    Prefix the QMP commands with 'x-debug-'

v2: introduce VirtioType enum
    use an enum for the endianness
    change field names to stick to naming convertions (s/_/-/)
    add a patch to decode feature bits
    don't check if the queue is empty to allow display of old elements
    use enum for desc flags
    manage indirect desc
    decode device features in the HMP command

Laurent Vivier (6):
  qmp: add QMP command x-query-virtio
  qmp: add QMP command x-query-virtio-status
  qmp: decode feature & status bits in virtio-status
  qmp: add QMP commands for virtio/vhost queue-status
  qmp: add QMP command x-query-virtio-queue-element
  hmp: add virtio commands

 hmp-commands-info.hx       |   70 +++
 hw/virtio/meson.build      |    2 +
 hw/virtio/virtio-stub.c    |   42 ++
 hw/virtio/virtio.c         | 1032 ++++++++++++++++++++++++++++++++++++
 include/hw/virtio/vhost.h  |    3 +
 include/hw/virtio/virtio.h |    6 +
 include/monitor/hmp.h      |    5 +
 monitor/hmp-cmds.c         |  310 +++++++++++
 qapi/meson.build           |    1 +
 qapi/qapi-schema.json      |    1 +
 qapi/virtio.json           |  954 +++++++++++++++++++++++++++++++++
 tests/qtest/qmp-cmd-test.c |    1 +
 12 files changed, 2427 insertions(+)
 create mode 100644 hw/virtio/virtio-stub.c
 create mode 100644 qapi/virtio.json

--
2.31.1