qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/3] Adjust the output of x-query-virtio-status
@ 2024-02-02 14:32 Hyman Huang
  2024-02-02 14:32 ` [PATCH v3 1/3] qmp: Switch x-query-virtio-status back to numeric encoding Hyman Huang
                   ` (3 more replies)
  0 siblings, 4 replies; 14+ messages in thread
From: Hyman Huang @ 2024-02-02 14:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: Markus Armbruster, Michael S . Tsirkin, Eric Blake, yong.huang

Sorry for the late post of version 3. The modifications are as follows:

v3:
- Rebase on master
- Use the refined commit message furnished by Markus for [PATCH v2 1/2] 
- Drop the [PATCH v2 2/2]
- Add [PATCH v3 2/3] to declare the decoding functions to static
- Add [PATCH v3 3/3] to Define VhostDeviceProtocols and
  VirtioDeviceFeatures as plain C types

Since Markus inspired all of the alterations above, we would like to
thank him for his contribution to this series.

Please review,
Yong

v2:
- Changing the hmp_virtio_dump_xxx function signatures to implement
  the bitmap decoding, suggested by Philippe. 

This patchset is derived from the series:
https://lore.kernel.org/qemu-devel/cover.1699793550.git.yong.huang@smartx.com/
Please go to the link to see more background information.

The following points are what we have done in the patchset:
1. Take the policy of adding human-readable output just in HMP.
2. For the HMP output, display the human-readable information and
   drop the unknown bits in practice.
3. For the QMP output, remove the descriptive strings and only
   display bits encoded as numbers.

Hyman Huang (3):
  qmp: Switch x-query-virtio-status back to numeric encoding
  virtio: Declare the decoding functions to static
  qapi: Define VhostDeviceProtocols and VirtioDeviceFeatures as plain C
    types

 hw/virtio/meson.build       |   3 +-
 hw/virtio/virtio-hmp-cmds.c | 702 +++++++++++++++++++++++++++++++++++-
 hw/virtio/virtio-qmp.c      | 684 +----------------------------------
 hw/virtio/virtio-qmp.h      |   3 -
 qapi/virtio.json            | 231 +-----------
 5 files changed, 723 insertions(+), 900 deletions(-)

-- 
2.31.1



^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v3 1/3] qmp: Switch x-query-virtio-status back to numeric encoding
  2024-02-02 14:32 [PATCH v3 0/3] Adjust the output of x-query-virtio-status Hyman Huang
