mirror of
https://github.com/qemu/qemu.git
synced 2026-02-04 05:35:39 +00:00
qmp: update virtio features map to support extended features
Extend the VirtioDeviceFeatures struct with an additional u64 to track unknown features in the 64-127 bit range and decode the full virtio features spaces for vhost and virtio devices. Also add entries for the soon-to-be-supported virtio net GSO over UDP features. Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp> Acked-by: Jason Wang <jasowang@redhat.com> Acked-by: Markus Armbruster <armbru@redhat.com> Acked-by: Stefano Garzarella <sgarzare@redhat.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com> Tested-by: Lei Yang <leiyang@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Message-ID: <e51969f94d89045b333f1bc5ef5fca9e12fc371a.1758549625.git.pabeni@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
committed by
Michael S. Tsirkin
parent
9f979ef0e0
commit
a76f5b795c
@@ -74,7 +74,8 @@ static void hmp_virtio_dump_features(Monitor *mon,
|
||||
}
|
||||
|
||||
if (features->has_unknown_dev_features) {
|
||||
monitor_printf(mon, " unknown-features(0x%016"PRIx64")\n",
|
||||
monitor_printf(mon, " unknown-features(0x%016"PRIx64"%016"PRIx64")\n",
|
||||
features->unknown_dev_features2,
|
||||
features->unknown_dev_features);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -325,6 +325,20 @@ static const qmp_virtio_feature_map_t virtio_net_feature_map[] = {
|
||||
FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
|
||||
"VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
|
||||
"negotiation supported"),
|
||||
FEATURE_ENTRY(VIRTIO_NET_F_GUEST_UDP_TUNNEL_GSO, \
|
||||
"VIRTIO_NET_F_GUEST_UDP_TUNNEL_GSO: Driver can receive GSO over "
|
||||
"UDP tunnel packets"),
|
||||
FEATURE_ENTRY(VIRTIO_NET_F_GUEST_UDP_TUNNEL_GSO_CSUM, \
|
||||
"VIRTIO_NET_F_GUEST_UDP_TUNNEL_GSO: Driver can receive GSO over "
|
||||
"UDP tunnel packets requiring checksum offload for the outer "
|
||||
"header"),
|
||||
FEATURE_ENTRY(VIRTIO_NET_F_HOST_UDP_TUNNEL_GSO, \
|
||||
"VIRTIO_NET_F_HOST_UDP_TUNNEL_GSO: Device can receive GSO over "
|
||||
"UDP tunnel packets"),
|
||||
FEATURE_ENTRY(VIRTIO_NET_F_HOST_UDP_TUNNEL_GSO_CSUM, \
|
||||
"VIRTIO_NET_F_HOST_UDP_TUNNEL_GSO_CSUM: Device can receive GSO over "
|
||||
"UDP tunnel packets requiring checksum offload for the outer "
|
||||
"header"),
|
||||
{ -1, "" }
|
||||
};
|
||||
#endif
|
||||
@@ -510,6 +524,24 @@ static const qmp_virtio_feature_map_t virtio_gpio_feature_map[] = {
|
||||
list; \
|
||||
})
|
||||
|
||||
#define CONVERT_FEATURES_EX(type, map, bitmap) \
|
||||
({ \
|
||||
type *list = NULL; \
|
||||
type *node; \
|
||||
for (i = 0; map[i].virtio_bit != -1; i++) { \
|
||||
bit = map[i].virtio_bit; \
|
||||
if (!virtio_has_feature_ex(bitmap, bit)) { \
|
||||
continue; \
|
||||
} \
|
||||
node = g_new0(type, 1); \
|
||||
node->value = g_strdup(map[i].feature_desc); \
|
||||
node->next = list; \
|
||||
list = node; \
|
||||
virtio_clear_feature_ex(bitmap, bit); \
|
||||
} \
|
||||
list; \
|
||||
})
|
||||
|
||||
VirtioDeviceStatus *qmp_decode_status(uint8_t bitmap)
|
||||
{
|
||||
VirtioDeviceStatus *status;
|
||||
@@ -545,109 +577,112 @@ VhostDeviceProtocols *qmp_decode_protocols(uint64_t bitmap)
|
||||
return vhu_protocols;
|
||||
}
|
||||
|
||||
VirtioDeviceFeatures *qmp_decode_features(uint16_t device_id, uint64_t bitmap)
|
||||
VirtioDeviceFeatures *qmp_decode_features(uint16_t device_id,
|
||||
const uint64_t *bmap)
|
||||
{
|
||||
uint64_t bitmap[VIRTIO_FEATURES_NU64S];
|
||||
VirtioDeviceFeatures *features;
|
||||
uint64_t bit;
|
||||
int i;
|
||||
|
||||
virtio_features_copy(bitmap, bmap);
|
||||
features = g_new0(VirtioDeviceFeatures, 1);
|
||||
features->has_dev_features = true;
|
||||
|
||||
/* transport features */
|
||||
features->transports = CONVERT_FEATURES(strList, virtio_transport_map, 0,
|
||||
bitmap);
|
||||
features->transports = CONVERT_FEATURES_EX(strList, virtio_transport_map,
|
||||
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);
|
||||
CONVERT_FEATURES_EX(strList, virtio_serial_feature_map, bitmap);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_VIRTIO_BLK
|
||||
case VIRTIO_ID_BLOCK:
|
||||
features->dev_features =
|
||||
CONVERT_FEATURES(strList, virtio_blk_feature_map, 0, bitmap);
|
||||
CONVERT_FEATURES_EX(strList, virtio_blk_feature_map, bitmap);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_VIRTIO_GPU
|
||||
case VIRTIO_ID_GPU:
|
||||
features->dev_features =
|
||||
CONVERT_FEATURES(strList, virtio_gpu_feature_map, 0, bitmap);
|
||||
CONVERT_FEATURES_EX(strList, virtio_gpu_feature_map, bitmap);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_VIRTIO_NET
|
||||
case VIRTIO_ID_NET:
|
||||
features->dev_features =
|
||||
CONVERT_FEATURES(strList, virtio_net_feature_map, 0, bitmap);
|
||||
CONVERT_FEATURES_EX(strList, virtio_net_feature_map, bitmap);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_VIRTIO_SCSI
|
||||
case VIRTIO_ID_SCSI:
|
||||
features->dev_features =
|
||||
CONVERT_FEATURES(strList, virtio_scsi_feature_map, 0, bitmap);
|
||||
CONVERT_FEATURES_EX(strList, virtio_scsi_feature_map, bitmap);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_VIRTIO_BALLOON
|
||||
case VIRTIO_ID_BALLOON:
|
||||
features->dev_features =
|
||||
CONVERT_FEATURES(strList, virtio_balloon_feature_map, 0, bitmap);
|
||||
CONVERT_FEATURES_EX(strList, virtio_balloon_feature_map, bitmap);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_VIRTIO_IOMMU
|
||||
case VIRTIO_ID_IOMMU:
|
||||
features->dev_features =
|
||||
CONVERT_FEATURES(strList, virtio_iommu_feature_map, 0, bitmap);
|
||||
CONVERT_FEATURES_EX(strList, virtio_iommu_feature_map, bitmap);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_VIRTIO_INPUT
|
||||
case VIRTIO_ID_INPUT:
|
||||
features->dev_features =
|
||||
CONVERT_FEATURES(strList, virtio_input_feature_map, 0, bitmap);
|
||||
CONVERT_FEATURES_EX(strList, virtio_input_feature_map, bitmap);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_VHOST_USER_FS
|
||||
case VIRTIO_ID_FS:
|
||||
features->dev_features =
|
||||
CONVERT_FEATURES(strList, virtio_fs_feature_map, 0, bitmap);
|
||||
CONVERT_FEATURES_EX(strList, virtio_fs_feature_map, bitmap);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_VHOST_VSOCK
|
||||
case VIRTIO_ID_VSOCK:
|
||||
features->dev_features =
|
||||
CONVERT_FEATURES(strList, virtio_vsock_feature_map, 0, bitmap);
|
||||
CONVERT_FEATURES_EX(strList, virtio_vsock_feature_map, bitmap);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_VIRTIO_CRYPTO
|
||||
case VIRTIO_ID_CRYPTO:
|
||||
features->dev_features =
|
||||
CONVERT_FEATURES(strList, virtio_crypto_feature_map, 0, bitmap);
|
||||
CONVERT_FEATURES_EX(strList, virtio_crypto_feature_map, bitmap);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_VIRTIO_MEM
|
||||
case VIRTIO_ID_MEM:
|
||||
features->dev_features =
|
||||
CONVERT_FEATURES(strList, virtio_mem_feature_map, 0, bitmap);
|
||||
CONVERT_FEATURES_EX(strList, virtio_mem_feature_map, 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);
|
||||
CONVERT_FEATURES_EX(strList, virtio_i2c_feature_map, bitmap);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_VIRTIO_RNG
|
||||
case VIRTIO_ID_RNG:
|
||||
features->dev_features =
|
||||
CONVERT_FEATURES(strList, virtio_rng_feature_map, 0, bitmap);
|
||||
CONVERT_FEATURES_EX(strList, virtio_rng_feature_map, bitmap);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_VHOST_USER_GPIO
|
||||
case VIRTIO_ID_GPIO:
|
||||
features->dev_features =
|
||||
CONVERT_FEATURES(strList, virtio_gpio_feature_map, 0, bitmap);
|
||||
CONVERT_FEATURES_EX(strList, virtio_gpio_feature_map, bitmap);
|
||||
break;
|
||||
#endif
|
||||
/* No features */
|
||||
@@ -680,10 +715,9 @@ VirtioDeviceFeatures *qmp_decode_features(uint16_t device_id, uint64_t bitmap)
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
features->has_unknown_dev_features = bitmap != 0;
|
||||
if (features->has_unknown_dev_features) {
|
||||
features->unknown_dev_features = bitmap;
|
||||
}
|
||||
features->has_unknown_dev_features = !virtio_features_empty(bitmap);
|
||||
features->unknown_dev_features = bitmap[0];
|
||||
features->unknown_dev_features2 = bitmap[1];
|
||||
|
||||
return features;
|
||||
}
|
||||
@@ -743,11 +777,11 @@ VirtioStatus *qmp_x_query_virtio_status(const char *path, Error **errp)
|
||||
status->device_id = vdev->device_id;
|
||||
status->vhost_started = vdev->vhost_started;
|
||||
status->guest_features = qmp_decode_features(vdev->device_id,
|
||||
vdev->guest_features);
|
||||
vdev->guest_features_ex);
|
||||
status->host_features = qmp_decode_features(vdev->device_id,
|
||||
vdev->host_features);
|
||||
vdev->host_features_ex);
|
||||
status->backend_features = qmp_decode_features(vdev->device_id,
|
||||
vdev->backend_features);
|
||||
vdev->backend_features_ex);
|
||||
|
||||
switch (vdev->device_endian) {
|
||||
case VIRTIO_DEVICE_ENDIAN_LITTLE:
|
||||
@@ -785,11 +819,12 @@ VirtioStatus *qmp_x_query_virtio_status(const char *path, Error **errp)
|
||||
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);
|
||||
qmp_decode_features(vdev->device_id, hdev->features_ex);
|
||||
status->vhost_dev->acked_features =
|
||||
qmp_decode_features(vdev->device_id, hdev->acked_features);
|
||||
qmp_decode_features(vdev->device_id, hdev->acked_features_ex);
|
||||
status->vhost_dev->backend_features =
|
||||
qmp_decode_features(vdev->device_id, hdev->backend_features);
|
||||
qmp_decode_features(vdev->device_id, hdev->backend_features_ex);
|
||||
|
||||
status->vhost_dev->protocol_features =
|
||||
qmp_decode_protocols(hdev->protocol_features);
|
||||
status->vhost_dev->max_queues = hdev->max_queues;
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
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);
|
||||
VirtioDeviceFeatures *qmp_decode_features(uint16_t device_id,
|
||||
const uint64_t *bitmap);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -247,6 +247,7 @@
|
||||
# },
|
||||
# "host-features": {
|
||||
# "unknown-dev-features": 1073741824,
|
||||
# "unknown-dev-features2": 0,
|
||||
# "dev-features": [],
|
||||
# "transports": [
|
||||
# "VIRTIO_RING_F_EVENT_IDX: Used & avail. event fields enabled",
|
||||
@@ -490,14 +491,18 @@
|
||||
# unique features)
|
||||
#
|
||||
# @unknown-dev-features: Virtio device features bitmap that have not
|
||||
# been decoded
|
||||
# been decoded (bits 0-63)
|
||||
#
|
||||
# @unknown-dev-features2: Virtio device features bitmap that have not
|
||||
# been decoded (bits 64-127) (since 10.2)
|
||||
#
|
||||
# Since: 7.2
|
||||
##
|
||||
{ 'struct': 'VirtioDeviceFeatures',
|
||||
'data': { 'transports': [ 'str' ],
|
||||
'*dev-features': [ 'str' ],
|
||||
'*unknown-dev-features': 'uint64' } }
|
||||
'*unknown-dev-features': 'uint64',
|
||||
'*unknown-dev-features2': 'uint64' } }
|
||||
|
||||
##
|
||||
# @VirtQueueStatus:
|
||||
|
||||
Reference in New Issue
Block a user