On Tue, Feb 13, 2024 at 6:26 PM Michael S. Tsirkin <m...@redhat.com> wrote:
> On Fri, Feb 02, 2024 at 10:32:15PM +0800, Hyman Huang wrote: > > x-query-virtio-status returns several sets of virtio feature and > > status flags. It goes back to v7.2.0. > > > > In the initial commit 90c066cd682 (qmp: add QMP command > > x-query-virtio-status), we returned them as numbers, using virtio's > > well-known binary encoding. > > > > The next commit f3034ad71fc (qmp: decode feature & status bits in > > virtio-status) replaced the numbers by objects. The objects represent > > bits QEMU knows symbolically, and any unknown bits numerically just like > > before. > > > > Commit 8a8287981d1 (hmp: add virtio commands) the matching HMP command > > "info virtio" (and a few more, which aren't relevant here). > > > > The symbolic representation uses lists of strings. The string format is > > undocumented. The strings look like "WELL_KNOWN_SYMBOL: human readable > > explanation". > > > > This symbolic representation is nice for humans. Machines it can save > > the trouble of decoding virtio's well-known binary encoding. > > > > However, we sometimes want to compare features and status bits without > > caring for their exact meaning. Say we want to verify the correctness > > of the virtio negotiation between guest, QEMU, and OVS-DPDK. We can use > > QMP command x-query-virtio-status to retrieve vhost-user net device > > features, and the "ovs-vsctl list interface" command to retrieve > > interface features. Without commit f3034ad71fc, we could then simply > > compare the numbers. With this commit, we first have to map from the > > strings back to the numeric encoding. > > > > Revert the decoding for QMP, but keep it for HMP. > > Is there a way to maybe have both decoded and numerical one? > What if the next patch went back to this implementation in the following patch? All you need to do is add a matching xxx_bits entry for each feature and status. https://patchew.org/QEMU/cover.1700319559.git.yong.hu...@smartx.com/3c7161a47b141af04b1f8272e8e24c5faa46ddb2.1700319559.git.yong.hu...@smartx.com/ E.g. I mostly use QMP even when I read it myself. > Thus, it is recommended that both numerical and decoded types be kept for QMP; this approach can be at odds with what was previously discussed. What do you think about this, Markus? > > This makes the QMP command easier to use for use cases where we > > don't need to decode, like the comparison above. For use cases > > where we need to decode, we replace parsing undocumented strings by > > decoding virtio's well-known binary encoding. > > > > Incompatible change; acceptable because x-query-virtio-status does > > comes without a stability promise. > > > > Signed-off-by: Hyman Huang <yong.hu...@smartx.com> > > --- > > hw/virtio/virtio-hmp-cmds.c | 25 +++-- > > hw/virtio/virtio-qmp.c | 23 ++--- > > qapi/virtio.json | 192 ++++-------------------------------- > > 3 files changed, 45 insertions(+), 195 deletions(-) > > > > diff --git a/hw/virtio/virtio-hmp-cmds.c b/hw/virtio/virtio-hmp-cmds.c > > index 477c97dea2..721c630ab0 100644 > > --- a/hw/virtio/virtio-hmp-cmds.c > > +++ b/hw/virtio/virtio-hmp-cmds.c > > @@ -6,6 +6,7 @@ > > */ > > > > #include "qemu/osdep.h" > > +#include "virtio-qmp.h" > > #include "monitor/hmp.h" > > #include "monitor/monitor.h" > > #include "qapi/qapi-commands-virtio.h" > > @@ -145,13 +146,17 @@ void hmp_virtio_status(Monitor *mon, const QDict > *qdict) > > monitor_printf(mon, " endianness: %s\n", > > s->device_endian); > > monitor_printf(mon, " status:\n"); > > - hmp_virtio_dump_status(mon, s->status); > > + hmp_virtio_dump_status(mon, > > + qmp_decode_status(s->status)); > > monitor_printf(mon, " Guest features:\n"); > > - hmp_virtio_dump_features(mon, s->guest_features); > > + hmp_virtio_dump_features(mon, > > + qmp_decode_features(s->device_id, s->guest_features)); > > monitor_printf(mon, " Host features:\n"); > > - hmp_virtio_dump_features(mon, s->host_features); > > + hmp_virtio_dump_features(mon, > > + qmp_decode_features(s->device_id, s->host_features)); > > monitor_printf(mon, " Backend features:\n"); > > - hmp_virtio_dump_features(mon, s->backend_features); > > + hmp_virtio_dump_features(mon, > > + qmp_decode_features(s->device_id, s->backend_features)); > > > > if (s->vhost_dev) { > > monitor_printf(mon, " VHost:\n"); > > @@ -172,13 +177,17 @@ void hmp_virtio_status(Monitor *mon, const QDict > *qdict) > > monitor_printf(mon, " log_size: %"PRId64"\n", > > s->vhost_dev->log_size); > > monitor_printf(mon, " Features:\n"); > > - hmp_virtio_dump_features(mon, s->vhost_dev->features); > > + hmp_virtio_dump_features(mon, > > + qmp_decode_features(s->device_id, s->vhost_dev->features)); > > monitor_printf(mon, " Acked features:\n"); > > - hmp_virtio_dump_features(mon, s->vhost_dev->acked_features); > > + hmp_virtio_dump_features(mon, > > + qmp_decode_features(s->device_id, > s->vhost_dev->acked_features)); > > monitor_printf(mon, " Backend features:\n"); > > - hmp_virtio_dump_features(mon, s->vhost_dev->backend_features); > > + hmp_virtio_dump_features(mon, > > + qmp_decode_features(s->device_id, > s->vhost_dev->backend_features)); > > monitor_printf(mon, " Protocol features:\n"); > > - hmp_virtio_dump_protocols(mon, s->vhost_dev->protocol_features); > > + hmp_virtio_dump_protocols(mon, > > + qmp_decode_protocols(s->vhost_dev->protocol_features)); > > } > > > > qapi_free_VirtioStatus(s); > > diff --git a/hw/virtio/virtio-qmp.c b/hw/virtio/virtio-qmp.c > > index 1dd96ed20f..1660c17653 100644 > > --- a/hw/virtio/virtio-qmp.c > > +++ b/hw/virtio/virtio-qmp.c > > @@ -733,12 +733,9 @@ 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 = 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); > > + 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: > > @@ -753,7 +750,7 @@ VirtioStatus *qmp_x_query_virtio_status(const char > *path, Error **errp) > > } > > > > status->num_vqs = virtio_get_num_queues(vdev); > > - status->status = qmp_decode_status(vdev->status); > > + status->status = vdev->status; > > status->isr = vdev->isr; > > status->queue_sel = vdev->queue_sel; > > status->vm_running = vdev->vm_running; > > @@ -775,14 +772,10 @@ 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 = > > - 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->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; > > diff --git a/qapi/virtio.json b/qapi/virtio.json > > index 19c7c36e36..26516fb29c 100644 > > --- a/qapi/virtio.json > > +++ b/qapi/virtio.json > > @@ -102,10 +102,10 @@ > > 'n-tmp-sections': 'int', > > 'nvqs': 'uint32', > > 'vq-index': 'int', > > - 'features': 'VirtioDeviceFeatures', > > - 'acked-features': 'VirtioDeviceFeatures', > > - 'backend-features': 'VirtioDeviceFeatures', > > - 'protocol-features': 'VhostDeviceProtocols', > > + 'features': 'uint64', > > + 'acked-features': 'uint64', > > + 'backend-features': 'uint64', > > + 'protocol-features': 'uint64', > > 'max-queues': 'uint64', > > 'backend-cap': 'uint64', > > 'log-enabled': 'bool', > > @@ -170,11 +170,11 @@ > > 'device-id': 'uint16', > > 'vhost-started': 'bool', > > 'device-endian': 'str', > > - 'guest-features': 'VirtioDeviceFeatures', > > - 'host-features': 'VirtioDeviceFeatures', > > - 'backend-features': 'VirtioDeviceFeatures', > > + 'guest-features': 'uint64', > > + 'host-features': 'uint64', > > + 'backend-features': 'uint64', > > 'num-vqs': 'int', > > - 'status': 'VirtioDeviceStatus', > > + 'status': 'uint8', > > 'isr': 'uint8', > > 'queue-sel': 'uint16', > > 'vm-running': 'bool', > > @@ -217,41 +217,14 @@ > > # "name": "virtio-crypto", > > # "started": true, > > # "device-id": 20, > > -# "backend-features": { > > -# "transports": [], > > -# "dev-features": [] > > -# }, > > +# "backend-features": 0, > > # "start-on-kick": false, > > # "isr": 1, > > # "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" > > -# ] > > -# }, > > +# "status": 15, > > # "num-vqs": 2, > > -# "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": { > > -# "unknown-dev-features": 1073741824, > > -# "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)", > > -# "VIRTIO_F_ANY_LAYOUT: Device accepts arbitrary desc. > layouts", > > -# "VIRTIO_F_NOTIFY_ON_EMPTY: Notify when device runs > out of avail. descs. on VQ" > > -# ] > > -# }, > > +# "guest-features": 5100273664, > > +# "host-features": 6325010432, > > # "use-guest-notifier-mask": true, > > # "vm-running": true, > > # "queue-sel": 1, > > @@ -279,147 +252,22 @@ > > # "max-queues": 1, > > # "backend-cap": 2, > > # "log-size": 0, > > -# "backend-features": { > > -# "dev-features": [], > > -# "transports": [] > > -# }, > > +# "backend-features": 0, > > # "nvqs": 2, > > -# "protocol-features": { > > -# "protocols": [] > > -# }, > > +# "protocol-features": 0, > > # "vq-index": 0, > > # "log-enabled": false, > > -# "acked-features": { > > -# "dev-features": [ > > -# "VIRTIO_NET_F_MRG_RXBUF: Driver can merge > receive buffers" > > -# ], > > -# "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", > > -# "VIRTIO_NET_F_MRG_RXBUF: Driver can merge > receive buffers" > > -# ], > > -# "transports": [ > > -# "VIRTIO_RING_F_EVENT_IDX: Used & avail. event > fields enabled", > > -# "VIRTIO_RING_F_INDIRECT_DESC: Indirect > descriptors supported", > > -# "VIRTIO_F_IOMMU_PLATFORM: Device can be used on > IOMMU platform", > > -# "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": [ > > -# "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol > features negotiation supported", > > -# "VIRTIO_NET_F_GSO: Handling GSO-type packets > supported", > > -# "VIRTIO_NET_F_CTRL_MAC_ADDR: MAC address set through > control channel", > > -# "VIRTIO_NET_F_GUEST_ANNOUNCE: Driver sending > gratuitous packets supported", > > -# "VIRTIO_NET_F_CTRL_RX_EXTRA: Extra RX mode control > supported", > > -# "VIRTIO_NET_F_CTRL_VLAN: Control channel VLAN > filtering supported", > > -# "VIRTIO_NET_F_CTRL_RX: Control channel RX mode > supported", > > -# "VIRTIO_NET_F_CTRL_VQ: Control channel available", > > -# "VIRTIO_NET_F_STATUS: Configuration status field > available", > > -# "VIRTIO_NET_F_MRG_RXBUF: Driver can merge receive > buffers", > > -# "VIRTIO_NET_F_HOST_UFO: Device can receive UFO", > > -# "VIRTIO_NET_F_HOST_ECN: Device can receive TSO with > ECN", > > -# "VIRTIO_NET_F_HOST_TSO6: Device can receive TSOv6", > > -# "VIRTIO_NET_F_HOST_TSO4: Device can receive TSOv4", > > -# "VIRTIO_NET_F_GUEST_UFO: Driver can receive UFO", > > -# "VIRTIO_NET_F_GUEST_ECN: Driver can receive TSO with > ECN", > > -# "VIRTIO_NET_F_GUEST_TSO6: Driver can receive TSOv6", > > -# "VIRTIO_NET_F_GUEST_TSO4: Driver can receive TSOv4", > > -# "VIRTIO_NET_F_MAC: Device has given MAC address", > > -# "VIRTIO_NET_F_CTRL_GUEST_OFFLOADS: Control channel > offloading reconfig. supported", > > -# "VIRTIO_NET_F_GUEST_CSUM: Driver handling packets > with partial checksum supported", > > -# "VIRTIO_NET_F_CSUM: Device handling packets with > partial checksum 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" > > -# ] > > +# "acked-features": 5100306432, > > +# "features": 13908344832, > > # }, > > +# "backend-features": 6337593319, > > # "start-on-kick": false, > > # "isr": 1, > > # "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" > > -# ] > > -# }, > > +# "status": 15, > > # "num-vqs": 3, > > -# "guest-features": { > > -# "dev-features": [ > > -# "VIRTIO_NET_F_CTRL_MAC_ADDR: MAC address set through > control channel", > > -# "VIRTIO_NET_F_GUEST_ANNOUNCE: Driver sending > gratuitous packets supported", > > -# "VIRTIO_NET_F_CTRL_VLAN: Control channel VLAN > filtering supported", > > -# "VIRTIO_NET_F_CTRL_RX: Control channel RX mode > supported", > > -# "VIRTIO_NET_F_CTRL_VQ: Control channel available", > > -# "VIRTIO_NET_F_STATUS: Configuration status field > available", > > -# "VIRTIO_NET_F_MRG_RXBUF: Driver can merge receive > buffers", > > -# "VIRTIO_NET_F_HOST_UFO: Device can receive UFO", > > -# "VIRTIO_NET_F_HOST_ECN: Device can receive TSO with > ECN", > > -# "VIRTIO_NET_F_HOST_TSO6: Device can receive TSOv6", > > -# "VIRTIO_NET_F_HOST_TSO4: Device can receive TSOv4", > > -# "VIRTIO_NET_F_GUEST_UFO: Driver can receive UFO", > > -# "VIRTIO_NET_F_GUEST_ECN: Driver can receive TSO with > ECN", > > -# "VIRTIO_NET_F_GUEST_TSO6: Driver can receive TSOv6", > > -# "VIRTIO_NET_F_GUEST_TSO4: Driver can receive TSOv4", > > -# "VIRTIO_NET_F_MAC: Device has given MAC address", > > -# "VIRTIO_NET_F_CTRL_GUEST_OFFLOADS: Control channel > offloading reconfig. supported", > > -# "VIRTIO_NET_F_GUEST_CSUM: Driver handling packets > with partial checksum supported", > > -# "VIRTIO_NET_F_CSUM: Device handling packets with > partial checksum 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)" > > -# ] > > -# }, > > -# "host-features": { > > -# "dev-features": [ > > -# "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol > features negotiation supported", > > -# "VIRTIO_NET_F_GSO: Handling GSO-type packets > supported", > > -# "VIRTIO_NET_F_CTRL_MAC_ADDR: MAC address set through > control channel", > > -# "VIRTIO_NET_F_GUEST_ANNOUNCE: Driver sending > gratuitous packets supported", > > -# "VIRTIO_NET_F_CTRL_RX_EXTRA: Extra RX mode control > supported", > > -# "VIRTIO_NET_F_CTRL_VLAN: Control channel VLAN > filtering supported", > > -# "VIRTIO_NET_F_CTRL_RX: Control channel RX mode > supported", > > -# "VIRTIO_NET_F_CTRL_VQ: Control channel available", > > -# "VIRTIO_NET_F_STATUS: Configuration status field > available", > > -# "VIRTIO_NET_F_MRG_RXBUF: Driver can merge receive > buffers", > > -# "VIRTIO_NET_F_HOST_UFO: Device can receive UFO", > > -# "VIRTIO_NET_F_HOST_ECN: Device can receive TSO with > ECN", > > -# "VIRTIO_NET_F_HOST_TSO6: Device can receive TSOv6", > > -# "VIRTIO_NET_F_HOST_TSO4: Device can receive TSOv4", > > -# "VIRTIO_NET_F_GUEST_UFO: Driver can receive UFO", > > -# "VIRTIO_NET_F_GUEST_ECN: Driver can receive TSO with > ECN", > > -# "VIRTIO_NET_F_GUEST_TSO6: Driver can receive TSOv6", > > -# "VIRTIO_NET_F_GUEST_TSO4: Driver can receive TSOv4", > > -# "VIRTIO_NET_F_MAC: Device has given MAC address", > > -# "VIRTIO_NET_F_CTRL_GUEST_OFFLOADS: Control channel > offloading reconfig. supported", > > -# "VIRTIO_NET_F_GUEST_CSUM: Driver handling packets > with partial checksum supported", > > -# "VIRTIO_NET_F_CSUM: Device handling packets with > partial checksum 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" > > -# ] > > -# }, > > +# "guest-features": 5111807911, > > +# "host-features": 6337593319, > > # "use-guest-notifier-mask": true, > > # "vm-running": true, > > # "queue-sel": 2, > > -- > > 2.31.1 > > -- Best regards