@ 2024-02-02 14:32 ` Hyman Huang
  2024-02-13 10:26   ` Michael S. Tsirkin
  2024-02-19 15:18   ` Markus Armbruster
  2024-02-02 14:32 ` [PATCH v3 2/3] virtio: Declare the decoding functions to static Hyman Huang
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 14+ messages in thread
From: Hyman Huang @ 2024-02-02 14:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: Markus Armbruster, Michael S . Tsirkin, Eric Blake, yong.huang

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.

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.huang@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



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v3 2/3] virtio: Declare the decoding functions to static
  2024-02-02 14:32 [PATCH v3 0/3] Adjust the output of x-query-virtio-status Hyman Huang
  2024-02-02 14:32 ` [PATCH v3 1/3] qmp: Switch x-query-virtio-status back to numeric encoding Hyman Huang
@ 2024-02-02 14:32 ` Hyman Huang
  2024-02-19 15:38   ` Markus Armbruster
  2024-02-02 14:32 ` [PATCH v3 3/3] qapi: Define VhostDeviceProtocols and VirtioDeviceFeatures as plain C types Hyman Huang
  2024-02-13 10:25 ` [PATCH v3 0/3] Adjust the output of x-query-virtio-status Michael S. Tsirkin
  3 siblings, 1 reply; 14+ messages in thread
From: Hyman Huang @ 2024-02-02 14:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: Markus Armbruster, Michael S . Tsirkin, Eric Blake, yong.huang

qmp_decode_protocols(), qmp_decode_status(), and qmp_decode_features()
are now only used in virtio-hmp-cmds.c.  So move them into there,
redeclare them to static, and replace the qmp_ prefix with hmp_.

Signed-off-by: Hyman Huang <yong.huang@smartx.com>
---
 hw/virtio/meson.build       |   3 +-
 hw/virtio/virtio-hmp-cmds.c | 677 +++++++++++++++++++++++++++++++++++-
 hw/virtio/virtio-qmp.c      | 661 -----------------------------------
 hw/virtio/virtio-qmp.h      |   3 -
 4 files changed, 670 insertions(+), 674 deletions(-)

diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build
index 47baf00366..6665669480 100644
--- a/hw/virtio/meson.build
+++ b/hw/virtio/meson.build
@@ -9,7 +9,7 @@ system_virtio_ss.add(when: 'CONFIG_VHOST_VDPA_DEV', if_true: files('vdpa-dev.c')
 
 specific_virtio_ss = ss.source_set()
 specific_virtio_ss.add(files('virtio.c'))
-specific_virtio_ss.add(files('virtio-config-io.c', 'virtio-qmp.c'))
+specific_virtio_ss.add(files('virtio-config-io.c', 'virtio-qmp.c', 'virtio-hmp-cmds.c'))
 
 if have_vhost
   system_virtio_ss.add(files('vhost.c'))
@@ -74,7 +74,6 @@ specific_virtio_ss.add_all(when: 'CONFIG_VIRTIO_PCI', if_true: virtio_pci_ss)
 system_ss.add_all(when: 'CONFIG_VIRTIO', if_true: system_virtio_ss)
 system_ss.add(when: 'CONFIG_VIRTIO', if_false: files('vhost-stub.c'))
 system_ss.add(when: 'CONFIG_VIRTIO', if_false: files('virtio-stub.c'))
-system_ss.add(files('virtio-hmp-cmds.c'))
 
 specific_ss.add_all(when: 'CONFIG_VIRTIO', if_true: specific_virtio_ss)
 system_ss.add(when: 'CONFIG_ACPI', if_true: files('virtio-acpi.c'))
diff --git a/hw/virtio/virtio-hmp-cmds.c b/hw/virtio/virtio-hmp-cmds.c
index 721c630ab0..f95bad0069 100644
--- a/hw/virtio/virtio-hmp-cmds.c
+++ b/hw/virtio/virtio-hmp-cmds.c
@@ -11,7 +11,668 @@
 #include "monitor/monitor.h"
 #include "qapi/qapi-commands-virtio.h"
 #include "qapi/qmp/qdict.h"
+#include "hw/virtio/vhost-user.h"
 
+#include "standard-headers/linux/virtio_ids.h"
+#include "standard-headers/linux/vhost_types.h"
+#include "standard-headers/linux/virtio_blk.h"
+#include "standard-headers/linux/virtio_console.h"
+#include "standard-headers/linux/virtio_gpu.h"
+#include "standard-headers/linux/virtio_net.h"
+#include "standard-headers/linux/virtio_scsi.h"
+#include "standard-headers/linux/virtio_i2c.h"
+#include "standard-headers/linux/virtio_balloon.h"
+#include "standard-headers/linux/virtio_iommu.h"
+#include "standard-headers/linux/virtio_mem.h"
+#include "standard-headers/linux/virtio_vsock.h"
+#include "standard-headers/linux/virtio_gpio.h"
+
+#include CONFIG_DEVICES
+
+#define FEATURE_ENTRY(name, desc) (qmp_virtio_feature_map_t) \
+    { .virtio_bit = name, .feature_desc = desc }
+
+/* Virtio transport features mapping */
+static const qmp_virtio_feature_map_t virtio_transport_map[] = {
+    /* Virtio device transport features */
+#ifndef VIRTIO_CONFIG_NO_LEGACY
+    FEATURE_ENTRY(VIRTIO_F_NOTIFY_ON_EMPTY, \
+            "VIRTIO_F_NOTIFY_ON_EMPTY: Notify when device runs out of avail. "
+            "descs. on VQ"),
+    FEATURE_ENTRY(VIRTIO_F_ANY_LAYOUT, \
+            "VIRTIO_F_ANY_LAYOUT: Device accepts arbitrary desc. layouts"),
+#endif /* !VIRTIO_CONFIG_NO_LEGACY */
+    FEATURE_ENTRY(VIRTIO_F_VERSION_1, \
+            "VIRTIO_F_VERSION_1: Device compliant for v1 spec (legacy)"),
+    FEATURE_ENTRY(VIRTIO_F_IOMMU_PLATFORM, \
+            "VIRTIO_F_IOMMU_PLATFORM: Device can be used on IOMMU platform"),
+    FEATURE_ENTRY(VIRTIO_F_RING_PACKED, \
+            "VIRTIO_F_RING_PACKED: Device supports packed VQ layout"),
+    FEATURE_ENTRY(VIRTIO_F_IN_ORDER, \
+            "VIRTIO_F_IN_ORDER: Device uses buffers in same order as made "
+            "available by driver"),
+    FEATURE_ENTRY(VIRTIO_F_ORDER_PLATFORM, \
+            "VIRTIO_F_ORDER_PLATFORM: Memory accesses ordered by platform"),
+    FEATURE_ENTRY(VIRTIO_F_SR_IOV, \
+            "VIRTIO_F_SR_IOV: Device supports single root I/O virtualization"),
+    FEATURE_ENTRY(VIRTIO_F_RING_RESET, \
+            "VIRTIO_F_RING_RESET: Driver can reset a queue individually"),
+    /* Virtio ring transport features */
+    FEATURE_ENTRY(VIRTIO_RING_F_INDIRECT_DESC, \
+            "VIRTIO_RING_F_INDIRECT_DESC: Indirect descriptors supported"),
+    FEATURE_ENTRY(VIRTIO_RING_F_EVENT_IDX, \
+            "VIRTIO_RING_F_EVENT_IDX: Used & avail. event fields enabled"),
+    { -1, "" }
+};
+
+/* Vhost-user protocol features mapping */
+static const qmp_virtio_feature_map_t vhost_user_protocol_map[] = {
+    FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_MQ, \
+            "VHOST_USER_PROTOCOL_F_MQ: Multiqueue protocol supported"),
+    FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_LOG_SHMFD, \
+            "VHOST_USER_PROTOCOL_F_LOG_SHMFD: Shared log memory fd supported"),
+    FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_RARP, \
+            "VHOST_USER_PROTOCOL_F_RARP: Vhost-user back-end RARP broadcasting "
+            "supported"),
+    FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_REPLY_ACK, \
+            "VHOST_USER_PROTOCOL_F_REPLY_ACK: Requested operation status ack. "
+            "supported"),
+    FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_NET_MTU, \
+            "VHOST_USER_PROTOCOL_F_NET_MTU: Expose host MTU to guest supported"),
+    FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_BACKEND_REQ, \
+            "VHOST_USER_PROTOCOL_F_BACKEND_REQ: Socket fd for back-end initiated "
+            "requests supported"),
+    FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_CROSS_ENDIAN, \
+            "VHOST_USER_PROTOCOL_F_CROSS_ENDIAN: Endianness of VQs for legacy "
+            "devices supported"),
+    FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_CRYPTO_SESSION, \
+            "VHOST_USER_PROTOCOL_F_CRYPTO_SESSION: Session creation for crypto "
+            "operations supported"),
+    FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_PAGEFAULT, \
+            "VHOST_USER_PROTOCOL_F_PAGEFAULT: Request servicing on userfaultfd "
+            "for accessed pages supported"),
+    FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_CONFIG, \
+            "VHOST_USER_PROTOCOL_F_CONFIG: Vhost-user messaging for virtio "
+            "device configuration space supported"),
+    FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_BACKEND_SEND_FD, \
+            "VHOST_USER_PROTOCOL_F_BACKEND_SEND_FD: Backend fd communication "
+            "channel supported"),
+    FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_HOST_NOTIFIER, \
+            "VHOST_USER_PROTOCOL_F_HOST_NOTIFIER: Host notifiers for specified "
+            "VQs supported"),
+    FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD, \
+            "VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD: Shared inflight I/O buffers "
+            "supported"),
+    FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_RESET_DEVICE, \
+            "VHOST_USER_PROTOCOL_F_RESET_DEVICE: Disabling all rings and "
+            "resetting internal device state supported"),
+    FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS, \
+            "VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS: In-band messaging "
+            "supported"),
+    FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS, \
+            "VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS: Configuration for "
+            "memory slots supported"),
+    FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_STATUS, \
+            "VHOST_USER_PROTOCOL_F_STATUS: Querying and notifying back-end "
+            "device status supported"),
+    { -1, "" }
+};
+
+/* virtio device configuration statuses */
+static const qmp_virtio_feature_map_t virtio_config_status_map[] = {
+    FEATURE_ENTRY(VIRTIO_CONFIG_S_DRIVER_OK, \
+            "VIRTIO_CONFIG_S_DRIVER_OK: Driver setup and ready"),
+    FEATURE_ENTRY(VIRTIO_CONFIG_S_FEATURES_OK, \
+            "VIRTIO_CONFIG_S_FEATURES_OK: Feature negotiation complete"),
+    FEATURE_ENTRY(VIRTIO_CONFIG_S_DRIVER, \
+            "VIRTIO_CONFIG_S_DRIVER: Guest OS compatible with device"),
+    FEATURE_ENTRY(VIRTIO_CONFIG_S_NEEDS_RESET, \
+            "VIRTIO_CONFIG_S_NEEDS_RESET: Irrecoverable error, device needs "
+            "reset"),
+    FEATURE_ENTRY(VIRTIO_CONFIG_S_FAILED, \
+            "VIRTIO_CONFIG_S_FAILED: Error in guest, device failed"),
+    FEATURE_ENTRY(VIRTIO_CONFIG_S_ACKNOWLEDGE, \
+            "VIRTIO_CONFIG_S_ACKNOWLEDGE: Valid virtio device found"),
+    { -1, "" }
+};
+
+/* virtio-blk features mapping */
+#ifdef CONFIG_VIRTIO_BLK
+static const qmp_virtio_feature_map_t virtio_blk_feature_map[] = {
+    FEATURE_ENTRY(VIRTIO_BLK_F_SIZE_MAX, \
+            "VIRTIO_BLK_F_SIZE_MAX: Max segment size is size_max"),
+    FEATURE_ENTRY(VIRTIO_BLK_F_SEG_MAX, \
+            "VIRTIO_BLK_F_SEG_MAX: Max segments in a request is seg_max"),
+    FEATURE_ENTRY(VIRTIO_BLK_F_GEOMETRY, \
+            "VIRTIO_BLK_F_GEOMETRY: Legacy geometry available"),
+    FEATURE_ENTRY(VIRTIO_BLK_F_RO, \
+            "VIRTIO_BLK_F_RO: Device is read-only"),
+    FEATURE_ENTRY(VIRTIO_BLK_F_BLK_SIZE, \
+            "VIRTIO_BLK_F_BLK_SIZE: Block size of disk available"),
+    FEATURE_ENTRY(VIRTIO_BLK_F_TOPOLOGY, \
+            "VIRTIO_BLK_F_TOPOLOGY: Topology information available"),
+    FEATURE_ENTRY(VIRTIO_BLK_F_MQ, \
+            "VIRTIO_BLK_F_MQ: Multiqueue supported"),
+    FEATURE_ENTRY(VIRTIO_BLK_F_DISCARD, \
+            "VIRTIO_BLK_F_DISCARD: Discard command supported"),
+    FEATURE_ENTRY(VIRTIO_BLK_F_WRITE_ZEROES, \
+            "VIRTIO_BLK_F_WRITE_ZEROES: Write zeroes command supported"),
+    FEATURE_ENTRY(VIRTIO_BLK_F_SECURE_ERASE, \
+            "VIRTIO_BLK_F_SECURE_ERASE: Secure erase supported"),
+    FEATURE_ENTRY(VIRTIO_BLK_F_ZONED, \
+            "VIRTIO_BLK_F_ZONED: Zoned block devices"),
+#ifndef VIRTIO_BLK_NO_LEGACY
+    FEATURE_ENTRY(VIRTIO_BLK_F_BARRIER, \
+            "VIRTIO_BLK_F_BARRIER: Request barriers supported"),
+    FEATURE_ENTRY(VIRTIO_BLK_F_SCSI, \
+            "VIRTIO_BLK_F_SCSI: SCSI packet commands supported"),
+    FEATURE_ENTRY(VIRTIO_BLK_F_FLUSH, \
+            "VIRTIO_BLK_F_FLUSH: Flush command supported"),
+    FEATURE_ENTRY(VIRTIO_BLK_F_CONFIG_WCE, \
+            "VIRTIO_BLK_F_CONFIG_WCE: Cache writeback and writethrough modes "
+            "supported"),
+#endif /* !VIRTIO_BLK_NO_LEGACY */
+    FEATURE_ENTRY(VHOST_F_LOG_ALL, \
+            "VHOST_F_LOG_ALL: Logging write descriptors supported"),
+    FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
+            "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
+            "negotiation supported"),
+    { -1, "" }
+};
+#endif
+
+/* virtio-serial features mapping */
+#ifdef CONFIG_VIRTIO_SERIAL
+static const qmp_virtio_feature_map_t virtio_serial_feature_map[] = {
+    FEATURE_ENTRY(VIRTIO_CONSOLE_F_SIZE, \
+            "VIRTIO_CONSOLE_F_SIZE: Host providing console size"),
+    FEATURE_ENTRY(VIRTIO_CONSOLE_F_MULTIPORT, \
+            "VIRTIO_CONSOLE_F_MULTIPORT: Multiple ports for device supported"),
+    FEATURE_ENTRY(VIRTIO_CONSOLE_F_EMERG_WRITE, \
+            "VIRTIO_CONSOLE_F_EMERG_WRITE: Emergency write supported"),
+    { -1, "" }
+};
+#endif
+
+/* virtio-gpu features mapping */
+#ifdef CONFIG_VIRTIO_GPU
+static const qmp_virtio_feature_map_t virtio_gpu_feature_map[] = {
+    FEATURE_ENTRY(VIRTIO_GPU_F_VIRGL, \
+            "VIRTIO_GPU_F_VIRGL: Virgl 3D mode supported"),
+    FEATURE_ENTRY(VIRTIO_GPU_F_EDID, \
+            "VIRTIO_GPU_F_EDID: EDID metadata supported"),
+    FEATURE_ENTRY(VIRTIO_GPU_F_RESOURCE_UUID, \
+            "VIRTIO_GPU_F_RESOURCE_UUID: Resource UUID assigning supported"),
+    FEATURE_ENTRY(VIRTIO_GPU_F_RESOURCE_BLOB, \
+            "VIRTIO_GPU_F_RESOURCE_BLOB: Size-based blob resources supported"),
+    FEATURE_ENTRY(VIRTIO_GPU_F_CONTEXT_INIT, \
+            "VIRTIO_GPU_F_CONTEXT_INIT: Context types and synchronization "
+            "timelines supported"),
+    FEATURE_ENTRY(VHOST_F_LOG_ALL, \
+            "VHOST_F_LOG_ALL: Logging write descriptors supported"),
+    FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
+            "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
+            "negotiation supported"),
+    { -1, "" }
+};
+#endif
+
+/* virtio-input features mapping */
+#ifdef CONFIG_VIRTIO_INPUT
+static const qmp_virtio_feature_map_t virtio_input_feature_map[] = {
+    FEATURE_ENTRY(VHOST_F_LOG_ALL, \
+            "VHOST_F_LOG_ALL: Logging write descriptors supported"),
+    FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
+            "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
+            "negotiation supported"),
+    { -1, "" }
+};
+#endif
+
+/* virtio-net features mapping */
+#ifdef CONFIG_VIRTIO_NET
+static const qmp_virtio_feature_map_t virtio_net_feature_map[] = {
+    FEATURE_ENTRY(VIRTIO_NET_F_CSUM, \
+            "VIRTIO_NET_F_CSUM: Device handling packets with partial checksum "
+            "supported"),
+    FEATURE_ENTRY(VIRTIO_NET_F_GUEST_CSUM, \
+            "VIRTIO_NET_F_GUEST_CSUM: Driver handling packets with partial "
+            "checksum supported"),
+    FEATURE_ENTRY(VIRTIO_NET_F_CTRL_GUEST_OFFLOADS, \
+            "VIRTIO_NET_F_CTRL_GUEST_OFFLOADS: Control channel offloading "
+            "reconfig. supported"),
+    FEATURE_ENTRY(VIRTIO_NET_F_MTU, \
+            "VIRTIO_NET_F_MTU: Device max MTU reporting supported"),
+    FEATURE_ENTRY(VIRTIO_NET_F_MAC, \
+            "VIRTIO_NET_F_MAC: Device has given MAC address"),
+    FEATURE_ENTRY(VIRTIO_NET_F_GUEST_TSO4, \
+            "VIRTIO_NET_F_GUEST_TSO4: Driver can receive TSOv4"),
+    FEATURE_ENTRY(VIRTIO_NET_F_GUEST_TSO6, \
+            "VIRTIO_NET_F_GUEST_TSO6: Driver can receive TSOv6"),
+    FEATURE_ENTRY(VIRTIO_NET_F_GUEST_ECN, \
+            "VIRTIO_NET_F_GUEST_ECN: Driver can receive TSO with ECN"),
+    FEATURE_ENTRY(VIRTIO_NET_F_GUEST_UFO, \
+            "VIRTIO_NET_F_GUEST_UFO: Driver can receive UFO"),
+    FEATURE_ENTRY(VIRTIO_NET_F_HOST_TSO4, \
+            "VIRTIO_NET_F_HOST_TSO4: Device can receive TSOv4"),
+    FEATURE_ENTRY(VIRTIO_NET_F_HOST_TSO6, \
+            "VIRTIO_NET_F_HOST_TSO6: Device can receive TSOv6"),
+    FEATURE_ENTRY(VIRTIO_NET_F_HOST_ECN, \
+            "VIRTIO_NET_F_HOST_ECN: Device can receive TSO with ECN"),
+    FEATURE_ENTRY(VIRTIO_NET_F_HOST_UFO, \
+            "VIRTIO_NET_F_HOST_UFO: Device can receive UFO"),
+    FEATURE_ENTRY(VIRTIO_NET_F_MRG_RXBUF, \
+            "VIRTIO_NET_F_MRG_RXBUF: Driver can merge receive buffers"),
+    FEATURE_ENTRY(VIRTIO_NET_F_STATUS, \
+            "VIRTIO_NET_F_STATUS: Configuration status field available"),
+    FEATURE_ENTRY(VIRTIO_NET_F_CTRL_VQ, \
+            "VIRTIO_NET_F_CTRL_VQ: Control channel available"),
+    FEATURE_ENTRY(VIRTIO_NET_F_CTRL_RX, \
+            "VIRTIO_NET_F_CTRL_RX: Control channel RX mode supported"),
+    FEATURE_ENTRY(VIRTIO_NET_F_CTRL_VLAN, \
+            "VIRTIO_NET_F_CTRL_VLAN: Control channel VLAN filtering supported"),
+    FEATURE_ENTRY(VIRTIO_NET_F_CTRL_RX_EXTRA, \
+            "VIRTIO_NET_F_CTRL_RX_EXTRA: Extra RX mode control supported"),
+    FEATURE_ENTRY(VIRTIO_NET_F_GUEST_ANNOUNCE, \
+            "VIRTIO_NET_F_GUEST_ANNOUNCE: Driver sending gratuitous packets "
+            "supported"),
+    FEATURE_ENTRY(VIRTIO_NET_F_MQ, \
+            "VIRTIO_NET_F_MQ: Multiqueue with automatic receive steering "
+            "supported"),
+    FEATURE_ENTRY(VIRTIO_NET_F_CTRL_MAC_ADDR, \
+            "VIRTIO_NET_F_CTRL_MAC_ADDR: MAC address set through control "
+            "channel"),
+    FEATURE_ENTRY(VIRTIO_NET_F_NOTF_COAL, \
+            "VIRTIO_NET_F_NOTF_COAL: Device supports coalescing notifications"),
+    FEATURE_ENTRY(VIRTIO_NET_F_GUEST_USO4, \
+            "VIRTIO_NET_F_GUEST_USO4: Driver can receive USOv4"),
+    FEATURE_ENTRY(VIRTIO_NET_F_GUEST_USO6, \
+            "VIRTIO_NET_F_GUEST_USO4: Driver can receive USOv6"),
+    FEATURE_ENTRY(VIRTIO_NET_F_HOST_USO, \
+            "VIRTIO_NET_F_HOST_USO: Device can receive USO"),
+    FEATURE_ENTRY(VIRTIO_NET_F_HASH_REPORT, \
+            "VIRTIO_NET_F_HASH_REPORT: Hash reporting supported"),
+    FEATURE_ENTRY(VIRTIO_NET_F_RSS, \
+            "VIRTIO_NET_F_RSS: RSS RX steering supported"),
+    FEATURE_ENTRY(VIRTIO_NET_F_RSC_EXT, \
+            "VIRTIO_NET_F_RSC_EXT: Extended coalescing info supported"),
+    FEATURE_ENTRY(VIRTIO_NET_F_STANDBY, \
+            "VIRTIO_NET_F_STANDBY: Device acting as standby for primary "
+            "device with same MAC addr. supported"),
+    FEATURE_ENTRY(VIRTIO_NET_F_SPEED_DUPLEX, \
+            "VIRTIO_NET_F_SPEED_DUPLEX: Device set linkspeed and duplex"),
+#ifndef VIRTIO_NET_NO_LEGACY
+    FEATURE_ENTRY(VIRTIO_NET_F_GSO, \
+            "VIRTIO_NET_F_GSO: Handling GSO-type packets supported"),
+#endif /* !VIRTIO_NET_NO_LEGACY */
+    FEATURE_ENTRY(VHOST_NET_F_VIRTIO_NET_HDR, \
+            "VHOST_NET_F_VIRTIO_NET_HDR: Virtio-net headers for RX and TX "
+            "packets supported"),
+    FEATURE_ENTRY(VHOST_F_LOG_ALL, \
+            "VHOST_F_LOG_ALL: Logging write descriptors supported"),
+    FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
+            "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
+            "negotiation supported"),
+    { -1, "" }
+};
+#endif
+
+/* virtio-scsi features mapping */
+#ifdef CONFIG_VIRTIO_SCSI
+static const qmp_virtio_feature_map_t virtio_scsi_feature_map[] = {
+    FEATURE_ENTRY(VIRTIO_SCSI_F_INOUT, \
+            "VIRTIO_SCSI_F_INOUT: Requests including read and writable data "
+            "buffers supported"),
+    FEATURE_ENTRY(VIRTIO_SCSI_F_HOTPLUG, \
+            "VIRTIO_SCSI_F_HOTPLUG: Reporting and handling hot-plug events "
+            "supported"),
+    FEATURE_ENTRY(VIRTIO_SCSI_F_CHANGE, \
+            "VIRTIO_SCSI_F_CHANGE: Reporting and handling LUN changes "
+            "supported"),
+    FEATURE_ENTRY(VIRTIO_SCSI_F_T10_PI, \
+            "VIRTIO_SCSI_F_T10_PI: T10 info included in request header"),
+    FEATURE_ENTRY(VHOST_F_LOG_ALL, \
+            "VHOST_F_LOG_ALL: Logging write descriptors supported"),
+    FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
+            "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
+            "negotiation supported"),
+    { -1, "" }
+};
+#endif
+
+/* virtio/vhost-user-fs features mapping */
+#ifdef CONFIG_VHOST_USER_FS
+static const qmp_virtio_feature_map_t virtio_fs_feature_map[] = {
+    FEATURE_ENTRY(VHOST_F_LOG_ALL, \
+            "VHOST_F_LOG_ALL: Logging write descriptors supported"),
+    FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
+            "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
+            "negotiation supported"),
+    { -1, "" }
+};
+#endif
+
+/* virtio/vhost-user-i2c features mapping */
+#ifdef CONFIG_VIRTIO_I2C_ADAPTER
+static const qmp_virtio_feature_map_t virtio_i2c_feature_map[] = {
+    FEATURE_ENTRY(VIRTIO_I2C_F_ZERO_LENGTH_REQUEST, \
+            "VIRTIO_I2C_F_ZERO_LEGNTH_REQUEST: Zero length requests supported"),
+    FEATURE_ENTRY(VHOST_F_LOG_ALL, \
+            "VHOST_F_LOG_ALL: Logging write descriptors supported"),
+    FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
+            "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
+            "negotiation supported"),
+    { -1, "" }
+};
+#endif
+
+/* virtio/vhost-vsock features mapping */
+#ifdef CONFIG_VHOST_VSOCK
+static const qmp_virtio_feature_map_t virtio_vsock_feature_map[] = {
+    FEATURE_ENTRY(VIRTIO_VSOCK_F_SEQPACKET, \
+            "VIRTIO_VSOCK_F_SEQPACKET: SOCK_SEQPACKET supported"),
+    FEATURE_ENTRY(VHOST_F_LOG_ALL, \
+            "VHOST_F_LOG_ALL: Logging write descriptors supported"),
+    FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
+            "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
+            "negotiation supported"),
+    { -1, "" }
+};
+#endif
+
+/* virtio-balloon features mapping */
+#ifdef CONFIG_VIRTIO_BALLOON
+static const qmp_virtio_feature_map_t virtio_balloon_feature_map[] = {
+    FEATURE_ENTRY(VIRTIO_BALLOON_F_MUST_TELL_HOST, \
+            "VIRTIO_BALLOON_F_MUST_TELL_HOST: Tell host before reclaiming "
+            "pages"),
+    FEATURE_ENTRY(VIRTIO_BALLOON_F_STATS_VQ, \
+            "VIRTIO_BALLOON_F_STATS_VQ: Guest memory stats VQ available"),
+    FEATURE_ENTRY(VIRTIO_BALLOON_F_DEFLATE_ON_OOM, \
+            "VIRTIO_BALLOON_F_DEFLATE_ON_OOM: Deflate balloon when guest OOM"),
+    FEATURE_ENTRY(VIRTIO_BALLOON_F_FREE_PAGE_HINT, \
+            "VIRTIO_BALLOON_F_FREE_PAGE_HINT: VQ reporting free pages enabled"),
+    FEATURE_ENTRY(VIRTIO_BALLOON_F_PAGE_POISON, \
+            "VIRTIO_BALLOON_F_PAGE_POISON: Guest page poisoning enabled"),
+    FEATURE_ENTRY(VIRTIO_BALLOON_F_REPORTING, \
+            "VIRTIO_BALLOON_F_REPORTING: Page reporting VQ enabled"),
+    { -1, "" }
+};
+#endif
+
+/* virtio-crypto features mapping */
+#ifdef CONFIG_VIRTIO_CRYPTO
+static const qmp_virtio_feature_map_t virtio_crypto_feature_map[] = {
+    FEATURE_ENTRY(VHOST_F_LOG_ALL, \
+            "VHOST_F_LOG_ALL: Logging write descriptors supported"),
+    { -1, "" }
+};
+#endif
+
+/* virtio-iommu features mapping */
+#ifdef CONFIG_VIRTIO_IOMMU
+static const qmp_virtio_feature_map_t virtio_iommu_feature_map[] = {
+    FEATURE_ENTRY(VIRTIO_IOMMU_F_INPUT_RANGE, \
+            "VIRTIO_IOMMU_F_INPUT_RANGE: Range of available virtual addrs. "
+            "available"),
+    FEATURE_ENTRY(VIRTIO_IOMMU_F_DOMAIN_RANGE, \
+            "VIRTIO_IOMMU_F_DOMAIN_RANGE: Number of supported domains "
+            "available"),
+    FEATURE_ENTRY(VIRTIO_IOMMU_F_MAP_UNMAP, \
+            "VIRTIO_IOMMU_F_MAP_UNMAP: Map and unmap requests available"),
+    FEATURE_ENTRY(VIRTIO_IOMMU_F_BYPASS, \
+            "VIRTIO_IOMMU_F_BYPASS: Endpoints not attached to domains are in "
+            "bypass mode"),
+    FEATURE_ENTRY(VIRTIO_IOMMU_F_PROBE, \
+            "VIRTIO_IOMMU_F_PROBE: Probe requests available"),
+    FEATURE_ENTRY(VIRTIO_IOMMU_F_MMIO, \
+            "VIRTIO_IOMMU_F_MMIO: VIRTIO_IOMMU_MAP_F_MMIO flag available"),
+    FEATURE_ENTRY(VIRTIO_IOMMU_F_BYPASS_CONFIG, \
+            "VIRTIO_IOMMU_F_BYPASS_CONFIG: Bypass field of IOMMU config "
+            "available"),
+    { -1, "" }
+};
+#endif
+
+/* virtio-mem features mapping */
+#ifdef CONFIG_VIRTIO_MEM
+static const qmp_virtio_feature_map_t virtio_mem_feature_map[] = {
+#ifndef CONFIG_ACPI
+    FEATURE_ENTRY(VIRTIO_MEM_F_ACPI_PXM, \
+            "VIRTIO_MEM_F_ACPI_PXM: node_id is an ACPI PXM and is valid"),
+#endif /* !CONFIG_ACPI */
+    FEATURE_ENTRY(VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE, \
+            "VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE: Unplugged memory cannot be "
+            "accessed"),
+    { -1, "" }
+};
+#endif
+
+/* virtio-rng features mapping */
+#ifdef CONFIG_VIRTIO_RNG
+static const qmp_virtio_feature_map_t virtio_rng_feature_map[] = {
+    FEATURE_ENTRY(VHOST_F_LOG_ALL, \
+            "VHOST_F_LOG_ALL: Logging write descriptors supported"),
+    FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
+            "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
+            "negotiation supported"),
+    { -1, "" }
+};
+#endif
+
+/* virtio/vhost-gpio features mapping */
+#ifdef CONFIG_VHOST_USER_GPIO
+static const qmp_virtio_feature_map_t virtio_gpio_feature_map[] = {
+    FEATURE_ENTRY(VIRTIO_GPIO_F_IRQ, \
+            "VIRTIO_GPIO_F_IRQ: Device supports interrupts on GPIO lines"),
+    FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
+            "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
+            "negotiation supported"),
+    { -1, "" }
+};
+#endif
+
+#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_desc); \
+            node->next = list;                           \
+            list = node;                                 \
+            bitmap ^= bit;                               \
+        }                                                \
+        list;                                            \
+    })
+
+static VhostDeviceProtocols *hmp_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 VirtioDeviceStatus *hmp_decode_status(uint8_t bitmap)
+{
+    VirtioDeviceStatus *status;
+    uint8_t bit;
+    int i;
+
+    status = g_new0(VirtioDeviceStatus, 1);
+    status->statuses = CONVERT_FEATURES(strList, virtio_config_status_map,
+                                        1, bitmap);
+    status->has_unknown_statuses = bitmap != 0;
+    if (status->has_unknown_statuses) {
+        status->unknown_statuses = bitmap;
+    }
+
+    return status;
+}
+
+static VirtioDeviceFeatures *hmp_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, virtio_transport_map, 0,
+                                            bitmap);
+
+    /* device features */
+    switch (device_id) {
+#ifdef CONFIG_VIRTIO_SERIAL
+    case VIRTIO_ID_CONSOLE:
+        features->dev_features =
+            CONVERT_FEATURES(strList, virtio_serial_feature_map, 0, bitmap);
+        break;
+#endif
+#ifdef CONFIG_VIRTIO_BLK
+    case VIRTIO_ID_BLOCK:
+        features->dev_features =
+            CONVERT_FEATURES(strList, virtio_blk_feature_map, 0, bitmap);
+        break;
+#endif
+#ifdef CONFIG_VIRTIO_GPU
+    case VIRTIO_ID_GPU:
+        features->dev_features =
+            CONVERT_FEATURES(strList, virtio_gpu_feature_map, 0, bitmap);
+        break;
+#endif
+#ifdef CONFIG_VIRTIO_NET
+    case VIRTIO_ID_NET:
+        features->dev_features =
+            CONVERT_FEATURES(strList, virtio_net_feature_map, 0, bitmap);
+        break;
+#endif
+#ifdef CONFIG_VIRTIO_SCSI
+    case VIRTIO_ID_SCSI:
+        features->dev_features =
+            CONVERT_FEATURES(strList, virtio_scsi_feature_map, 0, bitmap);
+        break;
+#endif
+#ifdef CONFIG_VIRTIO_BALLOON
+    case VIRTIO_ID_BALLOON:
+        features->dev_features =
+            CONVERT_FEATURES(strList, virtio_balloon_feature_map, 0, bitmap);
+        break;
+#endif
+#ifdef CONFIG_VIRTIO_IOMMU
+    case VIRTIO_ID_IOMMU:
+        features->dev_features =
+            CONVERT_FEATURES(strList, virtio_iommu_feature_map, 0, bitmap);
+        break;
+#endif
+#ifdef CONFIG_VIRTIO_INPUT
+    case VIRTIO_ID_INPUT:
+        features->dev_features =
+            CONVERT_FEATURES(strList, virtio_input_feature_map, 0, bitmap);
+        break;
+#endif
+#ifdef CONFIG_VHOST_USER_FS
+    case VIRTIO_ID_FS:
+        features->dev_features =
+            CONVERT_FEATURES(strList, virtio_fs_feature_map, 0, bitmap);
+        break;
+#endif
+#ifdef CONFIG_VHOST_VSOCK
+    case VIRTIO_ID_VSOCK:
+        features->dev_features =
+            CONVERT_FEATURES(strList, virtio_vsock_feature_map, 0, bitmap);
+        break;
+#endif
+#ifdef CONFIG_VIRTIO_CRYPTO
+    case VIRTIO_ID_CRYPTO:
+        features->dev_features =
+            CONVERT_FEATURES(strList, virtio_crypto_feature_map, 0, bitmap);
+        break;
+#endif
+#ifdef CONFIG_VIRTIO_MEM
+    case VIRTIO_ID_MEM:
+        features->dev_features =
+            CONVERT_FEATURES(strList, virtio_mem_feature_map, 0, bitmap);
+        break;
+#endif
+#ifdef CONFIG_VIRTIO_I2C_ADAPTER
+    case VIRTIO_ID_I2C_ADAPTER:
+        features->dev_features =
+            CONVERT_FEATURES(strList, virtio_i2c_feature_map, 0, bitmap);
+        break;
+#endif
+#ifdef CONFIG_VIRTIO_RNG
+    case VIRTIO_ID_RNG:
+        features->dev_features =
+            CONVERT_FEATURES(strList, virtio_rng_feature_map, 0, bitmap);
+        break;
+#endif
+#ifdef CONFIG_VHOST_USER_GPIO
+    case VIRTIO_ID_GPIO:
+        features->dev_features =
+            CONVERT_FEATURES(strList, virtio_gpio_feature_map, 0, bitmap);
+        break;
+#endif
+    /* No features */
+    case VIRTIO_ID_9P:
+    case VIRTIO_ID_PMEM:
+    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:
+        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;
+}
 
 static void hmp_virtio_dump_protocols(Monitor *mon,
                                       VhostDeviceProtocols *pcol)
@@ -147,16 +808,16 @@ void hmp_virtio_status(Monitor *mon, const QDict *qdict)
                    s->device_endian);
     monitor_printf(mon, "  status:\n");
     hmp_virtio_dump_status(mon,
-        qmp_decode_status(s->status));
+        hmp_decode_status(s->status));
     monitor_printf(mon, "  Guest features:\n");
     hmp_virtio_dump_features(mon,
-        qmp_decode_features(s->device_id, s->guest_features));
+        hmp_decode_features(s->device_id, s->guest_features));
     monitor_printf(mon, "  Host features:\n");
     hmp_virtio_dump_features(mon,
-        qmp_decode_features(s->device_id, s->host_features));
+        hmp_decode_features(s->device_id, s->host_features));
     monitor_printf(mon, "  Backend features:\n");
     hmp_virtio_dump_features(mon,
-        qmp_decode_features(s->device_id, s->backend_features));
+        hmp_decode_features(s->device_id, s->backend_features));
 
     if (s->vhost_dev) {
         monitor_printf(mon, "  VHost:\n");
@@ -178,16 +839,16 @@ void hmp_virtio_status(Monitor *mon, const QDict *qdict)
                        s->vhost_dev->log_size);
         monitor_printf(mon, "    Features:\n");
         hmp_virtio_dump_features(mon,
-            qmp_decode_features(s->device_id, s->vhost_dev->features));
+            hmp_decode_features(s->device_id, s->vhost_dev->features));
         monitor_printf(mon, "    Acked features:\n");
         hmp_virtio_dump_features(mon,
-            qmp_decode_features(s->device_id, s->vhost_dev->acked_features));
+            hmp_decode_features(s->device_id, s->vhost_dev->acked_features));
         monitor_printf(mon, "    Backend features:\n");
         hmp_virtio_dump_features(mon,
-            qmp_decode_features(s->device_id, s->vhost_dev->backend_features));
+            hmp_decode_features(s->device_id, s->vhost_dev->backend_features));
         monitor_printf(mon, "    Protocol features:\n");
         hmp_virtio_dump_protocols(mon,
-            qmp_decode_protocols(s->vhost_dev->protocol_features));
+            hmp_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 1660c17653..37a1296604 100644
--- a/hw/virtio/virtio-qmp.c
+++ b/hw/virtio/virtio-qmp.c
@@ -17,667 +17,6 @@
 #include "qapi/qapi-commands-qom.h"
 #include "qapi/qmp/qobject.h"
 #include "qapi/qmp/qjson.h"
-#include "hw/virtio/vhost-user.h"
-
-#include "standard-headers/linux/virtio_ids.h"
-#include "standard-headers/linux/vhost_types.h"
-#include "standard-headers/linux/virtio_blk.h"
-#include "standard-headers/linux/virtio_console.h"
-#include "standard-headers/linux/virtio_gpu.h"
-#include "standard-headers/linux/virtio_net.h"
-#include "standard-headers/linux/virtio_scsi.h"
-#include "standard-headers/linux/virtio_i2c.h"
-#include "standard-headers/linux/virtio_balloon.h"
-#include "standard-headers/linux/virtio_iommu.h"
-#include "standard-headers/linux/virtio_mem.h"
-#include "standard-headers/linux/virtio_vsock.h"
-#include "standard-headers/linux/virtio_gpio.h"
-
-#include CONFIG_DEVICES
-
-#define FEATURE_ENTRY(name, desc) (qmp_virtio_feature_map_t) \
-    { .virtio_bit = name, .feature_desc = desc }
-
-/* Virtio transport features mapping */
-static const qmp_virtio_feature_map_t virtio_transport_map[] = {
-    /* Virtio device transport features */
-#ifndef VIRTIO_CONFIG_NO_LEGACY
-    FEATURE_ENTRY(VIRTIO_F_NOTIFY_ON_EMPTY, \
-            "VIRTIO_F_NOTIFY_ON_EMPTY: Notify when device runs out of avail. "
-            "descs. on VQ"),
-    FEATURE_ENTRY(VIRTIO_F_ANY_LAYOUT, \
-            "VIRTIO_F_ANY_LAYOUT: Device accepts arbitrary desc. layouts"),
-#endif /* !VIRTIO_CONFIG_NO_LEGACY */
-    FEATURE_ENTRY(VIRTIO_F_VERSION_1, \
-            "VIRTIO_F_VERSION_1: Device compliant for v1 spec (legacy)"),
-    FEATURE_ENTRY(VIRTIO_F_IOMMU_PLATFORM, \
-            "VIRTIO_F_IOMMU_PLATFORM: Device can be used on IOMMU platform"),
-    FEATURE_ENTRY(VIRTIO_F_RING_PACKED, \
-            "VIRTIO_F_RING_PACKED: Device supports packed VQ layout"),
-    FEATURE_ENTRY(VIRTIO_F_IN_ORDER, \
-            "VIRTIO_F_IN_ORDER: Device uses buffers in same order as made "
-            "available by driver"),
-    FEATURE_ENTRY(VIRTIO_F_ORDER_PLATFORM, \
-            "VIRTIO_F_ORDER_PLATFORM: Memory accesses ordered by platform"),
-    FEATURE_ENTRY(VIRTIO_F_SR_IOV, \
-            "VIRTIO_F_SR_IOV: Device supports single root I/O virtualization"),
-    FEATURE_ENTRY(VIRTIO_F_RING_RESET, \
-            "VIRTIO_F_RING_RESET: Driver can reset a queue individually"),
-    /* Virtio ring transport features */
-    FEATURE_ENTRY(VIRTIO_RING_F_INDIRECT_DESC, \
-            "VIRTIO_RING_F_INDIRECT_DESC: Indirect descriptors supported"),
-    FEATURE_ENTRY(VIRTIO_RING_F_EVENT_IDX, \
-            "VIRTIO_RING_F_EVENT_IDX: Used & avail. event fields enabled"),
-    { -1, "" }
-};
-
-/* Vhost-user protocol features mapping */
-static const qmp_virtio_feature_map_t vhost_user_protocol_map[] = {
-    FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_MQ, \
-            "VHOST_USER_PROTOCOL_F_MQ: Multiqueue protocol supported"),
-    FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_LOG_SHMFD, \
-            "VHOST_USER_PROTOCOL_F_LOG_SHMFD: Shared log memory fd supported"),
-    FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_RARP, \
-            "VHOST_USER_PROTOCOL_F_RARP: Vhost-user back-end RARP broadcasting "
-            "supported"),
-    FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_REPLY_ACK, \
-            "VHOST_USER_PROTOCOL_F_REPLY_ACK: Requested operation status ack. "
-            "supported"),
-    FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_NET_MTU, \
-            "VHOST_USER_PROTOCOL_F_NET_MTU: Expose host MTU to guest supported"),
-    FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_BACKEND_REQ, \
-            "VHOST_USER_PROTOCOL_F_BACKEND_REQ: Socket fd for back-end initiated "
-            "requests supported"),
-    FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_CROSS_ENDIAN, \
-            "VHOST_USER_PROTOCOL_F_CROSS_ENDIAN: Endianness of VQs for legacy "
-            "devices supported"),
-    FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_CRYPTO_SESSION, \
-            "VHOST_USER_PROTOCOL_F_CRYPTO_SESSION: Session creation for crypto "
-            "operations supported"),
-    FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_PAGEFAULT, \
-            "VHOST_USER_PROTOCOL_F_PAGEFAULT: Request servicing on userfaultfd "
-            "for accessed pages supported"),
-    FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_CONFIG, \
-            "VHOST_USER_PROTOCOL_F_CONFIG: Vhost-user messaging for virtio "
-            "device configuration space supported"),
-    FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_BACKEND_SEND_FD, \
-            "VHOST_USER_PROTOCOL_F_BACKEND_SEND_FD: Backend fd communication "
-            "channel supported"),
-    FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_HOST_NOTIFIER, \
-            "VHOST_USER_PROTOCOL_F_HOST_NOTIFIER: Host notifiers for specified "
-            "VQs supported"),
-    FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD, \
-            "VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD: Shared inflight I/O buffers "
-            "supported"),
-    FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_RESET_DEVICE, \
-            "VHOST_USER_PROTOCOL_F_RESET_DEVICE: Disabling all rings and "
-            "resetting internal device state supported"),
-    FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS, \
-            "VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS: In-band messaging "
-            "supported"),
-    FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS, \
-            "VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS: Configuration for "
-            "memory slots supported"),
-    FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_STATUS, \
-            "VHOST_USER_PROTOCOL_F_STATUS: Querying and notifying back-end "
-            "device status supported"),
-    { -1, "" }
-};
-
-/* virtio device configuration statuses */
-static const qmp_virtio_feature_map_t virtio_config_status_map[] = {
-    FEATURE_ENTRY(VIRTIO_CONFIG_S_DRIVER_OK, \
-            "VIRTIO_CONFIG_S_DRIVER_OK: Driver setup and ready"),
-    FEATURE_ENTRY(VIRTIO_CONFIG_S_FEATURES_OK, \
-            "VIRTIO_CONFIG_S_FEATURES_OK: Feature negotiation complete"),
-    FEATURE_ENTRY(VIRTIO_CONFIG_S_DRIVER, \
-            "VIRTIO_CONFIG_S_DRIVER: Guest OS compatible with device"),
-    FEATURE_ENTRY(VIRTIO_CONFIG_S_NEEDS_RESET, \
-            "VIRTIO_CONFIG_S_NEEDS_RESET: Irrecoverable error, device needs "
-            "reset"),
-    FEATURE_ENTRY(VIRTIO_CONFIG_S_FAILED, \
-            "VIRTIO_CONFIG_S_FAILED: Error in guest, device failed"),
-    FEATURE_ENTRY(VIRTIO_CONFIG_S_ACKNOWLEDGE, \
-            "VIRTIO_CONFIG_S_ACKNOWLEDGE: Valid virtio device found"),
-    { -1, "" }
-};
-
-/* virtio-blk features mapping */
-#ifdef CONFIG_VIRTIO_BLK
-static const qmp_virtio_feature_map_t virtio_blk_feature_map[] = {
-    FEATURE_ENTRY(VIRTIO_BLK_F_SIZE_MAX, \
-            "VIRTIO_BLK_F_SIZE_MAX: Max segment size is size_max"),
-    FEATURE_ENTRY(VIRTIO_BLK_F_SEG_MAX, \
-            "VIRTIO_BLK_F_SEG_MAX: Max segments in a request is seg_max"),
-    FEATURE_ENTRY(VIRTIO_BLK_F_GEOMETRY, \
-            "VIRTIO_BLK_F_GEOMETRY: Legacy geometry available"),
-    FEATURE_ENTRY(VIRTIO_BLK_F_RO, \
-            "VIRTIO_BLK_F_RO: Device is read-only"),
-    FEATURE_ENTRY(VIRTIO_BLK_F_BLK_SIZE, \
-            "VIRTIO_BLK_F_BLK_SIZE: Block size of disk available"),
-    FEATURE_ENTRY(VIRTIO_BLK_F_TOPOLOGY, \
-            "VIRTIO_BLK_F_TOPOLOGY: Topology information available"),
-    FEATURE_ENTRY(VIRTIO_BLK_F_MQ, \
-            "VIRTIO_BLK_F_MQ: Multiqueue supported"),
-    FEATURE_ENTRY(VIRTIO_BLK_F_DISCARD, \
-            "VIRTIO_BLK_F_DISCARD: Discard command supported"),
-    FEATURE_ENTRY(VIRTIO_BLK_F_WRITE_ZEROES, \
-            "VIRTIO_BLK_F_WRITE_ZEROES: Write zeroes command supported"),
-    FEATURE_ENTRY(VIRTIO_BLK_F_SECURE_ERASE, \
-            "VIRTIO_BLK_F_SECURE_ERASE: Secure erase supported"),
-    FEATURE_ENTRY(VIRTIO_BLK_F_ZONED, \
-            "VIRTIO_BLK_F_ZONED: Zoned block devices"),
-#ifndef VIRTIO_BLK_NO_LEGACY
-    FEATURE_ENTRY(VIRTIO_BLK_F_BARRIER, \
-            "VIRTIO_BLK_F_BARRIER: Request barriers supported"),
-    FEATURE_ENTRY(VIRTIO_BLK_F_SCSI, \
-            "VIRTIO_BLK_F_SCSI: SCSI packet commands supported"),
-    FEATURE_ENTRY(VIRTIO_BLK_F_FLUSH, \
-            "VIRTIO_BLK_F_FLUSH: Flush command supported"),
-    FEATURE_ENTRY(VIRTIO_BLK_F_CONFIG_WCE, \
-            "VIRTIO_BLK_F_CONFIG_WCE: Cache writeback and writethrough modes "
-            "supported"),
-#endif /* !VIRTIO_BLK_NO_LEGACY */
-    FEATURE_ENTRY(VHOST_F_LOG_ALL, \
-            "VHOST_F_LOG_ALL: Logging write descriptors supported"),
-    FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
-            "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
-            "negotiation supported"),
-    { -1, "" }
-};
-#endif
-
-/* virtio-serial features mapping */
-#ifdef CONFIG_VIRTIO_SERIAL
-static const qmp_virtio_feature_map_t virtio_serial_feature_map[] = {
-    FEATURE_ENTRY(VIRTIO_CONSOLE_F_SIZE, \
-            "VIRTIO_CONSOLE_F_SIZE: Host providing console size"),
-    FEATURE_ENTRY(VIRTIO_CONSOLE_F_MULTIPORT, \
-            "VIRTIO_CONSOLE_F_MULTIPORT: Multiple ports for device supported"),
-    FEATURE_ENTRY(VIRTIO_CONSOLE_F_EMERG_WRITE, \
-            "VIRTIO_CONSOLE_F_EMERG_WRITE: Emergency write supported"),
-    { -1, "" }
-};
-#endif
-
-/* virtio-gpu features mapping */
-#ifdef CONFIG_VIRTIO_GPU
-static const qmp_virtio_feature_map_t virtio_gpu_feature_map[] = {
-    FEATURE_ENTRY(VIRTIO_GPU_F_VIRGL, \
-            "VIRTIO_GPU_F_VIRGL: Virgl 3D mode supported"),
-    FEATURE_ENTRY(VIRTIO_GPU_F_EDID, \
-            "VIRTIO_GPU_F_EDID: EDID metadata supported"),
-    FEATURE_ENTRY(VIRTIO_GPU_F_RESOURCE_UUID, \
-            "VIRTIO_GPU_F_RESOURCE_UUID: Resource UUID assigning supported"),
-    FEATURE_ENTRY(VIRTIO_GPU_F_RESOURCE_BLOB, \
-            "VIRTIO_GPU_F_RESOURCE_BLOB: Size-based blob resources supported"),
-    FEATURE_ENTRY(VIRTIO_GPU_F_CONTEXT_INIT, \
-            "VIRTIO_GPU_F_CONTEXT_INIT: Context types and synchronization "
-            "timelines supported"),
-    FEATURE_ENTRY(VHOST_F_LOG_ALL, \
-            "VHOST_F_LOG_ALL: Logging write descriptors supported"),
-    FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
-            "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
-            "negotiation supported"),
-    { -1, "" }
-};
-#endif
-
-/* virtio-input features mapping */
-#ifdef CONFIG_VIRTIO_INPUT
-static const qmp_virtio_feature_map_t virtio_input_feature_map[] = {
-    FEATURE_ENTRY(VHOST_F_LOG_ALL, \
-            "VHOST_F_LOG_ALL: Logging write descriptors supported"),
-    FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
-            "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
-            "negotiation supported"),
-    { -1, "" }
-};
-#endif
-
-/* virtio-net features mapping */
-#ifdef CONFIG_VIRTIO_NET
-static const qmp_virtio_feature_map_t virtio_net_feature_map[] = {
-    FEATURE_ENTRY(VIRTIO_NET_F_CSUM, \
-            "VIRTIO_NET_F_CSUM: Device handling packets with partial checksum "
-            "supported"),
-    FEATURE_ENTRY(VIRTIO_NET_F_GUEST_CSUM, \
-            "VIRTIO_NET_F_GUEST_CSUM: Driver handling packets with partial "
-            "checksum supported"),
-    FEATURE_ENTRY(VIRTIO_NET_F_CTRL_GUEST_OFFLOADS, \
-            "VIRTIO_NET_F_CTRL_GUEST_OFFLOADS: Control channel offloading "
-            "reconfig. supported"),
-    FEATURE_ENTRY(VIRTIO_NET_F_MTU, \
-            "VIRTIO_NET_F_MTU: Device max MTU reporting supported"),
-    FEATURE_ENTRY(VIRTIO_NET_F_MAC, \
-            "VIRTIO_NET_F_MAC: Device has given MAC address"),
-    FEATURE_ENTRY(VIRTIO_NET_F_GUEST_TSO4, \
-            "VIRTIO_NET_F_GUEST_TSO4: Driver can receive TSOv4"),
-    FEATURE_ENTRY(VIRTIO_NET_F_GUEST_TSO6, \
-            "VIRTIO_NET_F_GUEST_TSO6: Driver can receive TSOv6"),
-    FEATURE_ENTRY(VIRTIO_NET_F_GUEST_ECN, \
-            "VIRTIO_NET_F_GUEST_ECN: Driver can receive TSO with ECN"),
-    FEATURE_ENTRY(VIRTIO_NET_F_GUEST_UFO, \
-            "VIRTIO_NET_F_GUEST_UFO: Driver can receive UFO"),
-    FEATURE_ENTRY(VIRTIO_NET_F_HOST_TSO4, \
-            "VIRTIO_NET_F_HOST_TSO4: Device can receive TSOv4"),
-    FEATURE_ENTRY(VIRTIO_NET_F_HOST_TSO6, \
-            "VIRTIO_NET_F_HOST_TSO6: Device can receive TSOv6"),
-    FEATURE_ENTRY(VIRTIO_NET_F_HOST_ECN, \
-            "VIRTIO_NET_F_HOST_ECN: Device can receive TSO with ECN"),
-    FEATURE_ENTRY(VIRTIO_NET_F_HOST_UFO, \
-            "VIRTIO_NET_F_HOST_UFO: Device can receive UFO"),
-    FEATURE_ENTRY(VIRTIO_NET_F_MRG_RXBUF, \
-            "VIRTIO_NET_F_MRG_RXBUF: Driver can merge receive buffers"),
-    FEATURE_ENTRY(VIRTIO_NET_F_STATUS, \
-            "VIRTIO_NET_F_STATUS: Configuration status field available"),
-    FEATURE_ENTRY(VIRTIO_NET_F_CTRL_VQ, \
-            "VIRTIO_NET_F_CTRL_VQ: Control channel available"),
-    FEATURE_ENTRY(VIRTIO_NET_F_CTRL_RX, \
-            "VIRTIO_NET_F_CTRL_RX: Control channel RX mode supported"),
-    FEATURE_ENTRY(VIRTIO_NET_F_CTRL_VLAN, \
-            "VIRTIO_NET_F_CTRL_VLAN: Control channel VLAN filtering supported"),
-    FEATURE_ENTRY(VIRTIO_NET_F_CTRL_RX_EXTRA, \
-            "VIRTIO_NET_F_CTRL_RX_EXTRA: Extra RX mode control supported"),
-    FEATURE_ENTRY(VIRTIO_NET_F_GUEST_ANNOUNCE, \
-            "VIRTIO_NET_F_GUEST_ANNOUNCE: Driver sending gratuitous packets "
-            "supported"),
-    FEATURE_ENTRY(VIRTIO_NET_F_MQ, \
-            "VIRTIO_NET_F_MQ: Multiqueue with automatic receive steering "
-            "supported"),
-    FEATURE_ENTRY(VIRTIO_NET_F_CTRL_MAC_ADDR, \
-            "VIRTIO_NET_F_CTRL_MAC_ADDR: MAC address set through control "
-            "channel"),
-    FEATURE_ENTRY(VIRTIO_NET_F_NOTF_COAL, \
-            "VIRTIO_NET_F_NOTF_COAL: Device supports coalescing notifications"),
-    FEATURE_ENTRY(VIRTIO_NET_F_GUEST_USO4, \
-            "VIRTIO_NET_F_GUEST_USO4: Driver can receive USOv4"),
-    FEATURE_ENTRY(VIRTIO_NET_F_GUEST_USO6, \
-            "VIRTIO_NET_F_GUEST_USO4: Driver can receive USOv6"),
-    FEATURE_ENTRY(VIRTIO_NET_F_HOST_USO, \
-            "VIRTIO_NET_F_HOST_USO: Device can receive USO"),
-    FEATURE_ENTRY(VIRTIO_NET_F_HASH_REPORT, \
-            "VIRTIO_NET_F_HASH_REPORT: Hash reporting supported"),
-    FEATURE_ENTRY(VIRTIO_NET_F_RSS, \
-            "VIRTIO_NET_F_RSS: RSS RX steering supported"),
-    FEATURE_ENTRY(VIRTIO_NET_F_RSC_EXT, \
-            "VIRTIO_NET_F_RSC_EXT: Extended coalescing info supported"),
-    FEATURE_ENTRY(VIRTIO_NET_F_STANDBY, \
-            "VIRTIO_NET_F_STANDBY: Device acting as standby for primary "
-            "device with same MAC addr. supported"),
-    FEATURE_ENTRY(VIRTIO_NET_F_SPEED_DUPLEX, \
-            "VIRTIO_NET_F_SPEED_DUPLEX: Device set linkspeed and duplex"),
-#ifndef VIRTIO_NET_NO_LEGACY
-    FEATURE_ENTRY(VIRTIO_NET_F_GSO, \
-            "VIRTIO_NET_F_GSO: Handling GSO-type packets supported"),
-#endif /* !VIRTIO_NET_NO_LEGACY */
-    FEATURE_ENTRY(VHOST_NET_F_VIRTIO_NET_HDR, \
-            "VHOST_NET_F_VIRTIO_NET_HDR: Virtio-net headers for RX and TX "
-            "packets supported"),
-    FEATURE_ENTRY(VHOST_F_LOG_ALL, \
-            "VHOST_F_LOG_ALL: Logging write descriptors supported"),
-    FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
-            "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
-            "negotiation supported"),
-    { -1, "" }
-};
-#endif
-
-/* virtio-scsi features mapping */
-#ifdef CONFIG_VIRTIO_SCSI
-static const qmp_virtio_feature_map_t virtio_scsi_feature_map[] = {
-    FEATURE_ENTRY(VIRTIO_SCSI_F_INOUT, \
-            "VIRTIO_SCSI_F_INOUT: Requests including read and writable data "
-            "buffers supported"),
-    FEATURE_ENTRY(VIRTIO_SCSI_F_HOTPLUG, \
-            "VIRTIO_SCSI_F_HOTPLUG: Reporting and handling hot-plug events "
-            "supported"),
-    FEATURE_ENTRY(VIRTIO_SCSI_F_CHANGE, \
-            "VIRTIO_SCSI_F_CHANGE: Reporting and handling LUN changes "
-            "supported"),
-    FEATURE_ENTRY(VIRTIO_SCSI_F_T10_PI, \
-            "VIRTIO_SCSI_F_T10_PI: T10 info included in request header"),
-    FEATURE_ENTRY(VHOST_F_LOG_ALL, \
-            "VHOST_F_LOG_ALL: Logging write descriptors supported"),
-    FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
-            "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
-            "negotiation supported"),
-    { -1, "" }
-};
-#endif
-
-/* virtio/vhost-user-fs features mapping */
-#ifdef CONFIG_VHOST_USER_FS
-static const qmp_virtio_feature_map_t virtio_fs_feature_map[] = {
-    FEATURE_ENTRY(VHOST_F_LOG_ALL, \
-            "VHOST_F_LOG_ALL: Logging write descriptors supported"),
-    FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
-            "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
-            "negotiation supported"),
-    { -1, "" }
-};
-#endif
-
-/* virtio/vhost-user-i2c features mapping */
-#ifdef CONFIG_VIRTIO_I2C_ADAPTER
-static const qmp_virtio_feature_map_t virtio_i2c_feature_map[] = {
-    FEATURE_ENTRY(VIRTIO_I2C_F_ZERO_LENGTH_REQUEST, \
-            "VIRTIO_I2C_F_ZERO_LEGNTH_REQUEST: Zero length requests supported"),
-    FEATURE_ENTRY(VHOST_F_LOG_ALL, \
-            "VHOST_F_LOG_ALL: Logging write descriptors supported"),
-    FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
-            "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
-            "negotiation supported"),
-    { -1, "" }
-};
-#endif
-
-/* virtio/vhost-vsock features mapping */
-#ifdef CONFIG_VHOST_VSOCK
-static const qmp_virtio_feature_map_t virtio_vsock_feature_map[] = {
-    FEATURE_ENTRY(VIRTIO_VSOCK_F_SEQPACKET, \
-            "VIRTIO_VSOCK_F_SEQPACKET: SOCK_SEQPACKET supported"),
-    FEATURE_ENTRY(VHOST_F_LOG_ALL, \
-            "VHOST_F_LOG_ALL: Logging write descriptors supported"),
-    FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
-            "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
-            "negotiation supported"),
-    { -1, "" }
-};
-#endif
-
-/* virtio-balloon features mapping */
-#ifdef CONFIG_VIRTIO_BALLOON
-static const qmp_virtio_feature_map_t virtio_balloon_feature_map[] = {
-    FEATURE_ENTRY(VIRTIO_BALLOON_F_MUST_TELL_HOST, \
-            "VIRTIO_BALLOON_F_MUST_TELL_HOST: Tell host before reclaiming "
-            "pages"),
-    FEATURE_ENTRY(VIRTIO_BALLOON_F_STATS_VQ, \
-            "VIRTIO_BALLOON_F_STATS_VQ: Guest memory stats VQ available"),
-    FEATURE_ENTRY(VIRTIO_BALLOON_F_DEFLATE_ON_OOM, \
-            "VIRTIO_BALLOON_F_DEFLATE_ON_OOM: Deflate balloon when guest OOM"),
-    FEATURE_ENTRY(VIRTIO_BALLOON_F_FREE_PAGE_HINT, \
-            "VIRTIO_BALLOON_F_FREE_PAGE_HINT: VQ reporting free pages enabled"),
-    FEATURE_ENTRY(VIRTIO_BALLOON_F_PAGE_POISON, \
-            "VIRTIO_BALLOON_F_PAGE_POISON: Guest page poisoning enabled"),
-    FEATURE_ENTRY(VIRTIO_BALLOON_F_REPORTING, \
-            "VIRTIO_BALLOON_F_REPORTING: Page reporting VQ enabled"),
-    { -1, "" }
-};
-#endif
-
-/* virtio-crypto features mapping */
-#ifdef CONFIG_VIRTIO_CRYPTO
-static const qmp_virtio_feature_map_t virtio_crypto_feature_map[] = {
-    FEATURE_ENTRY(VHOST_F_LOG_ALL, \
-            "VHOST_F_LOG_ALL: Logging write descriptors supported"),
-    { -1, "" }
-};
-#endif
-
-/* virtio-iommu features mapping */
-#ifdef CONFIG_VIRTIO_IOMMU
-static const qmp_virtio_feature_map_t virtio_iommu_feature_map[] = {
-    FEATURE_ENTRY(VIRTIO_IOMMU_F_INPUT_RANGE, \
-            "VIRTIO_IOMMU_F_INPUT_RANGE: Range of available virtual addrs. "
-            "available"),
-    FEATURE_ENTRY(VIRTIO_IOMMU_F_DOMAIN_RANGE, \
-            "VIRTIO_IOMMU_F_DOMAIN_RANGE: Number of supported domains "
-            "available"),
-    FEATURE_ENTRY(VIRTIO_IOMMU_F_MAP_UNMAP, \
-            "VIRTIO_IOMMU_F_MAP_UNMAP: Map and unmap requests available"),
-    FEATURE_ENTRY(VIRTIO_IOMMU_F_BYPASS, \
-            "VIRTIO_IOMMU_F_BYPASS: Endpoints not attached to domains are in "
-            "bypass mode"),
-    FEATURE_ENTRY(VIRTIO_IOMMU_F_PROBE, \
-            "VIRTIO_IOMMU_F_PROBE: Probe requests available"),
-    FEATURE_ENTRY(VIRTIO_IOMMU_F_MMIO, \
-            "VIRTIO_IOMMU_F_MMIO: VIRTIO_IOMMU_MAP_F_MMIO flag available"),
-    FEATURE_ENTRY(VIRTIO_IOMMU_F_BYPASS_CONFIG, \
-            "VIRTIO_IOMMU_F_BYPASS_CONFIG: Bypass field of IOMMU config "
-            "available"),
-    { -1, "" }
-};
-#endif
-
-/* virtio-mem features mapping */
-#ifdef CONFIG_VIRTIO_MEM
-static const qmp_virtio_feature_map_t virtio_mem_feature_map[] = {
-#ifndef CONFIG_ACPI
-    FEATURE_ENTRY(VIRTIO_MEM_F_ACPI_PXM, \
-            "VIRTIO_MEM_F_ACPI_PXM: node_id is an ACPI PXM and is valid"),
-#endif /* !CONFIG_ACPI */
-    FEATURE_ENTRY(VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE, \
-            "VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE: Unplugged memory cannot be "
-            "accessed"),
-    { -1, "" }
-};
-#endif
-
-/* virtio-rng features mapping */
-#ifdef CONFIG_VIRTIO_RNG
-static const qmp_virtio_feature_map_t virtio_rng_feature_map[] = {
-    FEATURE_ENTRY(VHOST_F_LOG_ALL, \
-            "VHOST_F_LOG_ALL: Logging write descriptors supported"),
-    FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
-            "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
-            "negotiation supported"),
-    { -1, "" }
-};
-#endif
-
-/* virtio/vhost-gpio features mapping */
-#ifdef CONFIG_VHOST_USER_GPIO
-static const qmp_virtio_feature_map_t virtio_gpio_feature_map[] = {
-    FEATURE_ENTRY(VIRTIO_GPIO_F_IRQ, \
-            "VIRTIO_GPIO_F_IRQ: Device supports interrupts on GPIO lines"),
-    FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
-            "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
-            "negotiation supported"),
-    { -1, "" }
-};
-#endif
-
-#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_desc); \
-            node->next = list;                           \
-            list = node;                                 \
-            bitmap ^= bit;                               \
-        }                                                \
-        list;                                            \
-    })
-
-VirtioDeviceStatus *qmp_decode_status(uint8_t bitmap)
-{
-    VirtioDeviceStatus *status;
-    uint8_t bit;
-    int i;
-
-    status = g_new0(VirtioDeviceStatus, 1);
-    status->statuses = CONVERT_FEATURES(strList, virtio_config_status_map,
-                                        1, bitmap);
-    status->has_unknown_statuses = bitmap != 0;
-    if (status->has_unknown_statuses) {
-        status->unknown_statuses = bitmap;
-    }
-
-    return status;
-}
-
-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;
-}
-
-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, virtio_transport_map, 0,
-                                            bitmap);
-
-    /* device features */
-    switch (device_id) {
-#ifdef CONFIG_VIRTIO_SERIAL
-    case VIRTIO_ID_CONSOLE:
-        features->dev_features =
-            CONVERT_FEATURES(strList, virtio_serial_feature_map, 0, bitmap);
-        break;
-#endif
-#ifdef CONFIG_VIRTIO_BLK
-    case VIRTIO_ID_BLOCK:
-        features->dev_features =
-            CONVERT_FEATURES(strList, virtio_blk_feature_map, 0, bitmap);
-        break;
-#endif
-#ifdef CONFIG_VIRTIO_GPU
-    case VIRTIO_ID_GPU:
-        features->dev_features =
-            CONVERT_FEATURES(strList, virtio_gpu_feature_map, 0, bitmap);
-        break;
-#endif
-#ifdef CONFIG_VIRTIO_NET
-    case VIRTIO_ID_NET:
-        features->dev_features =
-            CONVERT_FEATURES(strList, virtio_net_feature_map, 0, bitmap);
-        break;
-#endif
-#ifdef CONFIG_VIRTIO_SCSI
-    case VIRTIO_ID_SCSI:
-        features->dev_features =
-            CONVERT_FEATURES(strList, virtio_scsi_feature_map, 0, bitmap);
-        break;
-#endif
-#ifdef CONFIG_VIRTIO_BALLOON
-    case VIRTIO_ID_BALLOON:
-        features->dev_features =
-            CONVERT_FEATURES(strList, virtio_balloon_feature_map, 0, bitmap);
-        break;
-#endif
-#ifdef CONFIG_VIRTIO_IOMMU
-    case VIRTIO_ID_IOMMU:
-        features->dev_features =
-            CONVERT_FEATURES(strList, virtio_iommu_feature_map, 0, bitmap);
-        break;
-#endif
-#ifdef CONFIG_VIRTIO_INPUT
-    case VIRTIO_ID_INPUT:
-        features->dev_features =
-            CONVERT_FEATURES(strList, virtio_input_feature_map, 0, bitmap);
-        break;
-#endif
-#ifdef CONFIG_VHOST_USER_FS
-    case VIRTIO_ID_FS:
-        features->dev_features =
-            CONVERT_FEATURES(strList, virtio_fs_feature_map, 0, bitmap);
-        break;
-#endif
-#ifdef CONFIG_VHOST_VSOCK
-    case VIRTIO_ID_VSOCK:
-        features->dev_features =
-            CONVERT_FEATURES(strList, virtio_vsock_feature_map, 0, bitmap);
-        break;
-#endif
-#ifdef CONFIG_VIRTIO_CRYPTO
-    case VIRTIO_ID_CRYPTO:
-        features->dev_features =
-            CONVERT_FEATURES(strList, virtio_crypto_feature_map, 0, bitmap);
-        break;
-#endif
-#ifdef CONFIG_VIRTIO_MEM
-    case VIRTIO_ID_MEM:
-        features->dev_features =
-            CONVERT_FEATURES(strList, virtio_mem_feature_map, 0, bitmap);
-        break;
-#endif
-#ifdef CONFIG_VIRTIO_I2C_ADAPTER
-    case VIRTIO_ID_I2C_ADAPTER:
-        features->dev_features =
-            CONVERT_FEATURES(strList, virtio_i2c_feature_map, 0, bitmap);
-        break;
-#endif
-#ifdef CONFIG_VIRTIO_RNG
-    case VIRTIO_ID_RNG:
-        features->dev_features =
-            CONVERT_FEATURES(strList, virtio_rng_feature_map, 0, bitmap);
-        break;
-#endif
-#ifdef CONFIG_VHOST_USER_GPIO
-    case VIRTIO_ID_GPIO:
-        features->dev_features =
-            CONVERT_FEATURES(strList, virtio_gpio_feature_map, 0, bitmap);
-        break;
-#endif
-    /* No features */
-    case VIRTIO_ID_9P:
-    case VIRTIO_ID_PMEM:
-    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:
-        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;
-}
 
 static int query_dev_child(Object *child, void *opaque)
 {
diff --git a/hw/virtio/virtio-qmp.h b/hw/virtio/virtio-qmp.h
index 245a446a56..7aa1bb3c08 100644
--- a/hw/virtio/virtio-qmp.h
+++ b/hw/virtio/virtio-qmp.h
@@ -16,8 +16,5 @@
 #include "hw/virtio/vhost.h"
 
 VirtIODevice *qmp_find_virtio_device(const char *path);
-VirtioDeviceStatus *qmp_decode_status(uint8_t bitmap);
-VhostDeviceProtocols *qmp_decode_protocols(uint64_t bitmap);
-VirtioDeviceFeatures *qmp_decode_features(uint16_t device_id, uint64_t bitmap);
 
 #endif
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v3 3/3] qapi: Define VhostDeviceProtocols and VirtioDeviceFeatures as plain C types
  2024-02-02 14:32 [PATCH v3 0/3] Adjust the output of x-query-virtio-status Hyman Huang
  2024-02-02 14:32 ` [PATCH v3 1/3] qmp: Switch x-query-virtio-status back to numeric encoding Hyman Huang
  2024-02-02 14:32 ` [PATCH v3 2/3] virtio: Declare the decoding functions to static Hyman Huang
@ 2024-02-02 14:32 ` Hyman Huang
  2024-02-19 15:33   ` Markus Armbruster
  2024-02-13 10:25 ` [PATCH v3 0/3] Adjust the output of x-query-virtio-status Michael S. Tsirkin
  3 siblings, 1 reply; 14+ messages in thread
