[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH v14 5/8] qmp: decode feature & status bits in virtio-status
From: |
Michael S. Tsirkin |
Subject: |
Re: [PATCH v14 5/8] qmp: decode feature & status bits in virtio-status |
Date: |
Thu, 26 May 2022 11:11:01 -0400 |
On Thu, May 19, 2022 at 02:30:43AM -0400, Jonah Palmer wrote:
>
> On 5/16/22 16:26, Michael S. Tsirkin wrote:
>
> On Fri, Apr 01, 2022 at 09:23:22AM -0400, Jonah Palmer wrote:
>
> From: Laurent Vivier <lvivier@redhat.com>
>
> Display feature names instead of bitmaps for host, guest, and
> backend for VirtIODevices.
>
> Display status names instead of bitmaps for VirtIODevices.
>
> Display feature names instead of bitmaps for backend, protocol,
> acked, and features (hdev->features) for vhost devices.
>
> Decode features according to device ID. Decode statuses
> according to configuration status bitmap (config_status_map).
> Decode vhost user protocol features according to vhost user
> protocol bitmap (vhost_user_protocol_map).
>
> Transport features are on the first line. Undecoded bits (if
> any) are stored in a separate field.
>
> Signed-off-by: Jonah Palmer <jonah.palmer@oracle.com>
>
>
> So this has several problems that I missed previously.
> First, sign off from poster is missing.
>
> My apologies, will add missing Laurent's SOB in correct order for
> patches 3-8.
>
>
>
>
>
> ---
> hw/block/virtio-blk.c | 29 ++++
> hw/char/virtio-serial-bus.c | 11 ++
> hw/display/virtio-gpu.c | 18 ++
> hw/input/virtio-input.c | 10 ++
> hw/net/virtio-net.c | 47 +++++
> hw/scsi/virtio-scsi.c | 17 ++
> hw/virtio/vhost-user-fs.c | 10 ++
> hw/virtio/vhost-user-i2c.c | 14 ++
> hw/virtio/vhost-vsock-common.c | 10 ++
> hw/virtio/virtio-balloon.c | 14 ++
> hw/virtio/virtio-crypto.c | 10 ++
> hw/virtio/virtio-iommu.c | 14 ++
> hw/virtio/virtio-mem.c | 11 ++
> hw/virtio/virtio.c | 302
> ++++++++++++++++++++++++++++++++-
> include/hw/virtio/vhost.h | 3 +
> include/hw/virtio/virtio.h | 19 +++
> qapi/virtio.json | 156 ++++++++++++++---
> 17 files changed, 667 insertions(+), 28 deletions(-)
>
> diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
> index 27c71ad316..f104603040 100644
> --- a/hw/block/virtio-blk.c
> +++ b/hw/block/virtio-blk.c
> @@ -13,6 +13,7 @@
>
> #include "qemu/osdep.h"
> #include "qapi/error.h"
> +#include "qapi/qapi-visit-virtio.h"
> #include "qemu/iov.h"
> #include "qemu/module.h"
> #include "qemu/error-report.h"
> @@ -33,10 +34,38 @@
> #include "migration/qemu-file-types.h"
> #include "hw/virtio/virtio-access.h"
> #include "qemu/coroutine.h"
> +#include "standard-headers/linux/vhost_types.h"
>
> /* Config size before the discard support (hide associated config
> fields) */
> #define VIRTIO_BLK_CFG_SIZE offsetof(struct virtio_blk_config, \
> max_discard_sectors)
> +
> +qmp_virtio_feature_map_t blk_map[] = {
> +#define FEATURE_ENTRY(name) \
> + { VIRTIO_BLK_F_##name, #name }
> + FEATURE_ENTRY(SIZE_MAX),
> + FEATURE_ENTRY(SEG_MAX),
> + FEATURE_ENTRY(GEOMETRY),
> + FEATURE_ENTRY(RO),
> + FEATURE_ENTRY(BLK_SIZE),
> + FEATURE_ENTRY(TOPOLOGY),
> + FEATURE_ENTRY(MQ),
> + FEATURE_ENTRY(DISCARD),
> + FEATURE_ENTRY(WRITE_ZEROES),
> +#ifndef VIRTIO_BLK_NO_LEGACY
> + FEATURE_ENTRY(BARRIER),
> + FEATURE_ENTRY(SCSI),
> + FEATURE_ENTRY(FLUSH),
> + FEATURE_ENTRY(CONFIG_WCE),
> +#endif /* !VIRTIO_BLK_NO_LEGACY */
> +#undef FEATURE_ENTRY
> +#define FEATURE_ENTRY(name) \
> + { VHOST_F_##name, #name }
> + FEATURE_ENTRY(LOG_ALL),
> +#undef FEATURE_ENTRY
> + { -1, "" }
> +};
> +
> /*
> * Starting from the discard feature, we can use this array to
> properly
> * set the config size depending on the features enabled.
> diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
> index 7d4601cb5d..fbb31a2b16 100644
> --- a/hw/char/virtio-serial-bus.c
> +++ b/hw/char/virtio-serial-bus.c
> @@ -20,6 +20,7 @@
>
> #include "qemu/osdep.h"
> #include "qapi/error.h"
> +#include "qapi/qapi-visit-virtio.h"
> #include "qemu/iov.h"
> #include "qemu/main-loop.h"
> #include "qemu/module.h"
> @@ -32,6 +33,16 @@
> #include "hw/virtio/virtio-serial.h"
> #include "hw/virtio/virtio-access.h"
>
> +qmp_virtio_feature_map_t serial_map[] = {
> +#define FEATURE_ENTRY(name) \
> + { VIRTIO_CONSOLE_F_##name, #name }
> + FEATURE_ENTRY(SIZE),
> + FEATURE_ENTRY(MULTIPORT),
> + FEATURE_ENTRY(EMERG_WRITE),
> +#undef FEATURE_ENTRY
> + { -1, "" }
> +};
> +
> static struct VirtIOSerialDevices {
> QLIST_HEAD(, VirtIOSerial) devices;
> } vserdevices;
> diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
> index 529b5246b2..0bd5dc6232 100644
> --- a/hw/display/virtio-gpu.c
> +++ b/hw/display/virtio-gpu.c
> @@ -29,10 +29,28 @@
> #include "qemu/log.h"
> #include "qemu/module.h"
> #include "qapi/error.h"
> +#include "qapi/qapi-visit-virtio.h"
> #include "qemu/error-report.h"
> +#include "standard-headers/linux/vhost_types.h"
>
> #define VIRTIO_GPU_VM_VERSION 1
>
> +qmp_virtio_feature_map_t gpu_map[] = {
> +#define FEATURE_ENTRY(name) \
> + { VIRTIO_GPU_F_##name, #name }
> + FEATURE_ENTRY(VIRGL),
> + FEATURE_ENTRY(EDID),
> + FEATURE_ENTRY(RESOURCE_UUID),
> + FEATURE_ENTRY(RESOURCE_BLOB),
> + FEATURE_ENTRY(CONTEXT_INIT),
> +#undef FEATURE_ENTRY
> +#define FEATURE_ENTRY(name) \
> + { VHOST_F_##name, #name }
> + FEATURE_ENTRY(LOG_ALL),
> +#undef FEATURE_ENTRY
> + { -1, "" }
> +};
> +
>
>
> Now I had some experience with this, the trick makes it
> harder to find where is a given macro used, and at the same
> time saves very little. Also should a macro name change, we
> do not want the name to change.
> Let's just keep it simple please.
> Plain array of macros and strings with no tricks.
>
> Sure thing. Should I define the macro outside of the map
> definition? E.g:
>
> #define FEATURE_ENTRY(name) { ##name, #name }
> qmp_virtio_feature_map_t virtio_gpu_feature_map[] = {
> FEATURE_ENTRY(VIRTIO_GPU_F_VIRGL),
> FEATURE_ENTRY(VIRTIO_GPU_F_EDID),
> ...
> { -1, "" }
> };
> Also, is that what you were thinking as a "plain array of macros
> and strings"? Or was there something more simple you had in mind?
>
That's not too bad, yes.
But I think open-coding is even better since then you can add the
description:
VIRTIO_GPU_F_VIRGL, "VIRTIO_GPU_F_VIRGL: virgl 3D mode is supported"
I would advise against string concatenation for this since it
again makes it harder to find the string.
>
>
>
> static struct virtio_gpu_simple_resource*
> virtio_gpu_find_resource(VirtIOGPU *g, uint32_t resource_id);
> static struct virtio_gpu_simple_resource *
> diff --git a/hw/input/virtio-input.c b/hw/input/virtio-input.c
> index 5b5398b3ca..fe0ed6d5b4 100644
> --- a/hw/input/virtio-input.c
> +++ b/hw/input/virtio-input.c
> @@ -6,6 +6,7 @@
>
> #include "qemu/osdep.h"
> #include "qapi/error.h"
> +#include "qapi/qapi-visit-virtio.h"
> #include "qemu/iov.h"
> #include "qemu/module.h"
> #include "trace.h"
> @@ -14,10 +15,19 @@
> #include "hw/qdev-properties.h"
> #include "hw/virtio/virtio-input.h"
>
> +#include "standard-headers/linux/vhost_types.h"
> #include "standard-headers/linux/input.h"
>
> #define VIRTIO_INPUT_VM_VERSION 1
>
> +qmp_virtio_feature_map_t input_map[] = {
> +#define FEATURE_ENTRY(name) \
> + { VHOST_F_##name, #name }
> + FEATURE_ENTRY(LOG_ALL),
> +#undef FEATURE_ENTRY
> + { -1, "" }
> +};
> +
> /* -----------------------------------------------------------------
> */
>
> void virtio_input_send(VirtIOInput *vinput, virtio_input_event
> *event)
> diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> index 027ce40c6f..9356958fb6 100644
> --- a/hw/net/virtio-net.c
> +++ b/hw/net/virtio-net.c
> @@ -35,9 +35,11 @@
> #include "hw/qdev-properties.h"
> #include "qapi/qapi-types-migration.h"
> #include "qapi/qapi-events-migration.h"
> +#include "qapi/qapi-visit-virtio.h"
> #include "hw/virtio/virtio-access.h"
> #include "migration/misc.h"
> #include "standard-headers/linux/ethtool.h"
> +#include "standard-headers/linux/vhost_types.h"
> #include "sysemu/sysemu.h"
> #include "trace.h"
> #include "monitor/qdev.h"
> @@ -90,6 +92,51 @@
>
> VIRTIO_NET_RSS_HASH_TYPE_TCP_EX | \
>
> VIRTIO_NET_RSS_HASH_TYPE_UDP_EX)
>
> +qmp_virtio_feature_map_t net_map[] = {
> +#define FEATURE_ENTRY(name) \
> + { VIRTIO_NET_F_##name, #name }
> + FEATURE_ENTRY(CSUM),
> + FEATURE_ENTRY(GUEST_CSUM),
> + FEATURE_ENTRY(CTRL_GUEST_OFFLOADS),
> + FEATURE_ENTRY(MTU),
> + FEATURE_ENTRY(MAC),
> + FEATURE_ENTRY(GUEST_TSO4),
> + FEATURE_ENTRY(GUEST_TSO6),
> + FEATURE_ENTRY(GUEST_ECN),
> + FEATURE_ENTRY(GUEST_UFO),
> + FEATURE_ENTRY(HOST_TSO4),
> + FEATURE_ENTRY(HOST_TSO6),
> + FEATURE_ENTRY(HOST_ECN),
> + FEATURE_ENTRY(HOST_UFO),
> + FEATURE_ENTRY(MRG_RXBUF),
> + FEATURE_ENTRY(STATUS),
> + FEATURE_ENTRY(CTRL_VQ),
> + FEATURE_ENTRY(CTRL_RX),
> + FEATURE_ENTRY(CTRL_VLAN),
> + FEATURE_ENTRY(CTRL_RX_EXTRA),
> + FEATURE_ENTRY(GUEST_ANNOUNCE),
> + FEATURE_ENTRY(MQ),
> + FEATURE_ENTRY(CTRL_MAC_ADDR),
> + FEATURE_ENTRY(HASH_REPORT),
> + FEATURE_ENTRY(RSS),
> + FEATURE_ENTRY(RSC_EXT),
> + FEATURE_ENTRY(STANDBY),
> + FEATURE_ENTRY(SPEED_DUPLEX),
> +#ifndef VIRTIO_NET_NO_LEGACY
> + FEATURE_ENTRY(GSO),
> +#endif /* VIRTIO_NET_NO_LEGACY */
> +#undef FEATURE_ENTRY
> +#define FEATURE_ENTRY(name) \
> + { VHOST_NET_F_##name, #name }
> + FEATURE_ENTRY(VIRTIO_NET_HDR),
> +#undef FEATURE_ENTRY
> +#define FEATURE_ENTRY(name) \
> + { VHOST_F_##name, #name }
> + FEATURE_ENTRY(LOG_ALL),
> +#undef FEATURE_ENTRY
> + { -1, "" }
> +};
> +
> static const VirtIOFeature feature_sizes[] = {
> {.flags = 1ULL << VIRTIO_NET_F_MAC,
> .end = endof(struct virtio_net_config, mac)},
> diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
> index 2a6141d081..9ca8faa40e 100644
> --- a/hw/scsi/virtio-scsi.c
> +++ b/hw/scsi/virtio-scsi.c
> @@ -15,7 +15,9 @@
>
> #include "qemu/osdep.h"
> #include "qapi/error.h"
> +#include "qapi/qapi-visit-virtio.h"
> #include "standard-headers/linux/virtio_ids.h"
> +#include "standard-headers/linux/vhost_types.h"
> #include "hw/virtio/virtio-scsi.h"
> #include "migration/qemu-file-types.h"
> #include "qemu/error-report.h"
> @@ -29,6 +31,21 @@
> #include "hw/virtio/virtio-access.h"
> #include "trace.h"
>
> +qmp_virtio_feature_map_t scsi_map[] = {
> +#define FEATURE_ENTRY(name) \
> + { VIRTIO_SCSI_F_##name, #name }
> + FEATURE_ENTRY(INOUT),
> + FEATURE_ENTRY(HOTPLUG),
> + FEATURE_ENTRY(CHANGE),
> + FEATURE_ENTRY(T10_PI),
> +#undef FEATURE_ENTRY
> +#define FEATURE_ENTRY(name) \
> + { VHOST_F_##name, #name }
> + FEATURE_ENTRY(LOG_ALL),
> +#undef FEATURE_ENTRY
> + { -1, "" }
> +};
> +
> static inline int virtio_scsi_get_lun(uint8_t *lun)
> {
> return ((lun[2] << 8) | lun[3]) & 0x3FFF;
> diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c
> index e513e4fdda..096cc07c44 100644
> --- a/hw/virtio/vhost-user-fs.c
> +++ b/hw/virtio/vhost-user-fs.c
> @@ -15,6 +15,7 @@
> #include <sys/ioctl.h>
> #include "standard-headers/linux/virtio_fs.h"
> #include "qapi/error.h"
> +#include "qapi/qapi-visit-virtio.h"
> #include "hw/qdev-properties.h"
> #include "hw/qdev-properties-system.h"
> #include "hw/virtio/virtio-bus.h"
> @@ -23,6 +24,15 @@
> #include "hw/virtio/vhost-user-fs.h"
> #include "monitor/monitor.h"
> #include "sysemu/sysemu.h"
> +#include "standard-headers/linux/vhost_types.h"
> +
> +qmp_virtio_feature_map_t fs_map[] = {
> +#define FEATURE_ENTRY(name) \
> + { VHOST_F_##name, #name }
> + FEATURE_ENTRY(LOG_ALL),
> +#undef FEATURE_ENTRY
> + { -1, "" }
> +};
>
> static const int user_feature_bits[] = {
> VIRTIO_F_VERSION_1,
> diff --git a/hw/virtio/vhost-user-i2c.c b/hw/virtio/vhost-user-i2c.c
> index 6020eee093..931ec9836c 100644
> --- a/hw/virtio/vhost-user-i2c.c
> +++ b/hw/virtio/vhost-user-i2c.c
> @@ -8,11 +8,25 @@
>
> #include "qemu/osdep.h"
> #include "qapi/error.h"
> +#include "qapi/qapi-visit-virtio.h"
> #include "hw/qdev-properties.h"
> #include "hw/virtio/virtio-bus.h"
> #include "hw/virtio/vhost-user-i2c.h"
> #include "qemu/error-report.h"
> #include "standard-headers/linux/virtio_ids.h"
> +#include "standard-headers/linux/vhost_types.h"
> +
> +qmp_virtio_feature_map_t i2c_map[] = {
> +#define FEATURE_ENTRY(name) \
> + { VHOST_F_##name, #name }
> + FEATURE_ENTRY(LOG_ALL),
> +#undef FEATURE_ENTRY
> +#define FEATURE_ENTRY(name) \
> + { VIRTIO_I2C_F_##name, #name }
> + FEATURE_ENTRY(ZERO_LENGTH_REQUEST),
> +#undef FEATURE_ENTRY
> + { -1, "" }
> +};
>
> static const int feature_bits[] = {
> VIRTIO_I2C_F_ZERO_LENGTH_REQUEST,
> diff --git a/hw/virtio/vhost-vsock-common.c
> b/hw/virtio/vhost-vsock-common.c
> index 7394818e00..b03f94d8f8 100644
> --- a/hw/virtio/vhost-vsock-common.c
> +++ b/hw/virtio/vhost-vsock-common.c
> @@ -11,12 +11,22 @@
> #include "qemu/osdep.h"
> #include "standard-headers/linux/virtio_vsock.h"
> #include "qapi/error.h"
> +#include "qapi/qapi-visit-virtio.h"
> #include "hw/virtio/virtio-access.h"
> #include "qemu/error-report.h"
> #include "hw/qdev-properties.h"
> #include "hw/virtio/vhost-vsock.h"
> #include "qemu/iov.h"
> #include "monitor/monitor.h"
> +#include "standard-headers/linux/vhost_types.h"
> +
> +qmp_virtio_feature_map_t vsock_map[] = {
> +#define FEATURE_ENTRY(name) \
> + { VHOST_F_##name, #name }
> + FEATURE_ENTRY(LOG_ALL),
> +#undef FEATURE_ENTRY
> + { -1, "" }
> +};
>
> const int feature_bits[] = {
> VIRTIO_VSOCK_F_SEQPACKET,
> diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
> index 193ff5261c..b2ae0a4d8c 100644
> --- a/hw/virtio/virtio-balloon.c
> +++ b/hw/virtio/virtio-balloon.c
> @@ -28,6 +28,7 @@
> #include "qapi/error.h"
> #include "qapi/qapi-events-machine.h"
> #include "qapi/visitor.h"
> +#include "qapi/qapi-visit-virtio.h"
> #include "trace.h"
> #include "qemu/error-report.h"
> #include "migration/misc.h"
> @@ -38,6 +39,19 @@
>
> #define BALLOON_PAGE_SIZE (1 << VIRTIO_BALLOON_PFN_SHIFT)
>
> +qmp_virtio_feature_map_t balloon_map[] = {
> +#define FEATURE_ENTRY(name) \
> + { VIRTIO_BALLOON_F_##name, #name }
> + FEATURE_ENTRY(MUST_TELL_HOST),
> + FEATURE_ENTRY(STATS_VQ),
> + FEATURE_ENTRY(DEFLATE_ON_OOM),
> + FEATURE_ENTRY(FREE_PAGE_HINT),
> + FEATURE_ENTRY(PAGE_POISON),
> + FEATURE_ENTRY(REPORTING),
> +#undef FEATURE_ENTRY
> + { -1, "" }
> +};
> +
> typedef struct PartiallyBalloonedPage {
> ram_addr_t base_gpa;
> unsigned long *bitmap;
> diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c
> index 947a11c3af..5c9a3d045d 100644
> --- a/hw/virtio/virtio-crypto.c
> +++ b/hw/virtio/virtio-crypto.c
> @@ -16,6 +16,7 @@
> #include "qemu/main-loop.h"
> #include "qemu/module.h"
> #include "qapi/error.h"
> +#include "qapi/qapi-visit-virtio.h"
> #include "qemu/error-report.h"
>
> #include "hw/virtio/virtio.h"
> @@ -23,10 +24,19 @@
> #include "hw/qdev-properties.h"
> #include "hw/virtio/virtio-access.h"
> #include "standard-headers/linux/virtio_ids.h"
> +#include "standard-headers/linux/vhost_types.h"
> #include "sysemu/cryptodev-vhost.h"
>
> #define VIRTIO_CRYPTO_VM_VERSION 1
>
> +qmp_virtio_feature_map_t crypto_map[] = {
> +#define FEATURE_ENTRY(name) \
> + { VHOST_F_##name, #name }
> + FEATURE_ENTRY(LOG_ALL),
> +#undef FEATURE_ENTRY
> + { -1, "" }
> +};
> +
> /*
> * Transfer virtqueue index to crypto queue index.
> * The control virtqueue is after the data virtqueues
> diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c
> index 4ed5bb16ba..d993106d10 100644
> --- a/hw/virtio/virtio-iommu.c
> +++ b/hw/virtio/virtio-iommu.c
> @@ -26,6 +26,7 @@
> #include "sysemu/kvm.h"
> #include "sysemu/reset.h"
> #include "qapi/error.h"
> +#include "qapi/qapi-visit-virtio.h"
> #include "qemu/error-report.h"
> #include "trace.h"
>
> @@ -41,6 +42,19 @@
> #define VIOMMU_DEFAULT_QUEUE_SIZE 256
> #define VIOMMU_PROBE_SIZE 512
>
> +qmp_virtio_feature_map_t iommu_map[] = {
> +#define FEATURE_ENTRY(name) \
> + { VIRTIO_IOMMU_F_##name, #name }
> + FEATURE_ENTRY(INPUT_RANGE),
> + FEATURE_ENTRY(DOMAIN_RANGE),
> + FEATURE_ENTRY(MAP_UNMAP),
> + FEATURE_ENTRY(BYPASS),
> + FEATURE_ENTRY(PROBE),
> + FEATURE_ENTRY(MMIO),
> +#undef FEATURE_ENTRY
> + { -1, "" }
> +};
> +
> typedef struct VirtIOIOMMUDomain {
> uint32_t id;
> bool bypass;
> diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c
> index 465a996214..31e7af834e 100644
> --- a/hw/virtio/virtio-mem.c
> +++ b/hw/virtio/virtio-mem.c
> @@ -25,6 +25,7 @@
> #include "hw/virtio/virtio-mem.h"
> #include "qapi/error.h"
> #include "qapi/visitor.h"
> +#include "qapi/qapi-visit-virtio.h"
> #include "exec/ram_addr.h"
> #include "migration/misc.h"
> #include "hw/boards.h"
> @@ -32,6 +33,16 @@
> #include CONFIG_DEVICES
> #include "trace.h"
>
> +qmp_virtio_feature_map_t mem_map[] = {
> +#define FEATURE_ENTRY(name) \
> + { VIRTIO_MEM_F_##name, #name }
> +#ifndef CONFIG_ACPI
> + FEATURE_ENTRY(ACPI_PXM),
> +#endif /* CONFIG_ACPI */
> +#undef FEATURE_ENTRY
> + { -1, "" }
> +};
> +
> /*
> * We only had legacy x86 guests that did not support
> * VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE. Other targets don't have
> legacy guests.
> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> index 7f8eb29ced..af376be933 100644
> --- a/hw/virtio/virtio.c
> +++ b/hw/virtio/virtio.c
> @@ -34,10 +34,99 @@
> #include "sysemu/dma.h"
> #include "sysemu/runstate.h"
> #include "standard-headers/linux/virtio_ids.h"
> +#include "standard-headers/linux/vhost_types.h"
> +#include CONFIG_DEVICES
>
> /* QAPI list of realized VirtIODevices */
> static QTAILQ_HEAD(, VirtIODevice) virtio_list;
>
> +/*
> + * Maximum size of virtio device config space
> + */
> +#define VHOST_USER_MAX_CONFIG_SIZE 256
> +
> +enum VhostUserProtocolFeature {
> + VHOST_USER_PROTOCOL_F_MQ = 0,
> + VHOST_USER_PROTOCOL_F_LOG_SHMFD = 1,
> + VHOST_USER_PROTOCOL_F_RARP = 2,
> + VHOST_USER_PROTOCOL_F_REPLY_ACK = 3,
> + VHOST_USER_PROTOCOL_F_NET_MTU = 4,
> + VHOST_USER_PROTOCOL_F_SLAVE_REQ = 5,
> + VHOST_USER_PROTOCOL_F_CROSS_ENDIAN = 6,
> + VHOST_USER_PROTOCOL_F_CRYPTO_SESSION = 7,
> + VHOST_USER_PROTOCOL_F_PAGEFAULT = 8,
> + VHOST_USER_PROTOCOL_F_CONFIG = 9,
> + VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD = 10,
> + VHOST_USER_PROTOCOL_F_HOST_NOTIFIER = 11,
> + VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD = 12,
> + VHOST_USER_PROTOCOL_F_RESET_DEVICE = 13,
> + VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS = 14,
> + VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS = 15,
> + VHOST_USER_PROTOCOL_F_MAX
> +};
> +
> +static qmp_virtio_feature_map_t transport_map[] = {
> +#define FEATURE_ENTRY(name) \
> + { VIRTIO_F_##name, #name }
> +#ifndef VIRTIO_CONFIG_NO_LEGACY
> + FEATURE_ENTRY(NOTIFY_ON_EMPTY),
> + FEATURE_ENTRY(ANY_LAYOUT),
> +#endif /* VIRTIO_CONFIG_NO_LEGACY */
> + FEATURE_ENTRY(VERSION_1),
> + FEATURE_ENTRY(IOMMU_PLATFORM),
> + FEATURE_ENTRY(RING_PACKED),
> + FEATURE_ENTRY(ORDER_PLATFORM),
> + FEATURE_ENTRY(SR_IOV),
> +#undef FEATURE_ENTRY
> +#define FEATURE_ENTRY(name) \
> + { VIRTIO_RING_F_##name, #name }
> + FEATURE_ENTRY(INDIRECT_DESC),
> + FEATURE_ENTRY(EVENT_IDX),
> +#undef FEATURE_ENTRY
> +#define FEATURE_ENTRY(name) \
> + { VHOST_USER_F_##name, #name }
> + FEATURE_ENTRY(PROTOCOL_FEATURES),
> +#undef FEATURE_ENTRY
> + { -1, "" }
> +};
> +
> +static qmp_virtio_feature_map_t vhost_user_protocol_map[] = {
> +#define FEATURE_ENTRY(name) \
> + { VHOST_USER_PROTOCOL_F_##name, #name }
> + FEATURE_ENTRY(MQ),
> + FEATURE_ENTRY(LOG_SHMFD),
> + FEATURE_ENTRY(RARP),
> + FEATURE_ENTRY(REPLY_ACK),
> + FEATURE_ENTRY(NET_MTU),
> + FEATURE_ENTRY(SLAVE_REQ),
> + FEATURE_ENTRY(CROSS_ENDIAN),
> + FEATURE_ENTRY(CRYPTO_SESSION),
> + FEATURE_ENTRY(PAGEFAULT),
> + FEATURE_ENTRY(CONFIG),
> + FEATURE_ENTRY(SLAVE_SEND_FD),
> + FEATURE_ENTRY(HOST_NOTIFIER),
> + FEATURE_ENTRY(INFLIGHT_SHMFD),
> + FEATURE_ENTRY(RESET_DEVICE),
> + FEATURE_ENTRY(INBAND_NOTIFICATIONS),
> + FEATURE_ENTRY(CONFIGURE_MEM_SLOTS),
> +#undef FEATURE_ENTRY
> + { -1, "" }
> +};
> +
> +/* virtio device configuration statuses */
> +static qmp_virtio_feature_map_t config_status_map[] = {
> +#define STATUS_ENTRY(name) \
> + { VIRTIO_CONFIG_S_##name, #name }
> + STATUS_ENTRY(DRIVER_OK),
> + STATUS_ENTRY(FEATURES_OK),
> + STATUS_ENTRY(DRIVER),
> + STATUS_ENTRY(NEEDS_RESET),
> + STATUS_ENTRY(FAILED),
> + STATUS_ENTRY(ACKNOWLEDGE),
> +#undef STATUS_ENTRY
> + { -1, "" }
> +};
> +
> /*
> * The alignment to use between consumer and producer parts of vring.
> * x86 pagesize again. This is the default, used by transports like
> PCI
> @@ -3962,6 +4051,196 @@ static VirtIODevice *virtio_device_find(const
> char *path)
> return NULL;
> }
>
> +#define CONVERT_FEATURES(type, map, is_status, bitmap) \
> + ({ \
> + type *list = NULL; \
> + type *node; \
> + for (i = 0; map[i].virtio_bit != -1; i++) { \
> + if (is_status) { \
> + bit = map[i].virtio_bit; \
> + } \
> + else { \
> + bit = 1ULL << map[i].virtio_bit; \
> + } \
> + if ((bitmap & bit) == 0) { \
> + continue; \
> + } \
> + node = g_new0(type, 1); \
> + node->value = g_strdup(map[i].feature_name); \
> + node->next = list; \
> + list = node; \
> + bitmap ^= bit; \
> + } \
> + list; \
> + })
> +
> +static VirtioDeviceStatus *qmp_decode_status(uint8_t bitmap)
> +{
> + VirtioDeviceStatus *status;
> + uint8_t bit;
> + int i;
> +
> + status = g_new0(VirtioDeviceStatus, 1);
> + status->statuses = CONVERT_FEATURES(strList, config_status_map,
> 1, bitmap);
> + status->has_unknown_statuses = bitmap != 0;
> + if (status->has_unknown_statuses) {
> + status->unknown_statuses = bitmap;
> + }
> +
> + return status;
> +}
> +
> +static VhostDeviceProtocols *qmp_decode_protocols(uint64_t bitmap)
> +{
> + VhostDeviceProtocols *vhu_protocols;
> + uint64_t bit;
> + int i;
> +
> + vhu_protocols = g_new0(VhostDeviceProtocols, 1);
> + vhu_protocols->protocols =
> + CONVERT_FEATURES(strList,
> + vhost_user_protocol_map, 0,
> bitmap);
> + vhu_protocols->has_unknown_protocols = bitmap != 0;
> + if (vhu_protocols->has_unknown_protocols) {
> + vhu_protocols->unknown_protocols = bitmap;
> + }
> +
> + return vhu_protocols;
> +}
> +
> +static VirtioDeviceFeatures *qmp_decode_features(uint16_t device_id,
> + uint64_t bitmap)
> +{
> + VirtioDeviceFeatures *features;
> + uint64_t bit;
> + int i;
> +
> + features = g_new0(VirtioDeviceFeatures, 1);
> + features->has_dev_features = true;
> +
> + /* transport features */
> + features->transports = CONVERT_FEATURES(strList, transport_map,
> 0, bitmap);
> +
> + /* device features */
> + switch (device_id) {
> +#ifdef CONFIG_VIRTIO_SERIAL
> + case VIRTIO_ID_CONSOLE:
> + features->dev_features =
> + CONVERT_FEATURES(strList, serial_map, 0, bitmap);
> + break;
> +#endif
> +#ifdef CONFIG_VIRTIO_BLK
> + case VIRTIO_ID_BLOCK:
> + features->dev_features =
> + CONVERT_FEATURES(strList, blk_map, 0, bitmap);
> + break;
> +#endif
> +#ifdef CONFIG_VIRTIO_GPU
> + case VIRTIO_ID_GPU:
> + features->dev_features =
> + CONVERT_FEATURES(strList, gpu_map, 0, bitmap);
> + break;
> +#endif
> +#ifdef CONFIG_VIRTIO_NET
> + case VIRTIO_ID_NET:
> + features->dev_features =
> + CONVERT_FEATURES(strList, net_map, 0, bitmap);
> + break;
> +#endif
> +#ifdef CONFIG_VIRTIO_SCSI
> + case VIRTIO_ID_SCSI:
> + features->dev_features =
> + CONVERT_FEATURES(strList, scsi_map, 0, bitmap);
> + break;
> +#endif
> +#ifdef CONFIG_VIRTIO_BALLOON
> + case VIRTIO_ID_BALLOON:
> + features->dev_features =
> + CONVERT_FEATURES(strList, balloon_map, 0, bitmap);
> + break;
> +#endif
> +#ifdef CONFIG_VIRTIO_IOMMU
> + case VIRTIO_ID_IOMMU:
> + features->dev_features =
> + CONVERT_FEATURES(strList, iommu_map, 0, bitmap);
> + break;
> +#endif
> +#ifdef CONFIG_VIRTIO_INPUT
> + case VIRTIO_ID_INPUT:
> + features->dev_features =
> + CONVERT_FEATURES(strList, input_map, 0, bitmap);
> + break;
> +#endif
> +#ifdef CONFIG_VHOST_USER_FS
> + case VIRTIO_ID_FS:
> + features->dev_features =
> + CONVERT_FEATURES(strList, fs_map, 0, bitmap);
> + break;
> +#endif
> +#ifdef CONFIG_VHOST_VSOCK
> + case VIRTIO_ID_VSOCK:
> + features->dev_features =
> + CONVERT_FEATURES(strList, vsock_map, 0, bitmap);
> + break;
> +#endif
> +#ifdef CONFIG_VIRTIO_CRYPTO
> + case VIRTIO_ID_CRYPTO:
> + features->dev_features =
> + CONVERT_FEATURES(strList, crypto_map, 0, bitmap);
> + break;
> +#endif
> +#ifdef CONFIG_VIRTIO_MEM
> + case VIRTIO_ID_MEM:
> + features->dev_features =
> + CONVERT_FEATURES(strList, mem_map, 0, bitmap);
> + break;
> +#endif
> +#ifdef CONFIG_VIRTIO_I2C_ADAPTER
> + case VIRTIO_ID_I2C_ADAPTER:
> + features->dev_features =
> + CONVERT_FEATURES(strList, i2c_map, 0, bitmap);
> + break;
> +#endif
> + /* No features */
> + case VIRTIO_ID_9P:
> + case VIRTIO_ID_PMEM:
> + case VIRTIO_ID_RNG:
> + case VIRTIO_ID_IOMEM:
> + case VIRTIO_ID_RPMSG:
> + case VIRTIO_ID_CLOCK:
> + case VIRTIO_ID_MAC80211_WLAN:
> + case VIRTIO_ID_MAC80211_HWSIM:
> + case VIRTIO_ID_RPROC_SERIAL:
> + case VIRTIO_ID_MEMORY_BALLOON:
> + case VIRTIO_ID_CAIF:
> + case VIRTIO_ID_SIGNAL_DIST:
> + case VIRTIO_ID_PSTORE:
> + case VIRTIO_ID_SOUND:
> + case VIRTIO_ID_BT:
> + case VIRTIO_ID_RPMB:
> + case VIRTIO_ID_VIDEO_ENCODER:
> + case VIRTIO_ID_VIDEO_DECODER:
> + case VIRTIO_ID_SCMI:
> + case VIRTIO_ID_NITRO_SEC_MOD:
> + case VIRTIO_ID_WATCHDOG:
> + case VIRTIO_ID_CAN:
> + case VIRTIO_ID_DMABUF:
> + case VIRTIO_ID_PARAM_SERV:
> + case VIRTIO_ID_AUDIO_POLICY:
> + case VIRTIO_ID_GPIO:
> + break;
> + default:
> + g_assert_not_reached();
> + }
> +
> + features->has_unknown_dev_features = bitmap != 0;
> + if (features->has_unknown_dev_features) {
> + features->unknown_dev_features = bitmap;
> + }
> +
> + return features;
> +}
> +
> VirtioStatus *qmp_x_query_virtio_status(const char *path, Error
> **errp)
> {
> VirtIODevice *vdev;
> @@ -3977,9 +4256,12 @@ VirtioStatus *qmp_x_query_virtio_status(const
> char *path, Error **errp)
> 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;
> + status->guest_features = qmp_decode_features(vdev->device_id,
> +
> vdev->guest_features);
> + status->host_features = qmp_decode_features(vdev->device_id,
> + vdev->host_features);
> + status->backend_features = qmp_decode_features(vdev->device_id,
> +
> vdev->backend_features);
>
> switch (vdev->device_endian) {
> case VIRTIO_DEVICE_ENDIAN_LITTLE:
> @@ -3994,7 +4276,7 @@ VirtioStatus *qmp_x_query_virtio_status(const
> char *path, Error **errp)
> }
>
> status->num_vqs = virtio_get_num_queues(vdev);
> - status->status = vdev->status;
> + status->status = qmp_decode_status(vdev->status);
> status->isr = vdev->isr;
> status->queue_sel = vdev->queue_sel;
> status->vm_running = vdev->vm_running;
> @@ -4017,10 +4299,14 @@ VirtioStatus *qmp_x_query_virtio_status(const
> char *path, Error **errp)
> 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->features =
> + qmp_decode_features(vdev->device_id, hdev->features);
> + status->vhost_dev->acked_features =
> + qmp_decode_features(vdev->device_id,
> hdev->acked_features);
> + status->vhost_dev->backend_features =
> + qmp_decode_features(vdev->device_id,
> hdev->backend_features);
> + status->vhost_dev->protocol_features =
> + qmp_decode_protocols(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;
> diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
> index 58a73e7b7a..4aaa21faf6 100644
> --- a/include/hw/virtio/vhost.h
> +++ b/include/hw/virtio/vhost.h
> @@ -5,6 +5,9 @@
> #include "hw/virtio/virtio.h"
> #include "exec/memory.h"
>
> +#define VHOST_F_DEVICE_IOTLB 63
> +#define VHOST_USER_F_PROTOCOL_FEATURES 30
> +
> /* Generic structures common for any vhost based device. */
>
> struct vhost_inflight {
> diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> index ef99a626a8..9df4e081c9 100644
> --- a/include/hw/virtio/virtio.h
> +++ b/include/hw/virtio/virtio.h
> @@ -71,6 +71,25 @@ typedef struct VirtQueueElement
> #define TYPE_VIRTIO_DEVICE "virtio-device"
> OBJECT_DECLARE_TYPE(VirtIODevice, VirtioDeviceClass, VIRTIO_DEVICE)
>
> +typedef struct {
> + int virtio_bit;
> + const char *feature_name;
> +} qmp_virtio_feature_map_t;
> +
> +extern qmp_virtio_feature_map_t serial_map[];
> +extern qmp_virtio_feature_map_t blk_map[];
> +extern qmp_virtio_feature_map_t gpu_map[];
> +extern qmp_virtio_feature_map_t net_map[];
> +extern qmp_virtio_feature_map_t scsi_map[];
> +extern qmp_virtio_feature_map_t balloon_map[];
> +extern qmp_virtio_feature_map_t iommu_map[];
> +extern qmp_virtio_feature_map_t input_map[];
> +extern qmp_virtio_feature_map_t fs_map[];
> +extern qmp_virtio_feature_map_t vsock_map[];
> +extern qmp_virtio_feature_map_t crypto_map[];
> +extern qmp_virtio_feature_map_t mem_map[];
> +extern qmp_virtio_feature_map_t i2c_map[];
> +
>
>
> So this hack where extern is in a common header, but the
> actual values are spread in individual C files is not really
> acceptable.
>
> Understood. Will move these map definitions into virtio.c
> instead.
>
>
> Also, the names are too generic and are not prefixed with
> virtio which is a problem for a generic virtio.h header.
> this kind of name is only ok as a static variable.
>
> No problem, I can change them to something like
> 'virtio_x_feature_map'.
>
>
> And, it seems to be causing problems when some devices
> are disabled at config time. E.g. with virtio gpu disabled
> we get:
>
>
> https://urldefense.com/v3/__https://gitlab.com/qemu-project/qemu/-/jobs/2463276202__;!!ACWV5N9M2RV99hQ!LxUl7ygdoZjKT_zWfAfkcior1j2Bn4E5okOrtbudwWyRsmGyRMxMdQlIVhn5AhR7n6LHvABmkhnR$
>
> https://urldefense.com/v3/__https://gitlab.com/qemu-project/qemu/-/jobs/2463276291__;!!ACWV5N9M2RV99hQ!LxUl7ygdoZjKT_zWfAfkcior1j2Bn4E5okOrtbudwWyRsmGyRMxMdQlIVhn5AhR7n6LHvK89VWxr$
>
> libqemu-ppc64-softmmu.fa.p/hw_virtio_virtio.c.o: In function
> `qmp_decode_features':
> /builds/qemu-project/qemu/build/../hw/virtio/virtio.c:4167: undefined
> reference to `gpu_map'
> /builds/qemu-project/qemu/build/../hw/virtio/virtio.c:4167: undefined
> reference to `gpu_map'
>
>
> I could not figure it out from a quick look, please debug.
>
> Got it, will debug. May be missing an #ifdef somewhere I suspect...
>
> It will take some time for me to get the next series (v15) out since
> I'll be away next week but hopefully I'll be able to get them out sooner
> rather than later once I'm back.
>
> Thanks,
>
> Jonah
>
>
>
>
> enum virtio_device_endian {
> VIRTIO_DEVICE_ENDIAN_UNKNOWN,
> VIRTIO_DEVICE_ENDIAN_LITTLE,
> diff --git a/qapi/virtio.json b/qapi/virtio.json
> index ba61d83df7..474a8bd64e 100644
> --- a/qapi/virtio.json
> +++ b/qapi/virtio.json
> @@ -106,10 +106,10 @@
> 'n-tmp-sections': 'int',
> 'nvqs': 'uint32',
> 'vq-index': 'int',
> - 'features': 'uint64',
> - 'acked-features': 'uint64',
> - 'backend-features': 'uint64',
> - 'protocol-features': 'uint64',
> + 'features': 'VirtioDeviceFeatures',
> + 'acked-features': 'VirtioDeviceFeatures',
> + 'backend-features': 'VirtioDeviceFeatures',
> + 'protocol-features': 'VhostDeviceProtocols',
> 'max-queues': 'uint64',
> 'backend-cap': 'uint64',
> 'log-enabled': 'bool',
> @@ -176,11 +176,11 @@
> 'device-id': 'uint16',
> 'vhost-started': 'bool',
> 'device-endian': 'str',
> - 'guest-features': 'uint64',
> - 'host-features': 'uint64',
> - 'backend-features': 'uint64',
> + 'guest-features': 'VirtioDeviceFeatures',
> + 'host-features': 'VirtioDeviceFeatures',
> + 'backend-features': 'VirtioDeviceFeatures',
> 'num-vqs': 'int',
> - 'status': 'uint8',
> + 'status': 'VirtioDeviceStatus',
> 'isr': 'uint8',
> 'queue-sel': 'uint16',
> 'vm-running': 'bool',
> @@ -222,14 +222,28 @@
> # "name": "virtio-crypto",
> # "started": true,
> # "device-id": 20,
> -# "backend-features": 0,
> +# "backend-features": {
> +# "transports": [],
> +# "dev-features": []
> +# },
> # "start-on-kick": false,
> # "isr": 1,
> # "broken": false,
> -# "status": 15,
> +# "status": {
> +# "statuses": ["ACKNOWLEDGE", "DRIVER", "FEATURES_OK",
> +# "DRIVER_OK"]
> +# },
> # "num-vqs": 2,
> -# "guest-features": 5100273664,
> -# "host-features": 6325010432,
> +# "guest-features": {
> +# "transports": ["EVENT_IDX", "INDIRECT_DESC",
> "VERSION_1"],
> +# "dev-features": []
> +# },
> +# "host-features": {
> +# "transports": ["PROTOCOL_FEATURES", "EVENT_IDX",
> +# "INDIRECT_DESC", "VERSION_1",
> "ANY_LAYOUT",
> +# "NOTIFY_ON_EMPTY"],
> +# "dev-features": []
> +# },
> # "use-guest-notifier-mask": true,
> # "vm-running": true,
> # "queue-sel": 1,
> @@ -257,22 +271,65 @@
> # "max-queues": 1,
> # "backend-cap": 2,
> # "log-size": 0,
> -# "backend-features": 0,
> +# "backend-features": {
> +# "transports": [],
> +# "dev-features": []
> +# },
> # "nvqs": 2,
> -# "protocol-features": 0,
> +# "protocol-features": {
> +# "protocols": []
> +# },
> # "vq-index": 0,
> # "log-enabled": false,
> -# "acked-features": 5100306432,
> -# "features": 13908344832
> +# "acked-features": {
> +# "transports": ["EVENT_IDX", "INDIRECT_DESC",
> "VERSION_1",
> +# "ANY_LAYOUT", "NOTIFY_ON_EMPTY"],
> +# "dev-features": ["MRG_RXBUF"]
> +# },
> +# "features": {
> +# "transports": ["EVENT_IDX", "INDIRECT_DESC",
> +# "IOMMU_PLATFORM", "VERSION_1",
> "ANY_LAYOUT",
> +# "NOTIFY_ON_EMPTY"],
> +# "dev-features": ["LOG_ALL", "MRG_RXBUF"]
> +# }
> +# },
> +# "backend-features": {
> +# "transports": ["PROTOCOL_FEATURES", "EVENT_IDX",
> "INDIRECT_DESC",
> +# "VERSION_1", "ANY_LAYOUT",
> "NOTIFY_ON_EMPTY"],
> +# "dev-features": ["GSO", "CTRL_MAC_ADDR",
> "GUEST_ANNOUNCE", "CTRL_RX_EXTRA",
> +# "CTRL_VLAN", "CTRL_RX", "CTRL_VQ",
> "STATUS", "MRG_RXBUF",
> +# "HOST_UFO", "HOST_ECN",
> "HOST_TSO6", "HOST_TSO4",
> +# "GUEST_UFO", "GUEST_ECN",
> "GUEST_TSO6", "GUEST_TSO4",
> +# "MAC", "CTRL_GUEST_OFFLOADS",
> "GUEST_CSUM", "CSUM"]
> # },
> -# "backend-features": 6337593319,
> # "start-on-kick": false,
> # "isr": 1,
> # "broken": false,
> -# "status": 15,
> +# "status": {
> +# "statuses": ["ACKNOWLEDGE", "DRIVER", "FEATURES_OK",
> "DRIVER_OK"]
> +# },
> # "num-vqs": 3,
> -# "guest-features": 5111807911,
> -# "host-features": 6337593319,
> +# "guest-features": {
> +# "transports": ["EVENT_IDX", "INDIRECT_DESC",
> "VERSION_1"],
> +# "dev-features": ["CTRL_MAC_ADDR", "GUEST_ANNOUNCE",
> "CTRL_VLAN",
> +# "CTRL_RX", "CTRL_VQ", "STATUS",
> "MRG_RXBUF",
> +# "HOST_UFO", "HOST_ECN", "HOST_TSO6",
> +# "HOST_TSO4", "GUEST_UFO",
> "GUEST_ECN",
> +# "GUEST_TSO6", "GUEST_TSO4", "MAC",
> +# "CTRL_GUEST_OFFLOADS",
> "GUEST_CSUM", "CSUM"]
> +# },
> +# "host-features": {
> +# "transports": ["PROTOCOL_FEATURES", "EVENT_IDX",
> +# "INDIRECT_DESC", "VERSION_1",
> "ANY_LAYOUT",
> +# "NOTIFY_ON_EMPTY"],
> +# "dev-features": ["GSO", "CTRL_MAC_ADDR",
> "GUEST_ANNOUNCE",
> +# "CTRL_RX_EXTRA", "CTRL_VLAN",
> "CTRL_RX",
> +# "CTRL_VQ", "STATUS", "MRG_RXBUF",
> "HOST_UFO",
> +# "HOST_ECN", "HOST_TSO4",
> "HOST_TSO4",
> +# "GUEST_UFO", "GUEST_ECN",
> "GUEST_TSO6",
> +# "GUEST_TSO4", "MAC",
> "CTRL_GUEST_OFFLOADS",
> +# "GUEST_CSUM", "CSUM"]
> +# },
> # "use-guest-notifier-mask": true,
> # "vm-running": true,
> # "queue-sel": 2,
> @@ -288,3 +345,62 @@
> 'data': { 'path': 'str' },
> 'returns': 'VirtioStatus',
> 'features': [ 'unstable' ] }
> +
> +##
> +# @VirtioDeviceStatus:
> +#
> +# A structure defined to list the configuration statuses of a virtio
> +# device
> +#
> +# @statuses: List of decoded configuration statuses of the virtio
> +# device
> +#
> +# @unknown-statuses: Virtio device statuses bitmap that have not
> been decoded
> +#
> +# Since: 7.0
> +##
> +
> +{ 'struct': 'VirtioDeviceStatus',
> + 'data': { 'statuses': [ 'str' ],
> + '*unknown-statuses': 'uint8' } }
> +
> +##
> +# @VhostDeviceProtocols:
> +#
> +# A structure defined to list the vhost user protocol features of a
> +# Vhost User device
> +#
> +# @protocols: List of decoded vhost user protocol features of a vhost
> +# user device
> +#
> +# @unknown-protocols: Vhost user device protocol features bitmap that
> +# have not been decoded
> +#
> +# Since: 7.0
> +##
> +
> +{ 'struct': 'VhostDeviceProtocols',
> + 'data': { 'protocols': [ 'str' ],
> + '*unknown-protocols': 'uint64' } }
> +
> +##
> +# @VirtioDeviceFeatures:
> +#
> +# The common fields that apply to most Virtio devices. Some devices
> +# may not have their own device-specific features (e.g. virtio-rng).
> +#
> +# @transports: List of transport features of the virtio device
> +#
> +# @dev-features: List of device-specific features (if the device has
> +# unique features)
> +#
> +# @unknown-dev-features: Virtio device features bitmap that have not
> +# been decoded
> +#
> +# Since: 7.0
> +##
> +
> +{ 'struct': 'VirtioDeviceFeatures',
> + 'data': { 'transports': [ 'str' ],
> + '*dev-features': [ 'str' ],
> + '*unknown-dev-features': 'uint64' } }
> --
> 2.35.1
>