xref: /qemu/hw/virtio/virtio-qmp.c (revision f8ed3648b5b9c0cd77397ae4404f3e9e4be8a426)
128b629abSPhilippe Mathieu-Daudé /*
228b629abSPhilippe Mathieu-Daudé  * Virtio QMP helpers
328b629abSPhilippe Mathieu-Daudé  *
428b629abSPhilippe Mathieu-Daudé  * Copyright IBM, Corp. 2007
528b629abSPhilippe Mathieu-Daudé  *
628b629abSPhilippe Mathieu-Daudé  * Authors:
728b629abSPhilippe Mathieu-Daudé  *  Anthony Liguori   <aliguori@us.ibm.com>
828b629abSPhilippe Mathieu-Daudé  *
928b629abSPhilippe Mathieu-Daudé  * SPDX-License-Identifier: GPL-2.0-or-later
1028b629abSPhilippe Mathieu-Daudé  */
1128b629abSPhilippe Mathieu-Daudé 
1228b629abSPhilippe Mathieu-Daudé #include "qemu/osdep.h"
1328b629abSPhilippe Mathieu-Daudé #include "virtio-qmp.h"
1428b629abSPhilippe Mathieu-Daudé 
159d94c213SPhilippe Mathieu-Daudé #include "qapi/error.h"
169d94c213SPhilippe Mathieu-Daudé #include "qapi/qapi-commands-virtio.h"
179d94c213SPhilippe Mathieu-Daudé #include "qapi/qapi-commands-qom.h"
189d94c213SPhilippe Mathieu-Daudé #include "qapi/qmp/qobject.h"
199d94c213SPhilippe Mathieu-Daudé #include "qapi/qmp/qjson.h"
209d94c213SPhilippe Mathieu-Daudé 
2128b629abSPhilippe Mathieu-Daudé #include "standard-headers/linux/virtio_ids.h"
2228b629abSPhilippe Mathieu-Daudé #include "standard-headers/linux/vhost_types.h"
2328b629abSPhilippe Mathieu-Daudé #include "standard-headers/linux/virtio_blk.h"
2428b629abSPhilippe Mathieu-Daudé #include "standard-headers/linux/virtio_console.h"
2528b629abSPhilippe Mathieu-Daudé #include "standard-headers/linux/virtio_gpu.h"
2628b629abSPhilippe Mathieu-Daudé #include "standard-headers/linux/virtio_net.h"
2728b629abSPhilippe Mathieu-Daudé #include "standard-headers/linux/virtio_scsi.h"
2828b629abSPhilippe Mathieu-Daudé #include "standard-headers/linux/virtio_i2c.h"
2928b629abSPhilippe Mathieu-Daudé #include "standard-headers/linux/virtio_balloon.h"
3028b629abSPhilippe Mathieu-Daudé #include "standard-headers/linux/virtio_iommu.h"
3128b629abSPhilippe Mathieu-Daudé #include "standard-headers/linux/virtio_mem.h"
3228b629abSPhilippe Mathieu-Daudé #include "standard-headers/linux/virtio_vsock.h"
3328b629abSPhilippe Mathieu-Daudé 
3428b629abSPhilippe Mathieu-Daudé #include CONFIG_DEVICES
3528b629abSPhilippe Mathieu-Daudé 
3628b629abSPhilippe Mathieu-Daudé #define FEATURE_ENTRY(name, desc) (qmp_virtio_feature_map_t) \
3728b629abSPhilippe Mathieu-Daudé     { .virtio_bit = name, .feature_desc = desc }
3828b629abSPhilippe Mathieu-Daudé 
3928b629abSPhilippe Mathieu-Daudé enum VhostUserProtocolFeature {
4028b629abSPhilippe Mathieu-Daudé     VHOST_USER_PROTOCOL_F_MQ = 0,
4128b629abSPhilippe Mathieu-Daudé     VHOST_USER_PROTOCOL_F_LOG_SHMFD = 1,
4228b629abSPhilippe Mathieu-Daudé     VHOST_USER_PROTOCOL_F_RARP = 2,
4328b629abSPhilippe Mathieu-Daudé     VHOST_USER_PROTOCOL_F_REPLY_ACK = 3,
4428b629abSPhilippe Mathieu-Daudé     VHOST_USER_PROTOCOL_F_NET_MTU = 4,
45a84ec993SMaxime Coquelin     VHOST_USER_PROTOCOL_F_BACKEND_REQ = 5,
4628b629abSPhilippe Mathieu-Daudé     VHOST_USER_PROTOCOL_F_CROSS_ENDIAN = 6,
4728b629abSPhilippe Mathieu-Daudé     VHOST_USER_PROTOCOL_F_CRYPTO_SESSION = 7,
4828b629abSPhilippe Mathieu-Daudé     VHOST_USER_PROTOCOL_F_PAGEFAULT = 8,
4928b629abSPhilippe Mathieu-Daudé     VHOST_USER_PROTOCOL_F_CONFIG = 9,
50a84ec993SMaxime Coquelin     VHOST_USER_PROTOCOL_F_BACKEND_SEND_FD = 10,
5128b629abSPhilippe Mathieu-Daudé     VHOST_USER_PROTOCOL_F_HOST_NOTIFIER = 11,
5228b629abSPhilippe Mathieu-Daudé     VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD = 12,
5328b629abSPhilippe Mathieu-Daudé     VHOST_USER_PROTOCOL_F_RESET_DEVICE = 13,
5428b629abSPhilippe Mathieu-Daudé     VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS = 14,
5528b629abSPhilippe Mathieu-Daudé     VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS = 15,
5628b629abSPhilippe Mathieu-Daudé     VHOST_USER_PROTOCOL_F_MAX
5728b629abSPhilippe Mathieu-Daudé };
5828b629abSPhilippe Mathieu-Daudé 
5928b629abSPhilippe Mathieu-Daudé /* Virtio transport features mapping */
6028b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_transport_map[] = {
6128b629abSPhilippe Mathieu-Daudé     /* Virtio device transport features */
6228b629abSPhilippe Mathieu-Daudé #ifndef VIRTIO_CONFIG_NO_LEGACY
6328b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_F_NOTIFY_ON_EMPTY, \
6428b629abSPhilippe Mathieu-Daudé             "VIRTIO_F_NOTIFY_ON_EMPTY: Notify when device runs out of avail. "
6528b629abSPhilippe Mathieu-Daudé             "descs. on VQ"),
6628b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_F_ANY_LAYOUT, \
6728b629abSPhilippe Mathieu-Daudé             "VIRTIO_F_ANY_LAYOUT: Device accepts arbitrary desc. layouts"),
6828b629abSPhilippe Mathieu-Daudé #endif /* !VIRTIO_CONFIG_NO_LEGACY */
6928b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_F_VERSION_1, \
7028b629abSPhilippe Mathieu-Daudé             "VIRTIO_F_VERSION_1: Device compliant for v1 spec (legacy)"),
7128b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_F_IOMMU_PLATFORM, \
7228b629abSPhilippe Mathieu-Daudé             "VIRTIO_F_IOMMU_PLATFORM: Device can be used on IOMMU platform"),
7328b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_F_RING_PACKED, \
7428b629abSPhilippe Mathieu-Daudé             "VIRTIO_F_RING_PACKED: Device supports packed VQ layout"),
7528b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_F_IN_ORDER, \
7628b629abSPhilippe Mathieu-Daudé             "VIRTIO_F_IN_ORDER: Device uses buffers in same order as made "
7728b629abSPhilippe Mathieu-Daudé             "available by driver"),
7828b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_F_ORDER_PLATFORM, \
7928b629abSPhilippe Mathieu-Daudé             "VIRTIO_F_ORDER_PLATFORM: Memory accesses ordered by platform"),
8028b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_F_SR_IOV, \
8128b629abSPhilippe Mathieu-Daudé             "VIRTIO_F_SR_IOV: Device supports single root I/O virtualization"),
8228b629abSPhilippe Mathieu-Daudé     /* Virtio ring transport features */
8328b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_RING_F_INDIRECT_DESC, \
8428b629abSPhilippe Mathieu-Daudé             "VIRTIO_RING_F_INDIRECT_DESC: Indirect descriptors supported"),
8528b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_RING_F_EVENT_IDX, \
8628b629abSPhilippe Mathieu-Daudé             "VIRTIO_RING_F_EVENT_IDX: Used & avail. event fields enabled"),
8728b629abSPhilippe Mathieu-Daudé     { -1, "" }
8828b629abSPhilippe Mathieu-Daudé };
8928b629abSPhilippe Mathieu-Daudé 
9028b629abSPhilippe Mathieu-Daudé /* Vhost-user protocol features mapping */
9128b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t vhost_user_protocol_map[] = {
9228b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_MQ, \
9328b629abSPhilippe Mathieu-Daudé             "VHOST_USER_PROTOCOL_F_MQ: Multiqueue protocol supported"),
9428b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_LOG_SHMFD, \
9528b629abSPhilippe Mathieu-Daudé             "VHOST_USER_PROTOCOL_F_LOG_SHMFD: Shared log memory fd supported"),
9628b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_RARP, \
9728b629abSPhilippe Mathieu-Daudé             "VHOST_USER_PROTOCOL_F_RARP: Vhost-user back-end RARP broadcasting "
9828b629abSPhilippe Mathieu-Daudé             "supported"),
9928b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_REPLY_ACK, \
10028b629abSPhilippe Mathieu-Daudé             "VHOST_USER_PROTOCOL_F_REPLY_ACK: Requested operation status ack. "
10128b629abSPhilippe Mathieu-Daudé             "supported"),
10228b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_NET_MTU, \
10328b629abSPhilippe Mathieu-Daudé             "VHOST_USER_PROTOCOL_F_NET_MTU: Expose host MTU to guest supported"),
104a84ec993SMaxime Coquelin     FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_BACKEND_REQ, \
105a84ec993SMaxime Coquelin             "VHOST_USER_PROTOCOL_F_BACKEND_REQ: Socket fd for back-end initiated "
10628b629abSPhilippe Mathieu-Daudé             "requests supported"),
10728b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_CROSS_ENDIAN, \
10828b629abSPhilippe Mathieu-Daudé             "VHOST_USER_PROTOCOL_F_CROSS_ENDIAN: Endianness of VQs for legacy "
10928b629abSPhilippe Mathieu-Daudé             "devices supported"),
11028b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_CRYPTO_SESSION, \
11128b629abSPhilippe Mathieu-Daudé             "VHOST_USER_PROTOCOL_F_CRYPTO_SESSION: Session creation for crypto "
11228b629abSPhilippe Mathieu-Daudé             "operations supported"),
11328b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_PAGEFAULT, \
11428b629abSPhilippe Mathieu-Daudé             "VHOST_USER_PROTOCOL_F_PAGEFAULT: Request servicing on userfaultfd "
11528b629abSPhilippe Mathieu-Daudé             "for accessed pages supported"),
11628b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_CONFIG, \
11728b629abSPhilippe Mathieu-Daudé             "VHOST_USER_PROTOCOL_F_CONFIG: Vhost-user messaging for virtio "
11828b629abSPhilippe Mathieu-Daudé             "device configuration space supported"),
119a84ec993SMaxime Coquelin     FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_BACKEND_SEND_FD, \
120*f8ed3648SManos Pitsidianakis             "VHOST_USER_PROTOCOL_F_BACKEND_SEND_FD: Backend fd communication "
12128b629abSPhilippe Mathieu-Daudé             "channel supported"),
12228b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_HOST_NOTIFIER, \
12328b629abSPhilippe Mathieu-Daudé             "VHOST_USER_PROTOCOL_F_HOST_NOTIFIER: Host notifiers for specified "
12428b629abSPhilippe Mathieu-Daudé             "VQs supported"),
12528b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD, \
12628b629abSPhilippe Mathieu-Daudé             "VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD: Shared inflight I/O buffers "
12728b629abSPhilippe Mathieu-Daudé             "supported"),
12828b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_RESET_DEVICE, \
12928b629abSPhilippe Mathieu-Daudé             "VHOST_USER_PROTOCOL_F_RESET_DEVICE: Disabling all rings and "
13028b629abSPhilippe Mathieu-Daudé             "resetting internal device state supported"),
13128b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS, \
13228b629abSPhilippe Mathieu-Daudé             "VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS: In-band messaging "
13328b629abSPhilippe Mathieu-Daudé             "supported"),
13428b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS, \
13528b629abSPhilippe Mathieu-Daudé             "VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS: Configuration for "
13628b629abSPhilippe Mathieu-Daudé             "memory slots supported"),
13728b629abSPhilippe Mathieu-Daudé     { -1, "" }
13828b629abSPhilippe Mathieu-Daudé };
13928b629abSPhilippe Mathieu-Daudé 
14028b629abSPhilippe Mathieu-Daudé /* virtio device configuration statuses */
14128b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_config_status_map[] = {
14228b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_CONFIG_S_DRIVER_OK, \
14328b629abSPhilippe Mathieu-Daudé             "VIRTIO_CONFIG_S_DRIVER_OK: Driver setup and ready"),
14428b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_CONFIG_S_FEATURES_OK, \
14528b629abSPhilippe Mathieu-Daudé             "VIRTIO_CONFIG_S_FEATURES_OK: Feature negotiation complete"),
14628b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_CONFIG_S_DRIVER, \
14728b629abSPhilippe Mathieu-Daudé             "VIRTIO_CONFIG_S_DRIVER: Guest OS compatible with device"),
14828b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_CONFIG_S_NEEDS_RESET, \
14928b629abSPhilippe Mathieu-Daudé             "VIRTIO_CONFIG_S_NEEDS_RESET: Irrecoverable error, device needs "
15028b629abSPhilippe Mathieu-Daudé             "reset"),
15128b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_CONFIG_S_FAILED, \
15228b629abSPhilippe Mathieu-Daudé             "VIRTIO_CONFIG_S_FAILED: Error in guest, device failed"),
15328b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_CONFIG_S_ACKNOWLEDGE, \
15428b629abSPhilippe Mathieu-Daudé             "VIRTIO_CONFIG_S_ACKNOWLEDGE: Valid virtio device found"),
15528b629abSPhilippe Mathieu-Daudé     { -1, "" }
15628b629abSPhilippe Mathieu-Daudé };
15728b629abSPhilippe Mathieu-Daudé 
15828b629abSPhilippe Mathieu-Daudé /* virtio-blk features mapping */
15928b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_BLK
16028b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_blk_feature_map[] = {
16128b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_BLK_F_SIZE_MAX, \
16228b629abSPhilippe Mathieu-Daudé             "VIRTIO_BLK_F_SIZE_MAX: Max segment size is size_max"),
16328b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_BLK_F_SEG_MAX, \
16428b629abSPhilippe Mathieu-Daudé             "VIRTIO_BLK_F_SEG_MAX: Max segments in a request is seg_max"),
16528b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_BLK_F_GEOMETRY, \
16628b629abSPhilippe Mathieu-Daudé             "VIRTIO_BLK_F_GEOMETRY: Legacy geometry available"),
16728b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_BLK_F_RO, \
16828b629abSPhilippe Mathieu-Daudé             "VIRTIO_BLK_F_RO: Device is read-only"),
16928b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_BLK_F_BLK_SIZE, \
17028b629abSPhilippe Mathieu-Daudé             "VIRTIO_BLK_F_BLK_SIZE: Block size of disk available"),
17128b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_BLK_F_TOPOLOGY, \
17228b629abSPhilippe Mathieu-Daudé             "VIRTIO_BLK_F_TOPOLOGY: Topology information available"),
17328b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_BLK_F_MQ, \
17428b629abSPhilippe Mathieu-Daudé             "VIRTIO_BLK_F_MQ: Multiqueue supported"),
17528b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_BLK_F_DISCARD, \
17628b629abSPhilippe Mathieu-Daudé             "VIRTIO_BLK_F_DISCARD: Discard command supported"),
17728b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_BLK_F_WRITE_ZEROES, \
17828b629abSPhilippe Mathieu-Daudé             "VIRTIO_BLK_F_WRITE_ZEROES: Write zeroes command supported"),
1794f736650SSam Li     FEATURE_ENTRY(VIRTIO_BLK_F_ZONED, \
1804f736650SSam Li             "VIRTIO_BLK_F_ZONED: Zoned block devices"),
18128b629abSPhilippe Mathieu-Daudé #ifndef VIRTIO_BLK_NO_LEGACY
18228b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_BLK_F_BARRIER, \
18328b629abSPhilippe Mathieu-Daudé             "VIRTIO_BLK_F_BARRIER: Request barriers supported"),
18428b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_BLK_F_SCSI, \
18528b629abSPhilippe Mathieu-Daudé             "VIRTIO_BLK_F_SCSI: SCSI packet commands supported"),
18628b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_BLK_F_FLUSH, \
18728b629abSPhilippe Mathieu-Daudé             "VIRTIO_BLK_F_FLUSH: Flush command supported"),
18828b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_BLK_F_CONFIG_WCE, \
18928b629abSPhilippe Mathieu-Daudé             "VIRTIO_BLK_F_CONFIG_WCE: Cache writeback and writethrough modes "
19028b629abSPhilippe Mathieu-Daudé             "supported"),
19128b629abSPhilippe Mathieu-Daudé #endif /* !VIRTIO_BLK_NO_LEGACY */
19228b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_F_LOG_ALL, \
19328b629abSPhilippe Mathieu-Daudé             "VHOST_F_LOG_ALL: Logging write descriptors supported"),
19428b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
19528b629abSPhilippe Mathieu-Daudé             "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
19628b629abSPhilippe Mathieu-Daudé             "negotiation supported"),
19728b629abSPhilippe Mathieu-Daudé     { -1, "" }
19828b629abSPhilippe Mathieu-Daudé };
19928b629abSPhilippe Mathieu-Daudé #endif
20028b629abSPhilippe Mathieu-Daudé 
20128b629abSPhilippe Mathieu-Daudé /* virtio-serial features mapping */
20228b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_SERIAL
20328b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_serial_feature_map[] = {
20428b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_CONSOLE_F_SIZE, \
20528b629abSPhilippe Mathieu-Daudé             "VIRTIO_CONSOLE_F_SIZE: Host providing console size"),
20628b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_CONSOLE_F_MULTIPORT, \
20728b629abSPhilippe Mathieu-Daudé             "VIRTIO_CONSOLE_F_MULTIPORT: Multiple ports for device supported"),
20828b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_CONSOLE_F_EMERG_WRITE, \
20928b629abSPhilippe Mathieu-Daudé             "VIRTIO_CONSOLE_F_EMERG_WRITE: Emergency write supported"),
21028b629abSPhilippe Mathieu-Daudé     { -1, "" }
21128b629abSPhilippe Mathieu-Daudé };
21228b629abSPhilippe Mathieu-Daudé #endif
21328b629abSPhilippe Mathieu-Daudé 
21428b629abSPhilippe Mathieu-Daudé /* virtio-gpu features mapping */
21528b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_GPU
21628b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_gpu_feature_map[] = {
21728b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_GPU_F_VIRGL, \
21828b629abSPhilippe Mathieu-Daudé             "VIRTIO_GPU_F_VIRGL: Virgl 3D mode supported"),
21928b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_GPU_F_EDID, \
22028b629abSPhilippe Mathieu-Daudé             "VIRTIO_GPU_F_EDID: EDID metadata supported"),
22128b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_GPU_F_RESOURCE_UUID, \
22228b629abSPhilippe Mathieu-Daudé             "VIRTIO_GPU_F_RESOURCE_UUID: Resource UUID assigning supported"),
22328b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_GPU_F_RESOURCE_BLOB, \
22428b629abSPhilippe Mathieu-Daudé             "VIRTIO_GPU_F_RESOURCE_BLOB: Size-based blob resources supported"),
22528b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_GPU_F_CONTEXT_INIT, \
22628b629abSPhilippe Mathieu-Daudé             "VIRTIO_GPU_F_CONTEXT_INIT: Context types and synchronization "
22728b629abSPhilippe Mathieu-Daudé             "timelines supported"),
22828b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_F_LOG_ALL, \
22928b629abSPhilippe Mathieu-Daudé             "VHOST_F_LOG_ALL: Logging write descriptors supported"),
23028b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
23128b629abSPhilippe Mathieu-Daudé             "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
23228b629abSPhilippe Mathieu-Daudé             "negotiation supported"),
23328b629abSPhilippe Mathieu-Daudé     { -1, "" }
23428b629abSPhilippe Mathieu-Daudé };
23528b629abSPhilippe Mathieu-Daudé #endif
23628b629abSPhilippe Mathieu-Daudé 
23728b629abSPhilippe Mathieu-Daudé /* virtio-input features mapping */
23828b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_INPUT
23928b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_input_feature_map[] = {
24028b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_F_LOG_ALL, \
24128b629abSPhilippe Mathieu-Daudé             "VHOST_F_LOG_ALL: Logging write descriptors supported"),
24228b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
24328b629abSPhilippe Mathieu-Daudé             "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
24428b629abSPhilippe Mathieu-Daudé             "negotiation supported"),
24528b629abSPhilippe Mathieu-Daudé     { -1, "" }
24628b629abSPhilippe Mathieu-Daudé };
24728b629abSPhilippe Mathieu-Daudé #endif
24828b629abSPhilippe Mathieu-Daudé 
24928b629abSPhilippe Mathieu-Daudé /* virtio-net features mapping */
25028b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_NET
25128b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_net_feature_map[] = {
25228b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_CSUM, \
25328b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_CSUM: Device handling packets with partial checksum "
25428b629abSPhilippe Mathieu-Daudé             "supported"),
25528b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_GUEST_CSUM, \
25628b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_GUEST_CSUM: Driver handling packets with partial "
25728b629abSPhilippe Mathieu-Daudé             "checksum supported"),
25828b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_CTRL_GUEST_OFFLOADS, \
25928b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_CTRL_GUEST_OFFLOADS: Control channel offloading "
26028b629abSPhilippe Mathieu-Daudé             "reconfig. supported"),
26128b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_MTU, \
26228b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_MTU: Device max MTU reporting supported"),
26328b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_MAC, \
26428b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_MAC: Device has given MAC address"),
26528b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_GUEST_TSO4, \
26628b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_GUEST_TSO4: Driver can receive TSOv4"),
26728b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_GUEST_TSO6, \
26828b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_GUEST_TSO6: Driver can receive TSOv6"),
26928b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_GUEST_ECN, \
27028b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_GUEST_ECN: Driver can receive TSO with ECN"),
27128b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_GUEST_UFO, \
27228b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_GUEST_UFO: Driver can receive UFO"),
27328b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_HOST_TSO4, \
27428b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_HOST_TSO4: Device can receive TSOv4"),
27528b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_HOST_TSO6, \
27628b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_HOST_TSO6: Device can receive TSOv6"),
27728b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_HOST_ECN, \
27828b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_HOST_ECN: Device can receive TSO with ECN"),
27928b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_HOST_UFO, \
28028b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_HOST_UFO: Device can receive UFO"),
28128b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_MRG_RXBUF, \
28228b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_MRG_RXBUF: Driver can merge receive buffers"),
28328b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_STATUS, \
28428b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_STATUS: Configuration status field available"),
28528b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_CTRL_VQ, \
28628b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_CTRL_VQ: Control channel available"),
28728b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_CTRL_RX, \
28828b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_CTRL_RX: Control channel RX mode supported"),
28928b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_CTRL_VLAN, \
29028b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_CTRL_VLAN: Control channel VLAN filtering supported"),
29128b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_CTRL_RX_EXTRA, \
29228b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_CTRL_RX_EXTRA: Extra RX mode control supported"),
29328b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_GUEST_ANNOUNCE, \
29428b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_GUEST_ANNOUNCE: Driver sending gratuitous packets "
29528b629abSPhilippe Mathieu-Daudé             "supported"),
29628b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_MQ, \
29728b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_MQ: Multiqueue with automatic receive steering "
29828b629abSPhilippe Mathieu-Daudé             "supported"),
29928b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_CTRL_MAC_ADDR, \
30028b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_CTRL_MAC_ADDR: MAC address set through control "
30128b629abSPhilippe Mathieu-Daudé             "channel"),
30228b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_HASH_REPORT, \
30328b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_HASH_REPORT: Hash reporting supported"),
30428b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_RSS, \
30528b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_RSS: RSS RX steering supported"),
30628b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_RSC_EXT, \
30728b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_RSC_EXT: Extended coalescing info supported"),
30828b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_STANDBY, \
30928b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_STANDBY: Device acting as standby for primary "
31028b629abSPhilippe Mathieu-Daudé             "device with same MAC addr. supported"),
31128b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_SPEED_DUPLEX, \
31228b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_SPEED_DUPLEX: Device set linkspeed and duplex"),
31328b629abSPhilippe Mathieu-Daudé #ifndef VIRTIO_NET_NO_LEGACY
31428b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_GSO, \
31528b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_GSO: Handling GSO-type packets supported"),
31628b629abSPhilippe Mathieu-Daudé #endif /* !VIRTIO_NET_NO_LEGACY */
31728b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_NET_F_VIRTIO_NET_HDR, \
31828b629abSPhilippe Mathieu-Daudé             "VHOST_NET_F_VIRTIO_NET_HDR: Virtio-net headers for RX and TX "
31928b629abSPhilippe Mathieu-Daudé             "packets supported"),
32028b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_F_LOG_ALL, \
32128b629abSPhilippe Mathieu-Daudé             "VHOST_F_LOG_ALL: Logging write descriptors supported"),
32228b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
32328b629abSPhilippe Mathieu-Daudé             "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
32428b629abSPhilippe Mathieu-Daudé             "negotiation supported"),
32528b629abSPhilippe Mathieu-Daudé     { -1, "" }
32628b629abSPhilippe Mathieu-Daudé };
32728b629abSPhilippe Mathieu-Daudé #endif
32828b629abSPhilippe Mathieu-Daudé 
32928b629abSPhilippe Mathieu-Daudé /* virtio-scsi features mapping */
33028b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_SCSI
33128b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_scsi_feature_map[] = {
33228b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_SCSI_F_INOUT, \
33328b629abSPhilippe Mathieu-Daudé             "VIRTIO_SCSI_F_INOUT: Requests including read and writable data "
33446e75a77SMichael Tokarev             "buffers supported"),
33528b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_SCSI_F_HOTPLUG, \
33628b629abSPhilippe Mathieu-Daudé             "VIRTIO_SCSI_F_HOTPLUG: Reporting and handling hot-plug events "
33728b629abSPhilippe Mathieu-Daudé             "supported"),
33828b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_SCSI_F_CHANGE, \
33928b629abSPhilippe Mathieu-Daudé             "VIRTIO_SCSI_F_CHANGE: Reporting and handling LUN changes "
34028b629abSPhilippe Mathieu-Daudé             "supported"),
34128b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_SCSI_F_T10_PI, \
34228b629abSPhilippe Mathieu-Daudé             "VIRTIO_SCSI_F_T10_PI: T10 info included in request header"),
34328b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_F_LOG_ALL, \
34428b629abSPhilippe Mathieu-Daudé             "VHOST_F_LOG_ALL: Logging write descriptors supported"),
34528b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
34628b629abSPhilippe Mathieu-Daudé             "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
34728b629abSPhilippe Mathieu-Daudé             "negotiation supported"),
34828b629abSPhilippe Mathieu-Daudé     { -1, "" }
34928b629abSPhilippe Mathieu-Daudé };
35028b629abSPhilippe Mathieu-Daudé #endif
35128b629abSPhilippe Mathieu-Daudé 
35228b629abSPhilippe Mathieu-Daudé /* virtio/vhost-user-fs features mapping */
35328b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VHOST_USER_FS
35428b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_fs_feature_map[] = {
35528b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_F_LOG_ALL, \
35628b629abSPhilippe Mathieu-Daudé             "VHOST_F_LOG_ALL: Logging write descriptors supported"),
35728b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
35828b629abSPhilippe Mathieu-Daudé             "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
35928b629abSPhilippe Mathieu-Daudé             "negotiation supported"),
36028b629abSPhilippe Mathieu-Daudé     { -1, "" }
36128b629abSPhilippe Mathieu-Daudé };
36228b629abSPhilippe Mathieu-Daudé #endif
36328b629abSPhilippe Mathieu-Daudé 
36428b629abSPhilippe Mathieu-Daudé /* virtio/vhost-user-i2c features mapping */
36528b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_I2C_ADAPTER
36628b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_i2c_feature_map[] = {
36728b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_I2C_F_ZERO_LENGTH_REQUEST, \
36828b629abSPhilippe Mathieu-Daudé             "VIRTIO_I2C_F_ZERO_LEGNTH_REQUEST: Zero length requests supported"),
36928b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_F_LOG_ALL, \
37028b629abSPhilippe Mathieu-Daudé             "VHOST_F_LOG_ALL: Logging write descriptors supported"),
37128b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
37228b629abSPhilippe Mathieu-Daudé             "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
37328b629abSPhilippe Mathieu-Daudé             "negotiation supported"),
37428b629abSPhilippe Mathieu-Daudé     { -1, "" }
37528b629abSPhilippe Mathieu-Daudé };
37628b629abSPhilippe Mathieu-Daudé #endif
37728b629abSPhilippe Mathieu-Daudé 
37828b629abSPhilippe Mathieu-Daudé /* virtio/vhost-vsock features mapping */
37928b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VHOST_VSOCK
38028b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_vsock_feature_map[] = {
38128b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_VSOCK_F_SEQPACKET, \
38228b629abSPhilippe Mathieu-Daudé             "VIRTIO_VSOCK_F_SEQPACKET: SOCK_SEQPACKET supported"),
38328b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_F_LOG_ALL, \
38428b629abSPhilippe Mathieu-Daudé             "VHOST_F_LOG_ALL: Logging write descriptors supported"),
38528b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
38628b629abSPhilippe Mathieu-Daudé             "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
38728b629abSPhilippe Mathieu-Daudé             "negotiation supported"),
38828b629abSPhilippe Mathieu-Daudé     { -1, "" }
38928b629abSPhilippe Mathieu-Daudé };
39028b629abSPhilippe Mathieu-Daudé #endif
39128b629abSPhilippe Mathieu-Daudé 
39228b629abSPhilippe Mathieu-Daudé /* virtio-balloon features mapping */
39328b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_BALLOON
39428b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_balloon_feature_map[] = {
39528b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_BALLOON_F_MUST_TELL_HOST, \
39628b629abSPhilippe Mathieu-Daudé             "VIRTIO_BALLOON_F_MUST_TELL_HOST: Tell host before reclaiming "
39728b629abSPhilippe Mathieu-Daudé             "pages"),
39828b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_BALLOON_F_STATS_VQ, \
39928b629abSPhilippe Mathieu-Daudé             "VIRTIO_BALLOON_F_STATS_VQ: Guest memory stats VQ available"),
40028b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_BALLOON_F_DEFLATE_ON_OOM, \
40128b629abSPhilippe Mathieu-Daudé             "VIRTIO_BALLOON_F_DEFLATE_ON_OOM: Deflate balloon when guest OOM"),
40228b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_BALLOON_F_FREE_PAGE_HINT, \
40328b629abSPhilippe Mathieu-Daudé             "VIRTIO_BALLOON_F_FREE_PAGE_HINT: VQ reporting free pages enabled"),
40428b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_BALLOON_F_PAGE_POISON, \
40528b629abSPhilippe Mathieu-Daudé             "VIRTIO_BALLOON_F_PAGE_POISON: Guest page poisoning enabled"),
40628b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_BALLOON_F_REPORTING, \
40728b629abSPhilippe Mathieu-Daudé             "VIRTIO_BALLOON_F_REPORTING: Page reporting VQ enabled"),
40828b629abSPhilippe Mathieu-Daudé     { -1, "" }
40928b629abSPhilippe Mathieu-Daudé };
41028b629abSPhilippe Mathieu-Daudé #endif
41128b629abSPhilippe Mathieu-Daudé 
41228b629abSPhilippe Mathieu-Daudé /* virtio-crypto features mapping */
41328b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_CRYPTO
41428b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_crypto_feature_map[] = {
41528b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_F_LOG_ALL, \
41628b629abSPhilippe Mathieu-Daudé             "VHOST_F_LOG_ALL: Logging write descriptors supported"),
41728b629abSPhilippe Mathieu-Daudé     { -1, "" }
41828b629abSPhilippe Mathieu-Daudé };
41928b629abSPhilippe Mathieu-Daudé #endif
42028b629abSPhilippe Mathieu-Daudé 
42128b629abSPhilippe Mathieu-Daudé /* virtio-iommu features mapping */
42228b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_IOMMU
42328b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_iommu_feature_map[] = {
42428b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_IOMMU_F_INPUT_RANGE, \
42528b629abSPhilippe Mathieu-Daudé             "VIRTIO_IOMMU_F_INPUT_RANGE: Range of available virtual addrs. "
42628b629abSPhilippe Mathieu-Daudé             "available"),
42728b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_IOMMU_F_DOMAIN_RANGE, \
42828b629abSPhilippe Mathieu-Daudé             "VIRTIO_IOMMU_F_DOMAIN_RANGE: Number of supported domains "
42928b629abSPhilippe Mathieu-Daudé             "available"),
43028b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_IOMMU_F_MAP_UNMAP, \
43128b629abSPhilippe Mathieu-Daudé             "VIRTIO_IOMMU_F_MAP_UNMAP: Map and unmap requests available"),
43228b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_IOMMU_F_BYPASS, \
43328b629abSPhilippe Mathieu-Daudé             "VIRTIO_IOMMU_F_BYPASS: Endpoints not attached to domains are in "
43428b629abSPhilippe Mathieu-Daudé             "bypass mode"),
43528b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_IOMMU_F_PROBE, \
43628b629abSPhilippe Mathieu-Daudé             "VIRTIO_IOMMU_F_PROBE: Probe requests available"),
43728b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_IOMMU_F_MMIO, \
43828b629abSPhilippe Mathieu-Daudé             "VIRTIO_IOMMU_F_MMIO: VIRTIO_IOMMU_MAP_F_MMIO flag available"),
43928b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_IOMMU_F_BYPASS_CONFIG, \
44028b629abSPhilippe Mathieu-Daudé             "VIRTIO_IOMMU_F_BYPASS_CONFIG: Bypass field of IOMMU config "
44128b629abSPhilippe Mathieu-Daudé             "available"),
44228b629abSPhilippe Mathieu-Daudé     { -1, "" }
44328b629abSPhilippe Mathieu-Daudé };
44428b629abSPhilippe Mathieu-Daudé #endif
44528b629abSPhilippe Mathieu-Daudé 
44628b629abSPhilippe Mathieu-Daudé /* virtio-mem features mapping */
44728b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_MEM
44828b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_mem_feature_map[] = {
44928b629abSPhilippe Mathieu-Daudé #ifndef CONFIG_ACPI
45028b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_MEM_F_ACPI_PXM, \
45128b629abSPhilippe Mathieu-Daudé             "VIRTIO_MEM_F_ACPI_PXM: node_id is an ACPI PXM and is valid"),
45228b629abSPhilippe Mathieu-Daudé #endif /* !CONFIG_ACPI */
45328b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE, \
45428b629abSPhilippe Mathieu-Daudé             "VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE: Unplugged memory cannot be "
45528b629abSPhilippe Mathieu-Daudé             "accessed"),
45628b629abSPhilippe Mathieu-Daudé     { -1, "" }
45728b629abSPhilippe Mathieu-Daudé };
45828b629abSPhilippe Mathieu-Daudé #endif
45928b629abSPhilippe Mathieu-Daudé 
46028b629abSPhilippe Mathieu-Daudé /* virtio-rng features mapping */
46128b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_RNG
46228b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_rng_feature_map[] = {
46328b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_F_LOG_ALL, \
46428b629abSPhilippe Mathieu-Daudé             "VHOST_F_LOG_ALL: Logging write descriptors supported"),
46528b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
46628b629abSPhilippe Mathieu-Daudé             "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
46728b629abSPhilippe Mathieu-Daudé             "negotiation supported"),
46828b629abSPhilippe Mathieu-Daudé     { -1, "" }
46928b629abSPhilippe Mathieu-Daudé };
47028b629abSPhilippe Mathieu-Daudé #endif
47128b629abSPhilippe Mathieu-Daudé 
47228b629abSPhilippe Mathieu-Daudé #define CONVERT_FEATURES(type, map, is_status, bitmap)   \
47328b629abSPhilippe Mathieu-Daudé     ({                                                   \
47428b629abSPhilippe Mathieu-Daudé         type *list = NULL;                               \
47528b629abSPhilippe Mathieu-Daudé         type *node;                                      \
47628b629abSPhilippe Mathieu-Daudé         for (i = 0; map[i].virtio_bit != -1; i++) {      \
47728b629abSPhilippe Mathieu-Daudé             if (is_status) {                             \
47828b629abSPhilippe Mathieu-Daudé                 bit = map[i].virtio_bit;                 \
47928b629abSPhilippe Mathieu-Daudé             }                                            \
48028b629abSPhilippe Mathieu-Daudé             else {                                       \
48128b629abSPhilippe Mathieu-Daudé                 bit = 1ULL << map[i].virtio_bit;         \
48228b629abSPhilippe Mathieu-Daudé             }                                            \
48328b629abSPhilippe Mathieu-Daudé             if ((bitmap & bit) == 0) {                   \
48428b629abSPhilippe Mathieu-Daudé                 continue;                                \
48528b629abSPhilippe Mathieu-Daudé             }                                            \
48628b629abSPhilippe Mathieu-Daudé             node = g_new0(type, 1);                      \
48728b629abSPhilippe Mathieu-Daudé             node->value = g_strdup(map[i].feature_desc); \
48828b629abSPhilippe Mathieu-Daudé             node->next = list;                           \
48928b629abSPhilippe Mathieu-Daudé             list = node;                                 \
49028b629abSPhilippe Mathieu-Daudé             bitmap ^= bit;                               \
49128b629abSPhilippe Mathieu-Daudé         }                                                \
49228b629abSPhilippe Mathieu-Daudé         list;                                            \
49328b629abSPhilippe Mathieu-Daudé     })
49428b629abSPhilippe Mathieu-Daudé 
49528b629abSPhilippe Mathieu-Daudé VirtioDeviceStatus *qmp_decode_status(uint8_t bitmap)
49628b629abSPhilippe Mathieu-Daudé {
49728b629abSPhilippe Mathieu-Daudé     VirtioDeviceStatus *status;
49828b629abSPhilippe Mathieu-Daudé     uint8_t bit;
49928b629abSPhilippe Mathieu-Daudé     int i;
50028b629abSPhilippe Mathieu-Daudé 
50128b629abSPhilippe Mathieu-Daudé     status = g_new0(VirtioDeviceStatus, 1);
50228b629abSPhilippe Mathieu-Daudé     status->statuses = CONVERT_FEATURES(strList, virtio_config_status_map,
50328b629abSPhilippe Mathieu-Daudé                                         1, bitmap);
50428b629abSPhilippe Mathieu-Daudé     status->has_unknown_statuses = bitmap != 0;
50528b629abSPhilippe Mathieu-Daudé     if (status->has_unknown_statuses) {
50628b629abSPhilippe Mathieu-Daudé         status->unknown_statuses = bitmap;
50728b629abSPhilippe Mathieu-Daudé     }
50828b629abSPhilippe Mathieu-Daudé 
50928b629abSPhilippe Mathieu-Daudé     return status;
51028b629abSPhilippe Mathieu-Daudé }
51128b629abSPhilippe Mathieu-Daudé 
51228b629abSPhilippe Mathieu-Daudé VhostDeviceProtocols *qmp_decode_protocols(uint64_t bitmap)
51328b629abSPhilippe Mathieu-Daudé {
51428b629abSPhilippe Mathieu-Daudé     VhostDeviceProtocols *vhu_protocols;
51528b629abSPhilippe Mathieu-Daudé     uint64_t bit;
51628b629abSPhilippe Mathieu-Daudé     int i;
51728b629abSPhilippe Mathieu-Daudé 
51828b629abSPhilippe Mathieu-Daudé     vhu_protocols = g_new0(VhostDeviceProtocols, 1);
51928b629abSPhilippe Mathieu-Daudé     vhu_protocols->protocols =
52028b629abSPhilippe Mathieu-Daudé                     CONVERT_FEATURES(strList,
52128b629abSPhilippe Mathieu-Daudé                                      vhost_user_protocol_map, 0, bitmap);
52228b629abSPhilippe Mathieu-Daudé     vhu_protocols->has_unknown_protocols = bitmap != 0;
52328b629abSPhilippe Mathieu-Daudé     if (vhu_protocols->has_unknown_protocols) {
52428b629abSPhilippe Mathieu-Daudé         vhu_protocols->unknown_protocols = bitmap;
52528b629abSPhilippe Mathieu-Daudé     }
52628b629abSPhilippe Mathieu-Daudé 
52728b629abSPhilippe Mathieu-Daudé     return vhu_protocols;
52828b629abSPhilippe Mathieu-Daudé }
52928b629abSPhilippe Mathieu-Daudé 
53028b629abSPhilippe Mathieu-Daudé VirtioDeviceFeatures *qmp_decode_features(uint16_t device_id, uint64_t bitmap)
53128b629abSPhilippe Mathieu-Daudé {
53228b629abSPhilippe Mathieu-Daudé     VirtioDeviceFeatures *features;
53328b629abSPhilippe Mathieu-Daudé     uint64_t bit;
53428b629abSPhilippe Mathieu-Daudé     int i;
53528b629abSPhilippe Mathieu-Daudé 
53628b629abSPhilippe Mathieu-Daudé     features = g_new0(VirtioDeviceFeatures, 1);
53728b629abSPhilippe Mathieu-Daudé     features->has_dev_features = true;
53828b629abSPhilippe Mathieu-Daudé 
53928b629abSPhilippe Mathieu-Daudé     /* transport features */
54028b629abSPhilippe Mathieu-Daudé     features->transports = CONVERT_FEATURES(strList, virtio_transport_map, 0,
54128b629abSPhilippe Mathieu-Daudé                                             bitmap);
54228b629abSPhilippe Mathieu-Daudé 
54328b629abSPhilippe Mathieu-Daudé     /* device features */
54428b629abSPhilippe Mathieu-Daudé     switch (device_id) {
54528b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_SERIAL
54628b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_CONSOLE:
54728b629abSPhilippe Mathieu-Daudé         features->dev_features =
54828b629abSPhilippe Mathieu-Daudé             CONVERT_FEATURES(strList, virtio_serial_feature_map, 0, bitmap);
54928b629abSPhilippe Mathieu-Daudé         break;
55028b629abSPhilippe Mathieu-Daudé #endif
55128b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_BLK
55228b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_BLOCK:
55328b629abSPhilippe Mathieu-Daudé         features->dev_features =
55428b629abSPhilippe Mathieu-Daudé             CONVERT_FEATURES(strList, virtio_blk_feature_map, 0, bitmap);
55528b629abSPhilippe Mathieu-Daudé         break;
55628b629abSPhilippe Mathieu-Daudé #endif
55728b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_GPU
55828b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_GPU:
55928b629abSPhilippe Mathieu-Daudé         features->dev_features =
56028b629abSPhilippe Mathieu-Daudé             CONVERT_FEATURES(strList, virtio_gpu_feature_map, 0, bitmap);
56128b629abSPhilippe Mathieu-Daudé         break;
56228b629abSPhilippe Mathieu-Daudé #endif
56328b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_NET
56428b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_NET:
56528b629abSPhilippe Mathieu-Daudé         features->dev_features =
56628b629abSPhilippe Mathieu-Daudé             CONVERT_FEATURES(strList, virtio_net_feature_map, 0, bitmap);
56728b629abSPhilippe Mathieu-Daudé         break;
56828b629abSPhilippe Mathieu-Daudé #endif
56928b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_SCSI
57028b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_SCSI:
57128b629abSPhilippe Mathieu-Daudé         features->dev_features =
57228b629abSPhilippe Mathieu-Daudé             CONVERT_FEATURES(strList, virtio_scsi_feature_map, 0, bitmap);
57328b629abSPhilippe Mathieu-Daudé         break;
57428b629abSPhilippe Mathieu-Daudé #endif
57528b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_BALLOON
57628b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_BALLOON:
57728b629abSPhilippe Mathieu-Daudé         features->dev_features =
57828b629abSPhilippe Mathieu-Daudé             CONVERT_FEATURES(strList, virtio_balloon_feature_map, 0, bitmap);
57928b629abSPhilippe Mathieu-Daudé         break;
58028b629abSPhilippe Mathieu-Daudé #endif
58128b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_IOMMU
58228b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_IOMMU:
58328b629abSPhilippe Mathieu-Daudé         features->dev_features =
58428b629abSPhilippe Mathieu-Daudé             CONVERT_FEATURES(strList, virtio_iommu_feature_map, 0, bitmap);
58528b629abSPhilippe Mathieu-Daudé         break;
58628b629abSPhilippe Mathieu-Daudé #endif
58728b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_INPUT
58828b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_INPUT:
58928b629abSPhilippe Mathieu-Daudé         features->dev_features =
59028b629abSPhilippe Mathieu-Daudé             CONVERT_FEATURES(strList, virtio_input_feature_map, 0, bitmap);
59128b629abSPhilippe Mathieu-Daudé         break;
59228b629abSPhilippe Mathieu-Daudé #endif
59328b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VHOST_USER_FS
59428b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_FS:
59528b629abSPhilippe Mathieu-Daudé         features->dev_features =
59628b629abSPhilippe Mathieu-Daudé             CONVERT_FEATURES(strList, virtio_fs_feature_map, 0, bitmap);
59728b629abSPhilippe Mathieu-Daudé         break;
59828b629abSPhilippe Mathieu-Daudé #endif
59928b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VHOST_VSOCK
60028b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_VSOCK:
60128b629abSPhilippe Mathieu-Daudé         features->dev_features =
60228b629abSPhilippe Mathieu-Daudé             CONVERT_FEATURES(strList, virtio_vsock_feature_map, 0, bitmap);
60328b629abSPhilippe Mathieu-Daudé         break;
60428b629abSPhilippe Mathieu-Daudé #endif
60528b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_CRYPTO
60628b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_CRYPTO:
60728b629abSPhilippe Mathieu-Daudé         features->dev_features =
60828b629abSPhilippe Mathieu-Daudé             CONVERT_FEATURES(strList, virtio_crypto_feature_map, 0, bitmap);
60928b629abSPhilippe Mathieu-Daudé         break;
61028b629abSPhilippe Mathieu-Daudé #endif
61128b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_MEM
61228b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_MEM:
61328b629abSPhilippe Mathieu-Daudé         features->dev_features =
61428b629abSPhilippe Mathieu-Daudé             CONVERT_FEATURES(strList, virtio_mem_feature_map, 0, bitmap);
61528b629abSPhilippe Mathieu-Daudé         break;
61628b629abSPhilippe Mathieu-Daudé #endif
61728b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_I2C_ADAPTER
61828b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_I2C_ADAPTER:
61928b629abSPhilippe Mathieu-Daudé         features->dev_features =
62028b629abSPhilippe Mathieu-Daudé             CONVERT_FEATURES(strList, virtio_i2c_feature_map, 0, bitmap);
62128b629abSPhilippe Mathieu-Daudé         break;
62228b629abSPhilippe Mathieu-Daudé #endif
62328b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_RNG
62428b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_RNG:
62528b629abSPhilippe Mathieu-Daudé         features->dev_features =
62628b629abSPhilippe Mathieu-Daudé             CONVERT_FEATURES(strList, virtio_rng_feature_map, 0, bitmap);
62728b629abSPhilippe Mathieu-Daudé         break;
62828b629abSPhilippe Mathieu-Daudé #endif
62928b629abSPhilippe Mathieu-Daudé     /* No features */
63028b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_9P:
63128b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_PMEM:
63228b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_IOMEM:
63328b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_RPMSG:
63428b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_CLOCK:
63528b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_MAC80211_WLAN:
63628b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_MAC80211_HWSIM:
63728b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_RPROC_SERIAL:
63828b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_MEMORY_BALLOON:
63928b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_CAIF:
64028b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_SIGNAL_DIST:
64128b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_PSTORE:
64228b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_SOUND:
64328b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_BT:
64428b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_RPMB:
64528b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_VIDEO_ENCODER:
64628b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_VIDEO_DECODER:
64728b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_SCMI:
64828b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_NITRO_SEC_MOD:
64928b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_WATCHDOG:
65028b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_CAN:
65128b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_DMABUF:
65228b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_PARAM_SERV:
65328b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_AUDIO_POLICY:
65428b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_GPIO:
65528b629abSPhilippe Mathieu-Daudé         break;
65628b629abSPhilippe Mathieu-Daudé     default:
65728b629abSPhilippe Mathieu-Daudé         g_assert_not_reached();
65828b629abSPhilippe Mathieu-Daudé     }
65928b629abSPhilippe Mathieu-Daudé 
66028b629abSPhilippe Mathieu-Daudé     features->has_unknown_dev_features = bitmap != 0;
66128b629abSPhilippe Mathieu-Daudé     if (features->has_unknown_dev_features) {
66228b629abSPhilippe Mathieu-Daudé         features->unknown_dev_features = bitmap;
66328b629abSPhilippe Mathieu-Daudé     }
66428b629abSPhilippe Mathieu-Daudé 
66528b629abSPhilippe Mathieu-Daudé     return features;
66628b629abSPhilippe Mathieu-Daudé }
6679d94c213SPhilippe Mathieu-Daudé 
6689d94c213SPhilippe Mathieu-Daudé VirtioInfoList *qmp_x_query_virtio(Error **errp)
6699d94c213SPhilippe Mathieu-Daudé {
6709d94c213SPhilippe Mathieu-Daudé     VirtioInfoList *list = NULL;
6710bfd1414SPaolo Bonzini     VirtioInfo *node;
6729d94c213SPhilippe Mathieu-Daudé     VirtIODevice *vdev;
6739d94c213SPhilippe Mathieu-Daudé 
6749d94c213SPhilippe Mathieu-Daudé     QTAILQ_FOREACH(vdev, &virtio_list, next) {
6759d94c213SPhilippe Mathieu-Daudé         DeviceState *dev = DEVICE(vdev);
6769d94c213SPhilippe Mathieu-Daudé         Error *err = NULL;
6779d94c213SPhilippe Mathieu-Daudé         QObject *obj = qmp_qom_get(dev->canonical_path, "realized", &err);
6789d94c213SPhilippe Mathieu-Daudé 
6799d94c213SPhilippe Mathieu-Daudé         if (err == NULL) {
6809d94c213SPhilippe Mathieu-Daudé             GString *is_realized = qobject_to_json_pretty(obj, true);
6819d94c213SPhilippe Mathieu-Daudé             /* virtio device is NOT realized, remove it from list */
6829d94c213SPhilippe Mathieu-Daudé             if (!strncmp(is_realized->str, "false", 4)) {
6839d94c213SPhilippe Mathieu-Daudé                 QTAILQ_REMOVE(&virtio_list, vdev, next);
6849d94c213SPhilippe Mathieu-Daudé             } else {
6850bfd1414SPaolo Bonzini                 node = g_new(VirtioInfo, 1);
6860bfd1414SPaolo Bonzini                 node->path = g_strdup(dev->canonical_path);
6870bfd1414SPaolo Bonzini                 node->name = g_strdup(vdev->name);
6880bfd1414SPaolo Bonzini                 QAPI_LIST_PREPEND(list, node);
6899d94c213SPhilippe Mathieu-Daudé             }
6909d94c213SPhilippe Mathieu-Daudé            g_string_free(is_realized, true);
6919d94c213SPhilippe Mathieu-Daudé         }
6929d94c213SPhilippe Mathieu-Daudé         qobject_unref(obj);
6939d94c213SPhilippe Mathieu-Daudé     }
6949d94c213SPhilippe Mathieu-Daudé 
6959d94c213SPhilippe Mathieu-Daudé     return list;
6969d94c213SPhilippe Mathieu-Daudé }
6979d94c213SPhilippe Mathieu-Daudé 
6989d94c213SPhilippe Mathieu-Daudé VirtIODevice *qmp_find_virtio_device(const char *path)
6999d94c213SPhilippe Mathieu-Daudé {
7009d94c213SPhilippe Mathieu-Daudé     VirtIODevice *vdev;
7019d94c213SPhilippe Mathieu-Daudé 
7029d94c213SPhilippe Mathieu-Daudé     QTAILQ_FOREACH(vdev, &virtio_list, next) {
7039d94c213SPhilippe Mathieu-Daudé         DeviceState *dev = DEVICE(vdev);
7049d94c213SPhilippe Mathieu-Daudé 
7059d94c213SPhilippe Mathieu-Daudé         if (strcmp(dev->canonical_path, path) != 0) {
7069d94c213SPhilippe Mathieu-Daudé             continue;
7079d94c213SPhilippe Mathieu-Daudé         }
7089d94c213SPhilippe Mathieu-Daudé 
7099d94c213SPhilippe Mathieu-Daudé         Error *err = NULL;
7109d94c213SPhilippe Mathieu-Daudé         QObject *obj = qmp_qom_get(dev->canonical_path, "realized", &err);
7119d94c213SPhilippe Mathieu-Daudé         if (err == NULL) {
7129d94c213SPhilippe Mathieu-Daudé             GString *is_realized = qobject_to_json_pretty(obj, true);
7139d94c213SPhilippe Mathieu-Daudé             /* virtio device is NOT realized, remove it from list */
7149d94c213SPhilippe Mathieu-Daudé             if (!strncmp(is_realized->str, "false", 4)) {
7159d94c213SPhilippe Mathieu-Daudé                 g_string_free(is_realized, true);
7169d94c213SPhilippe Mathieu-Daudé                 qobject_unref(obj);
7179d94c213SPhilippe Mathieu-Daudé                 QTAILQ_REMOVE(&virtio_list, vdev, next);
7189d94c213SPhilippe Mathieu-Daudé                 return NULL;
7199d94c213SPhilippe Mathieu-Daudé             }
7209d94c213SPhilippe Mathieu-Daudé             g_string_free(is_realized, true);
7219d94c213SPhilippe Mathieu-Daudé         } else {
7229d94c213SPhilippe Mathieu-Daudé             /* virtio device doesn't exist in QOM tree */
7239d94c213SPhilippe Mathieu-Daudé             QTAILQ_REMOVE(&virtio_list, vdev, next);
7249d94c213SPhilippe Mathieu-Daudé             qobject_unref(obj);
7259d94c213SPhilippe Mathieu-Daudé             return NULL;
7269d94c213SPhilippe Mathieu-Daudé         }
7279d94c213SPhilippe Mathieu-Daudé         /* device exists in QOM tree & is realized */
7289d94c213SPhilippe Mathieu-Daudé         qobject_unref(obj);
7299d94c213SPhilippe Mathieu-Daudé         return vdev;
7309d94c213SPhilippe Mathieu-Daudé     }
7319d94c213SPhilippe Mathieu-Daudé     return NULL;
7329d94c213SPhilippe Mathieu-Daudé }
7339d94c213SPhilippe Mathieu-Daudé 
7349d94c213SPhilippe Mathieu-Daudé VirtioStatus *qmp_x_query_virtio_status(const char *path, Error **errp)
7359d94c213SPhilippe Mathieu-Daudé {
7369d94c213SPhilippe Mathieu-Daudé     VirtIODevice *vdev;
7379d94c213SPhilippe Mathieu-Daudé     VirtioStatus *status;
7389d94c213SPhilippe Mathieu-Daudé 
7399d94c213SPhilippe Mathieu-Daudé     vdev = qmp_find_virtio_device(path);
7409d94c213SPhilippe Mathieu-Daudé     if (vdev == NULL) {
7419d94c213SPhilippe Mathieu-Daudé         error_setg(errp, "Path %s is not a VirtIODevice", path);
7429d94c213SPhilippe Mathieu-Daudé         return NULL;
7439d94c213SPhilippe Mathieu-Daudé     }
7449d94c213SPhilippe Mathieu-Daudé 
7459d94c213SPhilippe Mathieu-Daudé     status = g_new0(VirtioStatus, 1);
7469d94c213SPhilippe Mathieu-Daudé     status->name = g_strdup(vdev->name);
7479d94c213SPhilippe Mathieu-Daudé     status->device_id = vdev->device_id;
7489d94c213SPhilippe Mathieu-Daudé     status->vhost_started = vdev->vhost_started;
7499d94c213SPhilippe Mathieu-Daudé     status->guest_features = qmp_decode_features(vdev->device_id,
7509d94c213SPhilippe Mathieu-Daudé                                                  vdev->guest_features);
7519d94c213SPhilippe Mathieu-Daudé     status->host_features = qmp_decode_features(vdev->device_id,
7529d94c213SPhilippe Mathieu-Daudé                                                 vdev->host_features);
7539d94c213SPhilippe Mathieu-Daudé     status->backend_features = qmp_decode_features(vdev->device_id,
7549d94c213SPhilippe Mathieu-Daudé                                                    vdev->backend_features);
7559d94c213SPhilippe Mathieu-Daudé 
7569d94c213SPhilippe Mathieu-Daudé     switch (vdev->device_endian) {
7579d94c213SPhilippe Mathieu-Daudé     case VIRTIO_DEVICE_ENDIAN_LITTLE:
7589d94c213SPhilippe Mathieu-Daudé         status->device_endian = g_strdup("little");
7599d94c213SPhilippe Mathieu-Daudé         break;
7609d94c213SPhilippe Mathieu-Daudé     case VIRTIO_DEVICE_ENDIAN_BIG:
7619d94c213SPhilippe Mathieu-Daudé         status->device_endian = g_strdup("big");
7629d94c213SPhilippe Mathieu-Daudé         break;
7639d94c213SPhilippe Mathieu-Daudé     default:
7649d94c213SPhilippe Mathieu-Daudé         status->device_endian = g_strdup("unknown");
7659d94c213SPhilippe Mathieu-Daudé         break;
7669d94c213SPhilippe Mathieu-Daudé     }
7679d94c213SPhilippe Mathieu-Daudé 
7689d94c213SPhilippe Mathieu-Daudé     status->num_vqs = virtio_get_num_queues(vdev);
7699d94c213SPhilippe Mathieu-Daudé     status->status = qmp_decode_status(vdev->status);
7709d94c213SPhilippe Mathieu-Daudé     status->isr = vdev->isr;
7719d94c213SPhilippe Mathieu-Daudé     status->queue_sel = vdev->queue_sel;
7729d94c213SPhilippe Mathieu-Daudé     status->vm_running = vdev->vm_running;
7739d94c213SPhilippe Mathieu-Daudé     status->broken = vdev->broken;
7749d94c213SPhilippe Mathieu-Daudé     status->disabled = vdev->disabled;
7759d94c213SPhilippe Mathieu-Daudé     status->use_started = vdev->use_started;
7769d94c213SPhilippe Mathieu-Daudé     status->started = vdev->started;
7779d94c213SPhilippe Mathieu-Daudé     status->start_on_kick = vdev->start_on_kick;
7789d94c213SPhilippe Mathieu-Daudé     status->disable_legacy_check = vdev->disable_legacy_check;
7799d94c213SPhilippe Mathieu-Daudé     status->bus_name = g_strdup(vdev->bus_name);
7809d94c213SPhilippe Mathieu-Daudé     status->use_guest_notifier_mask = vdev->use_guest_notifier_mask;
7819d94c213SPhilippe Mathieu-Daudé 
7829d94c213SPhilippe Mathieu-Daudé     if (vdev->vhost_started) {
7839d94c213SPhilippe Mathieu-Daudé         VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
7849d94c213SPhilippe Mathieu-Daudé         struct vhost_dev *hdev = vdc->get_vhost(vdev);
7859d94c213SPhilippe Mathieu-Daudé 
7869d94c213SPhilippe Mathieu-Daudé         status->vhost_dev = g_new0(VhostStatus, 1);
7879d94c213SPhilippe Mathieu-Daudé         status->vhost_dev->n_mem_sections = hdev->n_mem_sections;
7889d94c213SPhilippe Mathieu-Daudé         status->vhost_dev->n_tmp_sections = hdev->n_tmp_sections;
7899d94c213SPhilippe Mathieu-Daudé         status->vhost_dev->nvqs = hdev->nvqs;
7909d94c213SPhilippe Mathieu-Daudé         status->vhost_dev->vq_index = hdev->vq_index;
7919d94c213SPhilippe Mathieu-Daudé         status->vhost_dev->features =
7929d94c213SPhilippe Mathieu-Daudé             qmp_decode_features(vdev->device_id, hdev->features);
7939d94c213SPhilippe Mathieu-Daudé         status->vhost_dev->acked_features =
7949d94c213SPhilippe Mathieu-Daudé             qmp_decode_features(vdev->device_id, hdev->acked_features);
7959d94c213SPhilippe Mathieu-Daudé         status->vhost_dev->backend_features =
7969d94c213SPhilippe Mathieu-Daudé             qmp_decode_features(vdev->device_id, hdev->backend_features);
7979d94c213SPhilippe Mathieu-Daudé         status->vhost_dev->protocol_features =
7989d94c213SPhilippe Mathieu-Daudé             qmp_decode_protocols(hdev->protocol_features);
7999d94c213SPhilippe Mathieu-Daudé         status->vhost_dev->max_queues = hdev->max_queues;
8009d94c213SPhilippe Mathieu-Daudé         status->vhost_dev->backend_cap = hdev->backend_cap;
8019d94c213SPhilippe Mathieu-Daudé         status->vhost_dev->log_enabled = hdev->log_enabled;
8029d94c213SPhilippe Mathieu-Daudé         status->vhost_dev->log_size = hdev->log_size;
8039d94c213SPhilippe Mathieu-Daudé     }
8049d94c213SPhilippe Mathieu-Daudé 
8059d94c213SPhilippe Mathieu-Daudé     return status;
8069d94c213SPhilippe Mathieu-Daudé }
8079d94c213SPhilippe Mathieu-Daudé 
8089d94c213SPhilippe Mathieu-Daudé VirtVhostQueueStatus *qmp_x_query_virtio_vhost_queue_status(const char *path,
8099d94c213SPhilippe Mathieu-Daudé                                                             uint16_t queue,
8109d94c213SPhilippe Mathieu-Daudé                                                             Error **errp)
8119d94c213SPhilippe Mathieu-Daudé {
8129d94c213SPhilippe Mathieu-Daudé     VirtIODevice *vdev;
8139d94c213SPhilippe Mathieu-Daudé     VirtVhostQueueStatus *status;
8149d94c213SPhilippe Mathieu-Daudé 
8159d94c213SPhilippe Mathieu-Daudé     vdev = qmp_find_virtio_device(path);
8169d94c213SPhilippe Mathieu-Daudé     if (vdev == NULL) {
8179d94c213SPhilippe Mathieu-Daudé         error_setg(errp, "Path %s is not a VirtIODevice", path);
8189d94c213SPhilippe Mathieu-Daudé         return NULL;
8199d94c213SPhilippe Mathieu-Daudé     }
8209d94c213SPhilippe Mathieu-Daudé 
8219d94c213SPhilippe Mathieu-Daudé     if (!vdev->vhost_started) {
8229d94c213SPhilippe Mathieu-Daudé         error_setg(errp, "Error: vhost device has not started yet");
8239d94c213SPhilippe Mathieu-Daudé         return NULL;
8249d94c213SPhilippe Mathieu-Daudé     }
8259d94c213SPhilippe Mathieu-Daudé 
8269d94c213SPhilippe Mathieu-Daudé     VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
8279d94c213SPhilippe Mathieu-Daudé     struct vhost_dev *hdev = vdc->get_vhost(vdev);
8289d94c213SPhilippe Mathieu-Daudé 
8299d94c213SPhilippe Mathieu-Daudé     if (queue < hdev->vq_index || queue >= hdev->vq_index + hdev->nvqs) {
8309d94c213SPhilippe Mathieu-Daudé         error_setg(errp, "Invalid vhost virtqueue number %d", queue);
8319d94c213SPhilippe Mathieu-Daudé         return NULL;
8329d94c213SPhilippe Mathieu-Daudé     }
8339d94c213SPhilippe Mathieu-Daudé 
8349d94c213SPhilippe Mathieu-Daudé     status = g_new0(VirtVhostQueueStatus, 1);
8359d94c213SPhilippe Mathieu-Daudé     status->name = g_strdup(vdev->name);
8369d94c213SPhilippe Mathieu-Daudé     status->kick = hdev->vqs[queue].kick;
8379d94c213SPhilippe Mathieu-Daudé     status->call = hdev->vqs[queue].call;
8389d94c213SPhilippe Mathieu-Daudé     status->desc = (uintptr_t)hdev->vqs[queue].desc;
8399d94c213SPhilippe Mathieu-Daudé     status->avail = (uintptr_t)hdev->vqs[queue].avail;
8409d94c213SPhilippe Mathieu-Daudé     status->used = (uintptr_t)hdev->vqs[queue].used;
8419d94c213SPhilippe Mathieu-Daudé     status->num = hdev->vqs[queue].num;
8429d94c213SPhilippe Mathieu-Daudé     status->desc_phys = hdev->vqs[queue].desc_phys;
8439d94c213SPhilippe Mathieu-Daudé     status->desc_size = hdev->vqs[queue].desc_size;
8449d94c213SPhilippe Mathieu-Daudé     status->avail_phys = hdev->vqs[queue].avail_phys;
8459d94c213SPhilippe Mathieu-Daudé     status->avail_size = hdev->vqs[queue].avail_size;
8469d94c213SPhilippe Mathieu-Daudé     status->used_phys = hdev->vqs[queue].used_phys;
8479d94c213SPhilippe Mathieu-Daudé     status->used_size = hdev->vqs[queue].used_size;
8489d94c213SPhilippe Mathieu-Daudé 
8499d94c213SPhilippe Mathieu-Daudé     return status;
8509d94c213SPhilippe Mathieu-Daudé }
851