From: Hyman Huang @ 2024-02-02 14:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: Markus Armbruster, Michael S . Tsirkin, Eric Blake, yong.huang

VhostDeviceProtocols and VirtioDeviceFeatures are only used in
virtio-hmp-cmds.c.  So define them as plain C types there, and drop
them from the QAPI schema.

Signed-off-by: Hyman Huang <yong.huang@smartx.com>
---
 hw/virtio/virtio-hmp-cmds.c | 16 +++++++++++++++
 qapi/virtio.json            | 39 -------------------------------------
 2 files changed, 16 insertions(+), 39 deletions(-)

diff --git a/hw/virtio/virtio-hmp-cmds.c b/hw/virtio/virtio-hmp-cmds.c
index f95bad0069..045b472228 100644
--- a/hw/virtio/virtio-hmp-cmds.c
+++ b/hw/virtio/virtio-hmp-cmds.c
@@ -29,6 +29,22 @@
 
 #include CONFIG_DEVICES
 
+typedef struct VhostDeviceProtocols VhostDeviceProtocols;
+struct VhostDeviceProtocols {
+    strList *protocols;
+    bool has_unknown_protocols;
+    uint64_t unknown_protocols;
+};
+
+typedef struct VirtioDeviceFeatures VirtioDeviceFeatures;
+struct VirtioDeviceFeatures {
+    strList *transports;
+    bool has_dev_features;
+    strList *dev_features;
+    bool has_unknown_dev_features;
+    uint64_t unknown_dev_features;
+};
+
 #define FEATURE_ENTRY(name, desc) (qmp_virtio_feature_map_t) \
     { .virtio_bit = name, .feature_desc = desc }
 
diff --git a/qapi/virtio.json b/qapi/virtio.json
index 26516fb29c..42dbc87f2f 100644
--- a/qapi/virtio.json
+++ b/qapi/virtio.json
@@ -300,45 +300,6 @@
   '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.2
-##
-{ '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.2
-##
-{ 'struct': 'VirtioDeviceFeatures',
-  'data': { 'transports': [ 'str' ],
-            '*dev-features': [ 'str' ],
-            '*unknown-dev-features': 'uint64' } }
-
 ##
 # @VirtQueueStatus:
 #
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH v3 0/3] Adjust the output of x-query-virtio-status
  2024-02-02 14:32 [PATCH v3 0/3] Adjust the output of x-query-virtio-status Hyman Huang
                   ` (2 preceding siblings ...)
  2024-02-02 14:32 ` [PATCH v3 3/3] qapi: Define VhostDeviceProtocols and VirtioDeviceFeatures as plain C types Hyman Huang
@ 2024-02-13 10:25 ` Michael S. Tsirkin
  2024-02-13 13:30   ` Markus Armbruster
  3 siblings, 1 reply; 14+ messages in thread
From: Michael S. Tsirkin @ 2024-02-13 10:25 UTC (permalink / raw)
  To: Hyman Huang; +Cc: qemu-devel, Markus Armbruster, Eric Blake

On Fri, Feb 02, 2024 at 10:32:14PM +0800, Hyman Huang wrote:
> Sorry for the late post of version 3. The modifications are as follows:
> 
> v3:
> - Rebase on master
> - Use the refined commit message furnished by Markus for [PATCH v2 1/2] 
> - Drop the [PATCH v2 2/2]
> - Add [PATCH v3 2/3] to declare the decoding functions to static
> - Add [PATCH v3 3/3] to Define VhostDeviceProtocols and
>   VirtioDeviceFeatures as plain C types
> 
> Since Markus inspired all of the alterations above, we would like to
> thank him for his contribution to this series.
> 
> Please review,
> Yong

Markus do you think you can take a look at this?

> v2:
> - Changing the hmp_virtio_dump_xxx function signatures to implement
>   the bitmap decoding, suggested by Philippe. 
> 
> This patchset is derived from the series:
> https://lore.kernel.org/qemu-devel/cover.1699793550.git.yong.huang@smartx.com/
> Please go to the link to see more background information.
> 
> The following points are what we have done in the patchset:
> 1. Take the policy of adding human-readable output just in HMP.
> 2. For the HMP output, display the human-readable information and
>    drop the unknown bits in practice.
> 3. For the QMP output, remove the descriptive strings and only
>    display bits encoded as numbers.
> 
> Hyman Huang (3):
>   qmp: Switch x-query-virtio-status back to numeric encoding
>   virtio: Declare the decoding functions to static
>   qapi: Define VhostDeviceProtocols and VirtioDeviceFeatures as plain C
>     types
> 
>  hw/virtio/meson.build       |   3 +-
>  hw/virtio/virtio-hmp-cmds.c | 702 +++++++++++++++++++++++++++++++++++-
>  hw/virtio/virtio-qmp.c      | 684 +----------------------------------
>  hw/virtio/virtio-qmp.h      |   3 -
>  qapi/virtio.json            | 231 +-----------
>  5 files changed, 723 insertions(+), 900 deletions(-)
> 
> -- 
> 2.31.1



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v3 1/3] qmp: Switch x-query-virtio-status back to numeric encoding
  2024-02-02 14:32 ` [PATCH v3 1/3] qmp: Switch x-query-virtio-status back to numeric encoding Hyman Huang
@ 2024-02-13 10:26   ` Michael S. Tsirkin
  2024-02-15 12:49     ` Yong Huang
  2024-02-19 15:18   ` Markus Armbruster
  1 sibling, 1 reply; 14+ messages in thread
From: Michael S. Tsirkin @ 2024-02-13 10:26 UTC (permalink / raw)
  To: Hyman Huang; +Cc: qemu-devel, Markus Armbruster, Eric Blake

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?
E.g. I mostly use QMP even when I read it myself.

> 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.huang@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



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v3 0/3] Adjust the output of x-query-virtio-status
  2024-02-13 10:25 ` [PATCH v3 0/3] Adjust the output of x-query-virtio-status Michael S. Tsirkin
@ 2024-02-13 13:30   ` Markus Armbruster
  0 siblings, 0 replies; 14+ messages in thread
From: Markus Armbruster @ 2024-02-13 13:30 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: Hyman Huang, qemu-devel, Eric Blake

"Michael S. Tsirkin" <mst@redhat.com> writes:

> On Fri, Feb 02, 2024 at 10:32:14PM +0800, Hyman Huang wrote:
>> Sorry for the late post of version 3. The modifications are as follows:
>> 
>> v3:
>> - Rebase on master
>> - Use the refined commit message furnished by Markus for [PATCH v2 1/2] 
>> - Drop the [PATCH v2 2/2]
>> - Add [PATCH v3 2/3] to declare the decoding functions to static
>> - Add [PATCH v3 3/3] to Define VhostDeviceProtocols and
>>   VirtioDeviceFeatures as plain C types
>> 
>> Since Markus inspired all of the alterations above, we would like to
>> thank him for his contribution to this series.
>> 
>> Please review,
>> Yong
>
> Markus do you think you can take a look at this?

I intend to.  Sorry for the delay!



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v3 1/3] qmp: Switch x-query-virtio-status back to numeric encoding
  2024-02-13 10:26   ` Michael S. Tsirkin
@ 2024-02-15 12:49     ` Yong Huang
  2024-02-19 15:32       ` Markus Armbruster
  0 siblings, 1 reply; 14+ messages in thread
From: Yong Huang @ 2024-02-15 12:49 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: qemu-devel, Markus Armbruster, Eric Blake

[-- Attachment #1: Type: text/plain, Size: 23036 bytes --]

On Tue, Feb 13, 2024 at 6:26 PM Michael S. Tsirkin <mst@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.huang@smartx.com/3c7161a47b141af04b1f8272e8e24c5faa46ddb2.1700319559.git.yong.huang@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.huang@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

[-- Attachment #2: Type: text/html, Size: 31944 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v3 1/3] qmp: Switch x-query-virtio-status back to numeric encoding
  2024-02-02 14:32 ` [PATCH v3 1/3] qmp: Switch x-query-virtio-status back to numeric encoding Hyman Huang
  2024-02-13 10:26   ` Michael S. Tsirkin
@ 2024-02-19 15:18   ` Markus Armbruster
  1 sibling, 0 replies; 14+ messages in thread
From: Markus Armbruster @ 2024-02-19 15:18 UTC (permalink / raw)
  To: Hyman Huang; +Cc: qemu-devel, Michael S . Tsirkin, Eric Blake

Hyman Huang <yong.huang@smartx.com> writes:

> 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

added 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.
>
> 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

Scratch "does".

> comes without a stability promise.
>
> Signed-off-by: Hyman Huang <yong.huang@smartx.com>

Acked-by: Markus Armbruster <armbru@redhat.com>



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v3 1/3] qmp: Switch x-query-virtio-status back to numeric encoding
  2024-02-15 12:49     ` Yong Huang
@ 2024-02-19 15:32       ` Markus Armbruster
  2024-02-20  1:27         ` Yong Huang
  0 siblings, 1 reply; 14+ messages in thread
From: Markus Armbruster @ 2024-02-19 15:32 UTC (permalink / raw)
  To: Yong Huang; +Cc: qemu-devel, Markus Armbruster, Eric Blake

Yong Huang <yong.huang@smartx.com> writes:

> On Tue, Feb 13, 2024 at 6:26 PM Michael S. Tsirkin <mst@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.huang@smartx.com/3c7161a47b141af04b1f8272e8e24c5faa46ddb2.1700319559.git.yong.huang@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?

QMP is for machines.

That said, I won't object to adding development & debugging aids meant
for humans as long as

1. they're marked unstable, and

2. they either add only a modest amount of output, or the additional
   output is off by default.

What exactly is a "modest amount" depends on how machines use the
command.  If they use it all the time, even going from 8KiB to 64KiB
could be too much.  If they use it just once per guest, we can afford
more waste.

In this particular case, we could add an unstable member of type ['str']
next to the int-valued bits.  For each set bit in the int, add a string
to the list.  If QEMU knows the bit, use the well-known name.  I'd omit
the common prefix, though: use "GUEST_ANNOUNCE" or "guest-announce"
instead of "VIRTIO_NET_F_GUEST_ANNOUNCE".  If QEMU doesn't know the bit,
you could use the bit's numeric value.

Recommend a separate patch, to avoid delaying this series.

Makes sense?



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v3 3/3] qapi: Define VhostDeviceProtocols and VirtioDeviceFeatures as plain C types
  2024-02-02 14:32 ` [PATCH v3 3/3] qapi: Define VhostDeviceProtocols and VirtioDeviceFeatures as plain C types Hyman Huang
@ 2024-02-19 15:33   ` Markus Armbruster
  0 siblings, 0 replies; 14+ messages in thread
From: Markus Armbruster @ 2024-02-19 15:33 UTC (permalink / raw)
  To: Hyman Huang; +Cc: qemu-devel, Michael S . Tsirkin, Eric Blake

Hyman Huang <yong.huang@smartx.com> writes:

> VhostDeviceProtocols and VirtioDeviceFeatures are only used in
> virtio-hmp-cmds.c.  So define them as plain C types there, and drop
> them from the QAPI schema.
>
> Signed-off-by: Hyman Huang <yong.huang@smartx.com>

Reviewed-by: Markus Armbruster <armbru@redhat.com>



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v3 2/3] virtio: Declare the decoding functions to static
  2024-02-02 14:32 ` [PATCH v3 2/3] virtio: Declare the decoding functions to static Hyman Huang
@ 2024-02-19 15:38   ` Markus Armbruster
  2024-02-21  3:59     ` Yong Huang
  0 siblings, 1 reply; 14+ messages in thread
From: Markus Armbruster @ 2024-02-19 15:38 UTC (permalink / raw)
  To: Hyman Huang; +Cc: qemu-devel, Michael S . Tsirkin, Eric Blake

Hyman Huang <yong.huang@smartx.com> writes:

> qmp_decode_protocols(), qmp_decode_status(), and qmp_decode_features()
> are now only used in virtio-hmp-cmds.c.  So move them into there,
> redeclare them to static, and replace the qmp_ prefix with hmp_.
>
> Signed-off-by: Hyman Huang <yong.huang@smartx.com>
> ---
>  hw/virtio/meson.build       |   3 +-
>  hw/virtio/virtio-hmp-cmds.c | 677 +++++++++++++++++++++++++++++++++++-
>  hw/virtio/virtio-qmp.c      | 661 -----------------------------------
>  hw/virtio/virtio-qmp.h      |   3 -
>  4 files changed, 670 insertions(+), 674 deletions(-)
>
> diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build
> index 47baf00366..6665669480 100644
> --- a/hw/virtio/meson.build
> +++ b/hw/virtio/meson.build
> @@ -9,7 +9,7 @@ system_virtio_ss.add(when: 'CONFIG_VHOST_VDPA_DEV', if_true: files('vdpa-dev.c')
>  
>  specific_virtio_ss = ss.source_set()
>  specific_virtio_ss.add(files('virtio.c'))
> -specific_virtio_ss.add(files('virtio-config-io.c', 'virtio-qmp.c'))
> +specific_virtio_ss.add(files('virtio-config-io.c', 'virtio-qmp.c', 'virtio-hmp-cmds.c'))

I think you can also move virtio-qmp.c, i.e.

   specific_virtio_ss.add(files('virtio-config-io.c', 'virtio-hmp-cmds.c'))

here, and ...

>  
>  if have_vhost
>    system_virtio_ss.add(files('vhost.c'))
> @@ -74,7 +74,6 @@ specific_virtio_ss.add_all(when: 'CONFIG_VIRTIO_PCI', if_true: virtio_pci_ss)
>  system_ss.add_all(when: 'CONFIG_VIRTIO', if_true: system_virtio_ss)
>  system_ss.add(when: 'CONFIG_VIRTIO', if_false: files('vhost-stub.c'))
>  system_ss.add(when: 'CONFIG_VIRTIO', if_false: files('virtio-stub.c'))
> -system_ss.add(files('virtio-hmp-cmds.c'))

   system_ss.add(files('virtio-qmp.c'))

here.

[...]



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v3 1/3] qmp: Switch x-query-virtio-status back to numeric encoding
  2024-02-19 15:32       ` Markus Armbruster
@ 2024-02-20  1:27         ` Yong Huang
  0 siblings, 0 replies; 14+ messages in thread
From: Yong Huang @ 2024-02-20  1:27 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: qemu-devel, Eric Blake

[-- Attachment #1: Type: text/plain, Size: 3803 bytes --]

On Mon, Feb 19, 2024 at 11:32 PM Markus Armbruster <armbru@redhat.com>
wrote:

> Yong Huang <yong.huang@smartx.com> writes:
>
> > On Tue, Feb 13, 2024 at 6:26 PM Michael S. Tsirkin <mst@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.huang@smartx.com/3c7161a47b141af04b1f8272e8e24c5faa46ddb2.1700319559.git.yong.huang@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?
>
> QMP is for machines.
>
> That said, I won't object to adding development & debugging aids meant
> for humans as long as
>
> 1. they're marked unstable, and
>
> 2. they either add only a modest amount of output, or the additional
>    output is off by default.
>
> What exactly is a "modest amount" depends on how machines use the
> command.  If they use it all the time, even going from 8KiB to 64KiB
> could be too much.  If they use it just once per guest, we can afford
> more waste.
>
> In this particular case, we could add an unstable member of type ['str']
> next to the int-valued bits.  For each set bit in the int, add a string
> to the list.  If QEMU knows the bit, use the well-known name.  I'd omit
> the common prefix, though: use "GUEST_ANNOUNCE" or "guest-announce"
> instead of "VIRTIO_NET_F_GUEST_ANNOUNCE".  If QEMU doesn't know the bit,
> you could use the bit's numeric value.
>
> Recommend a separate patch, to avoid delaying this series.
>
> Makes sense?
>
>
I agree,  and thanks for the comments.

Yong

-- 
Best regards

[-- Attachment #2: Type: text/html, Size: 5565 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v3 2/3] virtio: Declare the decoding functions to static
  2024-02-19 15:38   ` Markus Armbruster
@ 2024-02-21  3:59     ` Yong Huang
  0 siblings, 0 replies; 14+ messages in thread
From: Yong Huang @ 2024-02-21  3:59 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: qemu-devel, Michael S . Tsirkin, Eric Blake

[-- Attachment #1: Type: text/plain, Size: 2017 bytes --]

On Mon, Feb 19, 2024 at 11:38 PM Markus Armbruster <armbru@redhat.com>
wrote:

> Hyman Huang <yong.huang@smartx.com> writes:
>
> > qmp_decode_protocols(), qmp_decode_status(), and qmp_decode_features()
> > are now only used in virtio-hmp-cmds.c.  So move them into there,
> > redeclare them to static, and replace the qmp_ prefix with hmp_.
> >
> > Signed-off-by: Hyman Huang <yong.huang@smartx.com>
> > ---
> >  hw/virtio/meson.build       |   3 +-
> >  hw/virtio/virtio-hmp-cmds.c | 677 +++++++++++++++++++++++++++++++++++-
> >  hw/virtio/virtio-qmp.c      | 661 -----------------------------------
> >  hw/virtio/virtio-qmp.h      |   3 -
> >  4 files changed, 670 insertions(+), 674 deletions(-)
> >
> > diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build
> > index 47baf00366..6665669480 100644
> > --- a/hw/virtio/meson.build
> > +++ b/hw/virtio/meson.build
> > @@ -9,7 +9,7 @@ system_virtio_ss.add(when: 'CONFIG_VHOST_VDPA_DEV',
> if_true: files('vdpa-dev.c')
> >
> >  specific_virtio_ss = ss.source_set()
> >  specific_virtio_ss.add(files('virtio.c'))
> > -specific_virtio_ss.add(files('virtio-config-io.c', 'virtio-qmp.c'))
> > +specific_virtio_ss.add(files('virtio-config-io.c', 'virtio-qmp.c',
> 'virtio-hmp-cmds.c'))
>
> I think you can also move virtio-qmp.c, i.e.
>
>    specific_virtio_ss.add(files('virtio-config-io.c', 'virtio-hmp-cmds.c'))
>
> here, and ...
>
> >
> >  if have_vhost
> >    system_virtio_ss.add(files('vhost.c'))
> > @@ -74,7 +74,6 @@ specific_virtio_ss.add_all(when: 'CONFIG_VIRTIO_PCI',
> if_true: virtio_pci_ss)
> >  system_ss.add_all(when: 'CONFIG_VIRTIO', if_true: system_virtio_ss)
> >  system_ss.add(when: 'CONFIG_VIRTIO', if_false: files('vhost-stub.c'))
> >  system_ss.add(when: 'CONFIG_VIRTIO', if_false: files('virtio-stub.c'))
> > -system_ss.add(files('virtio-hmp-cmds.c'))
>
>    system_ss.add(files('virtio-qmp.c'))
>
> here.
>

Get it,  I'll try in the next version.


> [...]
>
>

-- 
Best regards

[-- Attachment #2: Type: text/html, Size: 3517 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2024-02-21  4:02 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-02-02 14:32 [PATCH v3 0/3] Adjust the output of x-query-virtio-status Hyman Huang
2024-02-02 14:32 ` [PATCH v3 1/3] qmp: Switch x-query-virtio-status back to numeric encoding Hyman Huang
2024-02-13 10:26   ` Michael S. Tsirkin
2024-02-15 12:49     ` Yong Huang
2024-02-19 15:32       ` Markus Armbruster
2024-02-20  1:27         ` Yong Huang
2024-02-19 15:18   ` Markus Armbruster
2024-02-02 14:32 ` [PATCH v3 2/3] virtio: Declare the decoding functions to static Hyman Huang
2024-02-19 15:38   ` Markus Armbruster
2024-02-21  3:59     ` Yong Huang
2024-02-02 14:32 ` [PATCH v3 3/3] qapi: Define VhostDeviceProtocols and VirtioDeviceFeatures as plain C types Hyman Huang
2024-02-19 15:33   ` Markus Armbruster
2024-02-13 10:25 ` [PATCH v3 0/3] Adjust the output of x-query-virtio-status Michael S. Tsirkin
2024-02-13 13:30   ` Markus Armbruster

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).