xref: /qemu/hw/virtio/virtio-qmp.c (revision 28b629ab4aa93b9b7ec79c7e480611e4554586be)
1*28b629abSPhilippe Mathieu-Daudé /*
2*28b629abSPhilippe Mathieu-Daudé  * Virtio QMP helpers
3*28b629abSPhilippe Mathieu-Daudé  *
4*28b629abSPhilippe Mathieu-Daudé  * Copyright IBM, Corp. 2007
5*28b629abSPhilippe Mathieu-Daudé  *
6*28b629abSPhilippe Mathieu-Daudé  * Authors:
7*28b629abSPhilippe Mathieu-Daudé  *  Anthony Liguori   <aliguori@us.ibm.com>
8*28b629abSPhilippe Mathieu-Daudé  *
9*28b629abSPhilippe Mathieu-Daudé  * SPDX-License-Identifier: GPL-2.0-or-later
10*28b629abSPhilippe Mathieu-Daudé  */
11*28b629abSPhilippe Mathieu-Daudé 
12*28b629abSPhilippe Mathieu-Daudé #include "qemu/osdep.h"
13*28b629abSPhilippe Mathieu-Daudé #include "hw/virtio/virtio.h"
14*28b629abSPhilippe Mathieu-Daudé #include "virtio-qmp.h"
15*28b629abSPhilippe Mathieu-Daudé 
16*28b629abSPhilippe Mathieu-Daudé #include "standard-headers/linux/virtio_ids.h"
17*28b629abSPhilippe Mathieu-Daudé #include "standard-headers/linux/vhost_types.h"
18*28b629abSPhilippe Mathieu-Daudé #include "standard-headers/linux/virtio_blk.h"
19*28b629abSPhilippe Mathieu-Daudé #include "standard-headers/linux/virtio_console.h"
20*28b629abSPhilippe Mathieu-Daudé #include "standard-headers/linux/virtio_gpu.h"
21*28b629abSPhilippe Mathieu-Daudé #include "standard-headers/linux/virtio_net.h"
22*28b629abSPhilippe Mathieu-Daudé #include "standard-headers/linux/virtio_scsi.h"
23*28b629abSPhilippe Mathieu-Daudé #include "standard-headers/linux/virtio_i2c.h"
24*28b629abSPhilippe Mathieu-Daudé #include "standard-headers/linux/virtio_balloon.h"
25*28b629abSPhilippe Mathieu-Daudé #include "standard-headers/linux/virtio_iommu.h"
26*28b629abSPhilippe Mathieu-Daudé #include "standard-headers/linux/virtio_mem.h"
27*28b629abSPhilippe Mathieu-Daudé #include "standard-headers/linux/virtio_vsock.h"
28*28b629abSPhilippe Mathieu-Daudé 
29*28b629abSPhilippe Mathieu-Daudé #include CONFIG_DEVICES
30*28b629abSPhilippe Mathieu-Daudé 
31*28b629abSPhilippe Mathieu-Daudé #define FEATURE_ENTRY(name, desc) (qmp_virtio_feature_map_t) \
32*28b629abSPhilippe Mathieu-Daudé     { .virtio_bit = name, .feature_desc = desc }
33*28b629abSPhilippe Mathieu-Daudé 
34*28b629abSPhilippe Mathieu-Daudé enum VhostUserProtocolFeature {
35*28b629abSPhilippe Mathieu-Daudé     VHOST_USER_PROTOCOL_F_MQ = 0,
36*28b629abSPhilippe Mathieu-Daudé     VHOST_USER_PROTOCOL_F_LOG_SHMFD = 1,
37*28b629abSPhilippe Mathieu-Daudé     VHOST_USER_PROTOCOL_F_RARP = 2,
38*28b629abSPhilippe Mathieu-Daudé     VHOST_USER_PROTOCOL_F_REPLY_ACK = 3,
39*28b629abSPhilippe Mathieu-Daudé     VHOST_USER_PROTOCOL_F_NET_MTU = 4,
40*28b629abSPhilippe Mathieu-Daudé     VHOST_USER_PROTOCOL_F_SLAVE_REQ = 5,
41*28b629abSPhilippe Mathieu-Daudé     VHOST_USER_PROTOCOL_F_CROSS_ENDIAN = 6,
42*28b629abSPhilippe Mathieu-Daudé     VHOST_USER_PROTOCOL_F_CRYPTO_SESSION = 7,
43*28b629abSPhilippe Mathieu-Daudé     VHOST_USER_PROTOCOL_F_PAGEFAULT = 8,
44*28b629abSPhilippe Mathieu-Daudé     VHOST_USER_PROTOCOL_F_CONFIG = 9,
45*28b629abSPhilippe Mathieu-Daudé     VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD = 10,
46*28b629abSPhilippe Mathieu-Daudé     VHOST_USER_PROTOCOL_F_HOST_NOTIFIER = 11,
47*28b629abSPhilippe Mathieu-Daudé     VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD = 12,
48*28b629abSPhilippe Mathieu-Daudé     VHOST_USER_PROTOCOL_F_RESET_DEVICE = 13,
49*28b629abSPhilippe Mathieu-Daudé     VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS = 14,
50*28b629abSPhilippe Mathieu-Daudé     VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS = 15,
51*28b629abSPhilippe Mathieu-Daudé     VHOST_USER_PROTOCOL_F_MAX
52*28b629abSPhilippe Mathieu-Daudé };
53*28b629abSPhilippe Mathieu-Daudé 
54*28b629abSPhilippe Mathieu-Daudé /* Virtio transport features mapping */
55*28b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_transport_map[] = {
56*28b629abSPhilippe Mathieu-Daudé     /* Virtio device transport features */
57*28b629abSPhilippe Mathieu-Daudé #ifndef VIRTIO_CONFIG_NO_LEGACY
58*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_F_NOTIFY_ON_EMPTY, \
59*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_F_NOTIFY_ON_EMPTY: Notify when device runs out of avail. "
60*28b629abSPhilippe Mathieu-Daudé             "descs. on VQ"),
61*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_F_ANY_LAYOUT, \
62*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_F_ANY_LAYOUT: Device accepts arbitrary desc. layouts"),
63*28b629abSPhilippe Mathieu-Daudé #endif /* !VIRTIO_CONFIG_NO_LEGACY */
64*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_F_VERSION_1, \
65*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_F_VERSION_1: Device compliant for v1 spec (legacy)"),
66*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_F_IOMMU_PLATFORM, \
67*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_F_IOMMU_PLATFORM: Device can be used on IOMMU platform"),
68*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_F_RING_PACKED, \
69*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_F_RING_PACKED: Device supports packed VQ layout"),
70*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_F_IN_ORDER, \
71*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_F_IN_ORDER: Device uses buffers in same order as made "
72*28b629abSPhilippe Mathieu-Daudé             "available by driver"),
73*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_F_ORDER_PLATFORM, \
74*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_F_ORDER_PLATFORM: Memory accesses ordered by platform"),
75*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_F_SR_IOV, \
76*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_F_SR_IOV: Device supports single root I/O virtualization"),
77*28b629abSPhilippe Mathieu-Daudé     /* Virtio ring transport features */
78*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_RING_F_INDIRECT_DESC, \
79*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_RING_F_INDIRECT_DESC: Indirect descriptors supported"),
80*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_RING_F_EVENT_IDX, \
81*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_RING_F_EVENT_IDX: Used & avail. event fields enabled"),
82*28b629abSPhilippe Mathieu-Daudé     { -1, "" }
83*28b629abSPhilippe Mathieu-Daudé };
84*28b629abSPhilippe Mathieu-Daudé 
85*28b629abSPhilippe Mathieu-Daudé /* Vhost-user protocol features mapping */
86*28b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t vhost_user_protocol_map[] = {
87*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_MQ, \
88*28b629abSPhilippe Mathieu-Daudé             "VHOST_USER_PROTOCOL_F_MQ: Multiqueue protocol supported"),
89*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_LOG_SHMFD, \
90*28b629abSPhilippe Mathieu-Daudé             "VHOST_USER_PROTOCOL_F_LOG_SHMFD: Shared log memory fd supported"),
91*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_RARP, \
92*28b629abSPhilippe Mathieu-Daudé             "VHOST_USER_PROTOCOL_F_RARP: Vhost-user back-end RARP broadcasting "
93*28b629abSPhilippe Mathieu-Daudé             "supported"),
94*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_REPLY_ACK, \
95*28b629abSPhilippe Mathieu-Daudé             "VHOST_USER_PROTOCOL_F_REPLY_ACK: Requested operation status ack. "
96*28b629abSPhilippe Mathieu-Daudé             "supported"),
97*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_NET_MTU, \
98*28b629abSPhilippe Mathieu-Daudé             "VHOST_USER_PROTOCOL_F_NET_MTU: Expose host MTU to guest supported"),
99*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_SLAVE_REQ, \
100*28b629abSPhilippe Mathieu-Daudé             "VHOST_USER_PROTOCOL_F_SLAVE_REQ: Socket fd for back-end initiated "
101*28b629abSPhilippe Mathieu-Daudé             "requests supported"),
102*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_CROSS_ENDIAN, \
103*28b629abSPhilippe Mathieu-Daudé             "VHOST_USER_PROTOCOL_F_CROSS_ENDIAN: Endianness of VQs for legacy "
104*28b629abSPhilippe Mathieu-Daudé             "devices supported"),
105*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_CRYPTO_SESSION, \
106*28b629abSPhilippe Mathieu-Daudé             "VHOST_USER_PROTOCOL_F_CRYPTO_SESSION: Session creation for crypto "
107*28b629abSPhilippe Mathieu-Daudé             "operations supported"),
108*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_PAGEFAULT, \
109*28b629abSPhilippe Mathieu-Daudé             "VHOST_USER_PROTOCOL_F_PAGEFAULT: Request servicing on userfaultfd "
110*28b629abSPhilippe Mathieu-Daudé             "for accessed pages supported"),
111*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_CONFIG, \
112*28b629abSPhilippe Mathieu-Daudé             "VHOST_USER_PROTOCOL_F_CONFIG: Vhost-user messaging for virtio "
113*28b629abSPhilippe Mathieu-Daudé             "device configuration space supported"),
114*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD, \
115*28b629abSPhilippe Mathieu-Daudé             "VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD: Slave fd communication "
116*28b629abSPhilippe Mathieu-Daudé             "channel supported"),
117*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_HOST_NOTIFIER, \
118*28b629abSPhilippe Mathieu-Daudé             "VHOST_USER_PROTOCOL_F_HOST_NOTIFIER: Host notifiers for specified "
119*28b629abSPhilippe Mathieu-Daudé             "VQs supported"),
120*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD, \
121*28b629abSPhilippe Mathieu-Daudé             "VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD: Shared inflight I/O buffers "
122*28b629abSPhilippe Mathieu-Daudé             "supported"),
123*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_RESET_DEVICE, \
124*28b629abSPhilippe Mathieu-Daudé             "VHOST_USER_PROTOCOL_F_RESET_DEVICE: Disabling all rings and "
125*28b629abSPhilippe Mathieu-Daudé             "resetting internal device state supported"),
126*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS, \
127*28b629abSPhilippe Mathieu-Daudé             "VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS: In-band messaging "
128*28b629abSPhilippe Mathieu-Daudé             "supported"),
129*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS, \
130*28b629abSPhilippe Mathieu-Daudé             "VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS: Configuration for "
131*28b629abSPhilippe Mathieu-Daudé             "memory slots supported"),
132*28b629abSPhilippe Mathieu-Daudé     { -1, "" }
133*28b629abSPhilippe Mathieu-Daudé };
134*28b629abSPhilippe Mathieu-Daudé 
135*28b629abSPhilippe Mathieu-Daudé /* virtio device configuration statuses */
136*28b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_config_status_map[] = {
137*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_CONFIG_S_DRIVER_OK, \
138*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_CONFIG_S_DRIVER_OK: Driver setup and ready"),
139*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_CONFIG_S_FEATURES_OK, \
140*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_CONFIG_S_FEATURES_OK: Feature negotiation complete"),
141*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_CONFIG_S_DRIVER, \
142*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_CONFIG_S_DRIVER: Guest OS compatible with device"),
143*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_CONFIG_S_NEEDS_RESET, \
144*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_CONFIG_S_NEEDS_RESET: Irrecoverable error, device needs "
145*28b629abSPhilippe Mathieu-Daudé             "reset"),
146*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_CONFIG_S_FAILED, \
147*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_CONFIG_S_FAILED: Error in guest, device failed"),
148*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_CONFIG_S_ACKNOWLEDGE, \
149*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_CONFIG_S_ACKNOWLEDGE: Valid virtio device found"),
150*28b629abSPhilippe Mathieu-Daudé     { -1, "" }
151*28b629abSPhilippe Mathieu-Daudé };
152*28b629abSPhilippe Mathieu-Daudé 
153*28b629abSPhilippe Mathieu-Daudé /* virtio-blk features mapping */
154*28b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_BLK
155*28b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_blk_feature_map[] = {
156*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_BLK_F_SIZE_MAX, \
157*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_BLK_F_SIZE_MAX: Max segment size is size_max"),
158*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_BLK_F_SEG_MAX, \
159*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_BLK_F_SEG_MAX: Max segments in a request is seg_max"),
160*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_BLK_F_GEOMETRY, \
161*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_BLK_F_GEOMETRY: Legacy geometry available"),
162*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_BLK_F_RO, \
163*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_BLK_F_RO: Device is read-only"),
164*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_BLK_F_BLK_SIZE, \
165*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_BLK_F_BLK_SIZE: Block size of disk available"),
166*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_BLK_F_TOPOLOGY, \
167*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_BLK_F_TOPOLOGY: Topology information available"),
168*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_BLK_F_MQ, \
169*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_BLK_F_MQ: Multiqueue supported"),
170*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_BLK_F_DISCARD, \
171*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_BLK_F_DISCARD: Discard command supported"),
172*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_BLK_F_WRITE_ZEROES, \
173*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_BLK_F_WRITE_ZEROES: Write zeroes command supported"),
174*28b629abSPhilippe Mathieu-Daudé #ifndef VIRTIO_BLK_NO_LEGACY
175*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_BLK_F_BARRIER, \
176*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_BLK_F_BARRIER: Request barriers supported"),
177*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_BLK_F_SCSI, \
178*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_BLK_F_SCSI: SCSI packet commands supported"),
179*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_BLK_F_FLUSH, \
180*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_BLK_F_FLUSH: Flush command supported"),
181*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_BLK_F_CONFIG_WCE, \
182*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_BLK_F_CONFIG_WCE: Cache writeback and writethrough modes "
183*28b629abSPhilippe Mathieu-Daudé             "supported"),
184*28b629abSPhilippe Mathieu-Daudé #endif /* !VIRTIO_BLK_NO_LEGACY */
185*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_F_LOG_ALL, \
186*28b629abSPhilippe Mathieu-Daudé             "VHOST_F_LOG_ALL: Logging write descriptors supported"),
187*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
188*28b629abSPhilippe Mathieu-Daudé             "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
189*28b629abSPhilippe Mathieu-Daudé             "negotiation supported"),
190*28b629abSPhilippe Mathieu-Daudé     { -1, "" }
191*28b629abSPhilippe Mathieu-Daudé };
192*28b629abSPhilippe Mathieu-Daudé #endif
193*28b629abSPhilippe Mathieu-Daudé 
194*28b629abSPhilippe Mathieu-Daudé /* virtio-serial features mapping */
195*28b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_SERIAL
196*28b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_serial_feature_map[] = {
197*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_CONSOLE_F_SIZE, \
198*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_CONSOLE_F_SIZE: Host providing console size"),
199*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_CONSOLE_F_MULTIPORT, \
200*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_CONSOLE_F_MULTIPORT: Multiple ports for device supported"),
201*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_CONSOLE_F_EMERG_WRITE, \
202*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_CONSOLE_F_EMERG_WRITE: Emergency write supported"),
203*28b629abSPhilippe Mathieu-Daudé     { -1, "" }
204*28b629abSPhilippe Mathieu-Daudé };
205*28b629abSPhilippe Mathieu-Daudé #endif
206*28b629abSPhilippe Mathieu-Daudé 
207*28b629abSPhilippe Mathieu-Daudé /* virtio-gpu features mapping */
208*28b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_GPU
209*28b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_gpu_feature_map[] = {
210*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_GPU_F_VIRGL, \
211*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_GPU_F_VIRGL: Virgl 3D mode supported"),
212*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_GPU_F_EDID, \
213*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_GPU_F_EDID: EDID metadata supported"),
214*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_GPU_F_RESOURCE_UUID, \
215*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_GPU_F_RESOURCE_UUID: Resource UUID assigning supported"),
216*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_GPU_F_RESOURCE_BLOB, \
217*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_GPU_F_RESOURCE_BLOB: Size-based blob resources supported"),
218*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_GPU_F_CONTEXT_INIT, \
219*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_GPU_F_CONTEXT_INIT: Context types and synchronization "
220*28b629abSPhilippe Mathieu-Daudé             "timelines supported"),
221*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_F_LOG_ALL, \
222*28b629abSPhilippe Mathieu-Daudé             "VHOST_F_LOG_ALL: Logging write descriptors supported"),
223*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
224*28b629abSPhilippe Mathieu-Daudé             "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
225*28b629abSPhilippe Mathieu-Daudé             "negotiation supported"),
226*28b629abSPhilippe Mathieu-Daudé     { -1, "" }
227*28b629abSPhilippe Mathieu-Daudé };
228*28b629abSPhilippe Mathieu-Daudé #endif
229*28b629abSPhilippe Mathieu-Daudé 
230*28b629abSPhilippe Mathieu-Daudé /* virtio-input features mapping */
231*28b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_INPUT
232*28b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_input_feature_map[] = {
233*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_F_LOG_ALL, \
234*28b629abSPhilippe Mathieu-Daudé             "VHOST_F_LOG_ALL: Logging write descriptors supported"),
235*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
236*28b629abSPhilippe Mathieu-Daudé             "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
237*28b629abSPhilippe Mathieu-Daudé             "negotiation supported"),
238*28b629abSPhilippe Mathieu-Daudé     { -1, "" }
239*28b629abSPhilippe Mathieu-Daudé };
240*28b629abSPhilippe Mathieu-Daudé #endif
241*28b629abSPhilippe Mathieu-Daudé 
242*28b629abSPhilippe Mathieu-Daudé /* virtio-net features mapping */
243*28b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_NET
244*28b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_net_feature_map[] = {
245*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_CSUM, \
246*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_CSUM: Device handling packets with partial checksum "
247*28b629abSPhilippe Mathieu-Daudé             "supported"),
248*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_GUEST_CSUM, \
249*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_GUEST_CSUM: Driver handling packets with partial "
250*28b629abSPhilippe Mathieu-Daudé             "checksum supported"),
251*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_CTRL_GUEST_OFFLOADS, \
252*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_CTRL_GUEST_OFFLOADS: Control channel offloading "
253*28b629abSPhilippe Mathieu-Daudé             "reconfig. supported"),
254*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_MTU, \
255*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_MTU: Device max MTU reporting supported"),
256*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_MAC, \
257*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_MAC: Device has given MAC address"),
258*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_GUEST_TSO4, \
259*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_GUEST_TSO4: Driver can receive TSOv4"),
260*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_GUEST_TSO6, \
261*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_GUEST_TSO6: Driver can receive TSOv6"),
262*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_GUEST_ECN, \
263*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_GUEST_ECN: Driver can receive TSO with ECN"),
264*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_GUEST_UFO, \
265*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_GUEST_UFO: Driver can receive UFO"),
266*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_HOST_TSO4, \
267*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_HOST_TSO4: Device can receive TSOv4"),
268*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_HOST_TSO6, \
269*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_HOST_TSO6: Device can receive TSOv6"),
270*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_HOST_ECN, \
271*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_HOST_ECN: Device can receive TSO with ECN"),
272*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_HOST_UFO, \
273*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_HOST_UFO: Device can receive UFO"),
274*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_MRG_RXBUF, \
275*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_MRG_RXBUF: Driver can merge receive buffers"),
276*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_STATUS, \
277*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_STATUS: Configuration status field available"),
278*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_CTRL_VQ, \
279*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_CTRL_VQ: Control channel available"),
280*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_CTRL_RX, \
281*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_CTRL_RX: Control channel RX mode supported"),
282*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_CTRL_VLAN, \
283*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_CTRL_VLAN: Control channel VLAN filtering supported"),
284*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_CTRL_RX_EXTRA, \
285*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_CTRL_RX_EXTRA: Extra RX mode control supported"),
286*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_GUEST_ANNOUNCE, \
287*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_GUEST_ANNOUNCE: Driver sending gratuitous packets "
288*28b629abSPhilippe Mathieu-Daudé             "supported"),
289*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_MQ, \
290*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_MQ: Multiqueue with automatic receive steering "
291*28b629abSPhilippe Mathieu-Daudé             "supported"),
292*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_CTRL_MAC_ADDR, \
293*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_CTRL_MAC_ADDR: MAC address set through control "
294*28b629abSPhilippe Mathieu-Daudé             "channel"),
295*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_HASH_REPORT, \
296*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_HASH_REPORT: Hash reporting supported"),
297*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_RSS, \
298*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_RSS: RSS RX steering supported"),
299*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_RSC_EXT, \
300*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_RSC_EXT: Extended coalescing info supported"),
301*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_STANDBY, \
302*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_STANDBY: Device acting as standby for primary "
303*28b629abSPhilippe Mathieu-Daudé             "device with same MAC addr. supported"),
304*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_SPEED_DUPLEX, \
305*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_SPEED_DUPLEX: Device set linkspeed and duplex"),
306*28b629abSPhilippe Mathieu-Daudé #ifndef VIRTIO_NET_NO_LEGACY
307*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_NET_F_GSO, \
308*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_NET_F_GSO: Handling GSO-type packets supported"),
309*28b629abSPhilippe Mathieu-Daudé #endif /* !VIRTIO_NET_NO_LEGACY */
310*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_NET_F_VIRTIO_NET_HDR, \
311*28b629abSPhilippe Mathieu-Daudé             "VHOST_NET_F_VIRTIO_NET_HDR: Virtio-net headers for RX and TX "
312*28b629abSPhilippe Mathieu-Daudé             "packets supported"),
313*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_F_LOG_ALL, \
314*28b629abSPhilippe Mathieu-Daudé             "VHOST_F_LOG_ALL: Logging write descriptors supported"),
315*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
316*28b629abSPhilippe Mathieu-Daudé             "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
317*28b629abSPhilippe Mathieu-Daudé             "negotiation supported"),
318*28b629abSPhilippe Mathieu-Daudé     { -1, "" }
319*28b629abSPhilippe Mathieu-Daudé };
320*28b629abSPhilippe Mathieu-Daudé #endif
321*28b629abSPhilippe Mathieu-Daudé 
322*28b629abSPhilippe Mathieu-Daudé /* virtio-scsi features mapping */
323*28b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_SCSI
324*28b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_scsi_feature_map[] = {
325*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_SCSI_F_INOUT, \
326*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_SCSI_F_INOUT: Requests including read and writable data "
327*28b629abSPhilippe Mathieu-Daudé             "buffers suppoted"),
328*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_SCSI_F_HOTPLUG, \
329*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_SCSI_F_HOTPLUG: Reporting and handling hot-plug events "
330*28b629abSPhilippe Mathieu-Daudé             "supported"),
331*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_SCSI_F_CHANGE, \
332*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_SCSI_F_CHANGE: Reporting and handling LUN changes "
333*28b629abSPhilippe Mathieu-Daudé             "supported"),
334*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_SCSI_F_T10_PI, \
335*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_SCSI_F_T10_PI: T10 info included in request header"),
336*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_F_LOG_ALL, \
337*28b629abSPhilippe Mathieu-Daudé             "VHOST_F_LOG_ALL: Logging write descriptors supported"),
338*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
339*28b629abSPhilippe Mathieu-Daudé             "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
340*28b629abSPhilippe Mathieu-Daudé             "negotiation supported"),
341*28b629abSPhilippe Mathieu-Daudé     { -1, "" }
342*28b629abSPhilippe Mathieu-Daudé };
343*28b629abSPhilippe Mathieu-Daudé #endif
344*28b629abSPhilippe Mathieu-Daudé 
345*28b629abSPhilippe Mathieu-Daudé /* virtio/vhost-user-fs features mapping */
346*28b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VHOST_USER_FS
347*28b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_fs_feature_map[] = {
348*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_F_LOG_ALL, \
349*28b629abSPhilippe Mathieu-Daudé             "VHOST_F_LOG_ALL: Logging write descriptors supported"),
350*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
351*28b629abSPhilippe Mathieu-Daudé             "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
352*28b629abSPhilippe Mathieu-Daudé             "negotiation supported"),
353*28b629abSPhilippe Mathieu-Daudé     { -1, "" }
354*28b629abSPhilippe Mathieu-Daudé };
355*28b629abSPhilippe Mathieu-Daudé #endif
356*28b629abSPhilippe Mathieu-Daudé 
357*28b629abSPhilippe Mathieu-Daudé /* virtio/vhost-user-i2c features mapping */
358*28b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_I2C_ADAPTER
359*28b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_i2c_feature_map[] = {
360*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_I2C_F_ZERO_LENGTH_REQUEST, \
361*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_I2C_F_ZERO_LEGNTH_REQUEST: Zero length requests supported"),
362*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_F_LOG_ALL, \
363*28b629abSPhilippe Mathieu-Daudé             "VHOST_F_LOG_ALL: Logging write descriptors supported"),
364*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
365*28b629abSPhilippe Mathieu-Daudé             "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
366*28b629abSPhilippe Mathieu-Daudé             "negotiation supported"),
367*28b629abSPhilippe Mathieu-Daudé     { -1, "" }
368*28b629abSPhilippe Mathieu-Daudé };
369*28b629abSPhilippe Mathieu-Daudé #endif
370*28b629abSPhilippe Mathieu-Daudé 
371*28b629abSPhilippe Mathieu-Daudé /* virtio/vhost-vsock features mapping */
372*28b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VHOST_VSOCK
373*28b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_vsock_feature_map[] = {
374*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_VSOCK_F_SEQPACKET, \
375*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_VSOCK_F_SEQPACKET: SOCK_SEQPACKET supported"),
376*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_F_LOG_ALL, \
377*28b629abSPhilippe Mathieu-Daudé             "VHOST_F_LOG_ALL: Logging write descriptors supported"),
378*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
379*28b629abSPhilippe Mathieu-Daudé             "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
380*28b629abSPhilippe Mathieu-Daudé             "negotiation supported"),
381*28b629abSPhilippe Mathieu-Daudé     { -1, "" }
382*28b629abSPhilippe Mathieu-Daudé };
383*28b629abSPhilippe Mathieu-Daudé #endif
384*28b629abSPhilippe Mathieu-Daudé 
385*28b629abSPhilippe Mathieu-Daudé /* virtio-balloon features mapping */
386*28b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_BALLOON
387*28b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_balloon_feature_map[] = {
388*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_BALLOON_F_MUST_TELL_HOST, \
389*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_BALLOON_F_MUST_TELL_HOST: Tell host before reclaiming "
390*28b629abSPhilippe Mathieu-Daudé             "pages"),
391*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_BALLOON_F_STATS_VQ, \
392*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_BALLOON_F_STATS_VQ: Guest memory stats VQ available"),
393*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_BALLOON_F_DEFLATE_ON_OOM, \
394*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_BALLOON_F_DEFLATE_ON_OOM: Deflate balloon when guest OOM"),
395*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_BALLOON_F_FREE_PAGE_HINT, \
396*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_BALLOON_F_FREE_PAGE_HINT: VQ reporting free pages enabled"),
397*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_BALLOON_F_PAGE_POISON, \
398*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_BALLOON_F_PAGE_POISON: Guest page poisoning enabled"),
399*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_BALLOON_F_REPORTING, \
400*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_BALLOON_F_REPORTING: Page reporting VQ enabled"),
401*28b629abSPhilippe Mathieu-Daudé     { -1, "" }
402*28b629abSPhilippe Mathieu-Daudé };
403*28b629abSPhilippe Mathieu-Daudé #endif
404*28b629abSPhilippe Mathieu-Daudé 
405*28b629abSPhilippe Mathieu-Daudé /* virtio-crypto features mapping */
406*28b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_CRYPTO
407*28b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_crypto_feature_map[] = {
408*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_F_LOG_ALL, \
409*28b629abSPhilippe Mathieu-Daudé             "VHOST_F_LOG_ALL: Logging write descriptors supported"),
410*28b629abSPhilippe Mathieu-Daudé     { -1, "" }
411*28b629abSPhilippe Mathieu-Daudé };
412*28b629abSPhilippe Mathieu-Daudé #endif
413*28b629abSPhilippe Mathieu-Daudé 
414*28b629abSPhilippe Mathieu-Daudé /* virtio-iommu features mapping */
415*28b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_IOMMU
416*28b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_iommu_feature_map[] = {
417*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_IOMMU_F_INPUT_RANGE, \
418*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_IOMMU_F_INPUT_RANGE: Range of available virtual addrs. "
419*28b629abSPhilippe Mathieu-Daudé             "available"),
420*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_IOMMU_F_DOMAIN_RANGE, \
421*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_IOMMU_F_DOMAIN_RANGE: Number of supported domains "
422*28b629abSPhilippe Mathieu-Daudé             "available"),
423*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_IOMMU_F_MAP_UNMAP, \
424*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_IOMMU_F_MAP_UNMAP: Map and unmap requests available"),
425*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_IOMMU_F_BYPASS, \
426*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_IOMMU_F_BYPASS: Endpoints not attached to domains are in "
427*28b629abSPhilippe Mathieu-Daudé             "bypass mode"),
428*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_IOMMU_F_PROBE, \
429*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_IOMMU_F_PROBE: Probe requests available"),
430*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_IOMMU_F_MMIO, \
431*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_IOMMU_F_MMIO: VIRTIO_IOMMU_MAP_F_MMIO flag available"),
432*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_IOMMU_F_BYPASS_CONFIG, \
433*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_IOMMU_F_BYPASS_CONFIG: Bypass field of IOMMU config "
434*28b629abSPhilippe Mathieu-Daudé             "available"),
435*28b629abSPhilippe Mathieu-Daudé     { -1, "" }
436*28b629abSPhilippe Mathieu-Daudé };
437*28b629abSPhilippe Mathieu-Daudé #endif
438*28b629abSPhilippe Mathieu-Daudé 
439*28b629abSPhilippe Mathieu-Daudé /* virtio-mem features mapping */
440*28b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_MEM
441*28b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_mem_feature_map[] = {
442*28b629abSPhilippe Mathieu-Daudé #ifndef CONFIG_ACPI
443*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_MEM_F_ACPI_PXM, \
444*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_MEM_F_ACPI_PXM: node_id is an ACPI PXM and is valid"),
445*28b629abSPhilippe Mathieu-Daudé #endif /* !CONFIG_ACPI */
446*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE, \
447*28b629abSPhilippe Mathieu-Daudé             "VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE: Unplugged memory cannot be "
448*28b629abSPhilippe Mathieu-Daudé             "accessed"),
449*28b629abSPhilippe Mathieu-Daudé     { -1, "" }
450*28b629abSPhilippe Mathieu-Daudé };
451*28b629abSPhilippe Mathieu-Daudé #endif
452*28b629abSPhilippe Mathieu-Daudé 
453*28b629abSPhilippe Mathieu-Daudé /* virtio-rng features mapping */
454*28b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_RNG
455*28b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_rng_feature_map[] = {
456*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_F_LOG_ALL, \
457*28b629abSPhilippe Mathieu-Daudé             "VHOST_F_LOG_ALL: Logging write descriptors supported"),
458*28b629abSPhilippe Mathieu-Daudé     FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
459*28b629abSPhilippe Mathieu-Daudé             "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
460*28b629abSPhilippe Mathieu-Daudé             "negotiation supported"),
461*28b629abSPhilippe Mathieu-Daudé     { -1, "" }
462*28b629abSPhilippe Mathieu-Daudé };
463*28b629abSPhilippe Mathieu-Daudé #endif
464*28b629abSPhilippe Mathieu-Daudé 
465*28b629abSPhilippe Mathieu-Daudé #define CONVERT_FEATURES(type, map, is_status, bitmap)   \
466*28b629abSPhilippe Mathieu-Daudé     ({                                                   \
467*28b629abSPhilippe Mathieu-Daudé         type *list = NULL;                               \
468*28b629abSPhilippe Mathieu-Daudé         type *node;                                      \
469*28b629abSPhilippe Mathieu-Daudé         for (i = 0; map[i].virtio_bit != -1; i++) {      \
470*28b629abSPhilippe Mathieu-Daudé             if (is_status) {                             \
471*28b629abSPhilippe Mathieu-Daudé                 bit = map[i].virtio_bit;                 \
472*28b629abSPhilippe Mathieu-Daudé             }                                            \
473*28b629abSPhilippe Mathieu-Daudé             else {                                       \
474*28b629abSPhilippe Mathieu-Daudé                 bit = 1ULL << map[i].virtio_bit;         \
475*28b629abSPhilippe Mathieu-Daudé             }                                            \
476*28b629abSPhilippe Mathieu-Daudé             if ((bitmap & bit) == 0) {                   \
477*28b629abSPhilippe Mathieu-Daudé                 continue;                                \
478*28b629abSPhilippe Mathieu-Daudé             }                                            \
479*28b629abSPhilippe Mathieu-Daudé             node = g_new0(type, 1);                      \
480*28b629abSPhilippe Mathieu-Daudé             node->value = g_strdup(map[i].feature_desc); \
481*28b629abSPhilippe Mathieu-Daudé             node->next = list;                           \
482*28b629abSPhilippe Mathieu-Daudé             list = node;                                 \
483*28b629abSPhilippe Mathieu-Daudé             bitmap ^= bit;                               \
484*28b629abSPhilippe Mathieu-Daudé         }                                                \
485*28b629abSPhilippe Mathieu-Daudé         list;                                            \
486*28b629abSPhilippe Mathieu-Daudé     })
487*28b629abSPhilippe Mathieu-Daudé 
488*28b629abSPhilippe Mathieu-Daudé VirtioDeviceStatus *qmp_decode_status(uint8_t bitmap)
489*28b629abSPhilippe Mathieu-Daudé {
490*28b629abSPhilippe Mathieu-Daudé     VirtioDeviceStatus *status;
491*28b629abSPhilippe Mathieu-Daudé     uint8_t bit;
492*28b629abSPhilippe Mathieu-Daudé     int i;
493*28b629abSPhilippe Mathieu-Daudé 
494*28b629abSPhilippe Mathieu-Daudé     status = g_new0(VirtioDeviceStatus, 1);
495*28b629abSPhilippe Mathieu-Daudé     status->statuses = CONVERT_FEATURES(strList, virtio_config_status_map,
496*28b629abSPhilippe Mathieu-Daudé                                         1, bitmap);
497*28b629abSPhilippe Mathieu-Daudé     status->has_unknown_statuses = bitmap != 0;
498*28b629abSPhilippe Mathieu-Daudé     if (status->has_unknown_statuses) {
499*28b629abSPhilippe Mathieu-Daudé         status->unknown_statuses = bitmap;
500*28b629abSPhilippe Mathieu-Daudé     }
501*28b629abSPhilippe Mathieu-Daudé 
502*28b629abSPhilippe Mathieu-Daudé     return status;
503*28b629abSPhilippe Mathieu-Daudé }
504*28b629abSPhilippe Mathieu-Daudé 
505*28b629abSPhilippe Mathieu-Daudé VhostDeviceProtocols *qmp_decode_protocols(uint64_t bitmap)
506*28b629abSPhilippe Mathieu-Daudé {
507*28b629abSPhilippe Mathieu-Daudé     VhostDeviceProtocols *vhu_protocols;
508*28b629abSPhilippe Mathieu-Daudé     uint64_t bit;
509*28b629abSPhilippe Mathieu-Daudé     int i;
510*28b629abSPhilippe Mathieu-Daudé 
511*28b629abSPhilippe Mathieu-Daudé     vhu_protocols = g_new0(VhostDeviceProtocols, 1);
512*28b629abSPhilippe Mathieu-Daudé     vhu_protocols->protocols =
513*28b629abSPhilippe Mathieu-Daudé                     CONVERT_FEATURES(strList,
514*28b629abSPhilippe Mathieu-Daudé                                      vhost_user_protocol_map, 0, bitmap);
515*28b629abSPhilippe Mathieu-Daudé     vhu_protocols->has_unknown_protocols = bitmap != 0;
516*28b629abSPhilippe Mathieu-Daudé     if (vhu_protocols->has_unknown_protocols) {
517*28b629abSPhilippe Mathieu-Daudé         vhu_protocols->unknown_protocols = bitmap;
518*28b629abSPhilippe Mathieu-Daudé     }
519*28b629abSPhilippe Mathieu-Daudé 
520*28b629abSPhilippe Mathieu-Daudé     return vhu_protocols;
521*28b629abSPhilippe Mathieu-Daudé }
522*28b629abSPhilippe Mathieu-Daudé 
523*28b629abSPhilippe Mathieu-Daudé VirtioDeviceFeatures *qmp_decode_features(uint16_t device_id, uint64_t bitmap)
524*28b629abSPhilippe Mathieu-Daudé {
525*28b629abSPhilippe Mathieu-Daudé     VirtioDeviceFeatures *features;
526*28b629abSPhilippe Mathieu-Daudé     uint64_t bit;
527*28b629abSPhilippe Mathieu-Daudé     int i;
528*28b629abSPhilippe Mathieu-Daudé 
529*28b629abSPhilippe Mathieu-Daudé     features = g_new0(VirtioDeviceFeatures, 1);
530*28b629abSPhilippe Mathieu-Daudé     features->has_dev_features = true;
531*28b629abSPhilippe Mathieu-Daudé 
532*28b629abSPhilippe Mathieu-Daudé     /* transport features */
533*28b629abSPhilippe Mathieu-Daudé     features->transports = CONVERT_FEATURES(strList, virtio_transport_map, 0,
534*28b629abSPhilippe Mathieu-Daudé                                             bitmap);
535*28b629abSPhilippe Mathieu-Daudé 
536*28b629abSPhilippe Mathieu-Daudé     /* device features */
537*28b629abSPhilippe Mathieu-Daudé     switch (device_id) {
538*28b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_SERIAL
539*28b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_CONSOLE:
540*28b629abSPhilippe Mathieu-Daudé         features->dev_features =
541*28b629abSPhilippe Mathieu-Daudé             CONVERT_FEATURES(strList, virtio_serial_feature_map, 0, bitmap);
542*28b629abSPhilippe Mathieu-Daudé         break;
543*28b629abSPhilippe Mathieu-Daudé #endif
544*28b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_BLK
545*28b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_BLOCK:
546*28b629abSPhilippe Mathieu-Daudé         features->dev_features =
547*28b629abSPhilippe Mathieu-Daudé             CONVERT_FEATURES(strList, virtio_blk_feature_map, 0, bitmap);
548*28b629abSPhilippe Mathieu-Daudé         break;
549*28b629abSPhilippe Mathieu-Daudé #endif
550*28b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_GPU
551*28b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_GPU:
552*28b629abSPhilippe Mathieu-Daudé         features->dev_features =
553*28b629abSPhilippe Mathieu-Daudé             CONVERT_FEATURES(strList, virtio_gpu_feature_map, 0, bitmap);
554*28b629abSPhilippe Mathieu-Daudé         break;
555*28b629abSPhilippe Mathieu-Daudé #endif
556*28b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_NET
557*28b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_NET:
558*28b629abSPhilippe Mathieu-Daudé         features->dev_features =
559*28b629abSPhilippe Mathieu-Daudé             CONVERT_FEATURES(strList, virtio_net_feature_map, 0, bitmap);
560*28b629abSPhilippe Mathieu-Daudé         break;
561*28b629abSPhilippe Mathieu-Daudé #endif
562*28b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_SCSI
563*28b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_SCSI:
564*28b629abSPhilippe Mathieu-Daudé         features->dev_features =
565*28b629abSPhilippe Mathieu-Daudé             CONVERT_FEATURES(strList, virtio_scsi_feature_map, 0, bitmap);
566*28b629abSPhilippe Mathieu-Daudé         break;
567*28b629abSPhilippe Mathieu-Daudé #endif
568*28b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_BALLOON
569*28b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_BALLOON:
570*28b629abSPhilippe Mathieu-Daudé         features->dev_features =
571*28b629abSPhilippe Mathieu-Daudé             CONVERT_FEATURES(strList, virtio_balloon_feature_map, 0, bitmap);
572*28b629abSPhilippe Mathieu-Daudé         break;
573*28b629abSPhilippe Mathieu-Daudé #endif
574*28b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_IOMMU
575*28b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_IOMMU:
576*28b629abSPhilippe Mathieu-Daudé         features->dev_features =
577*28b629abSPhilippe Mathieu-Daudé             CONVERT_FEATURES(strList, virtio_iommu_feature_map, 0, bitmap);
578*28b629abSPhilippe Mathieu-Daudé         break;
579*28b629abSPhilippe Mathieu-Daudé #endif
580*28b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_INPUT
581*28b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_INPUT:
582*28b629abSPhilippe Mathieu-Daudé         features->dev_features =
583*28b629abSPhilippe Mathieu-Daudé             CONVERT_FEATURES(strList, virtio_input_feature_map, 0, bitmap);
584*28b629abSPhilippe Mathieu-Daudé         break;
585*28b629abSPhilippe Mathieu-Daudé #endif
586*28b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VHOST_USER_FS
587*28b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_FS:
588*28b629abSPhilippe Mathieu-Daudé         features->dev_features =
589*28b629abSPhilippe Mathieu-Daudé             CONVERT_FEATURES(strList, virtio_fs_feature_map, 0, bitmap);
590*28b629abSPhilippe Mathieu-Daudé         break;
591*28b629abSPhilippe Mathieu-Daudé #endif
592*28b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VHOST_VSOCK
593*28b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_VSOCK:
594*28b629abSPhilippe Mathieu-Daudé         features->dev_features =
595*28b629abSPhilippe Mathieu-Daudé             CONVERT_FEATURES(strList, virtio_vsock_feature_map, 0, bitmap);
596*28b629abSPhilippe Mathieu-Daudé         break;
597*28b629abSPhilippe Mathieu-Daudé #endif
598*28b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_CRYPTO
599*28b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_CRYPTO:
600*28b629abSPhilippe Mathieu-Daudé         features->dev_features =
601*28b629abSPhilippe Mathieu-Daudé             CONVERT_FEATURES(strList, virtio_crypto_feature_map, 0, bitmap);
602*28b629abSPhilippe Mathieu-Daudé         break;
603*28b629abSPhilippe Mathieu-Daudé #endif
604*28b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_MEM
605*28b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_MEM:
606*28b629abSPhilippe Mathieu-Daudé         features->dev_features =
607*28b629abSPhilippe Mathieu-Daudé             CONVERT_FEATURES(strList, virtio_mem_feature_map, 0, bitmap);
608*28b629abSPhilippe Mathieu-Daudé         break;
609*28b629abSPhilippe Mathieu-Daudé #endif
610*28b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_I2C_ADAPTER
611*28b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_I2C_ADAPTER:
612*28b629abSPhilippe Mathieu-Daudé         features->dev_features =
613*28b629abSPhilippe Mathieu-Daudé             CONVERT_FEATURES(strList, virtio_i2c_feature_map, 0, bitmap);
614*28b629abSPhilippe Mathieu-Daudé         break;
615*28b629abSPhilippe Mathieu-Daudé #endif
616*28b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_RNG
617*28b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_RNG:
618*28b629abSPhilippe Mathieu-Daudé         features->dev_features =
619*28b629abSPhilippe Mathieu-Daudé             CONVERT_FEATURES(strList, virtio_rng_feature_map, 0, bitmap);
620*28b629abSPhilippe Mathieu-Daudé         break;
621*28b629abSPhilippe Mathieu-Daudé #endif
622*28b629abSPhilippe Mathieu-Daudé     /* No features */
623*28b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_9P:
624*28b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_PMEM:
625*28b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_IOMEM:
626*28b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_RPMSG:
627*28b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_CLOCK:
628*28b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_MAC80211_WLAN:
629*28b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_MAC80211_HWSIM:
630*28b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_RPROC_SERIAL:
631*28b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_MEMORY_BALLOON:
632*28b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_CAIF:
633*28b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_SIGNAL_DIST:
634*28b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_PSTORE:
635*28b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_SOUND:
636*28b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_BT:
637*28b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_RPMB:
638*28b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_VIDEO_ENCODER:
639*28b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_VIDEO_DECODER:
640*28b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_SCMI:
641*28b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_NITRO_SEC_MOD:
642*28b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_WATCHDOG:
643*28b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_CAN:
644*28b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_DMABUF:
645*28b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_PARAM_SERV:
646*28b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_AUDIO_POLICY:
647*28b629abSPhilippe Mathieu-Daudé     case VIRTIO_ID_GPIO:
648*28b629abSPhilippe Mathieu-Daudé         break;
649*28b629abSPhilippe Mathieu-Daudé     default:
650*28b629abSPhilippe Mathieu-Daudé         g_assert_not_reached();
651*28b629abSPhilippe Mathieu-Daudé     }
652*28b629abSPhilippe Mathieu-Daudé 
653*28b629abSPhilippe Mathieu-Daudé     features->has_unknown_dev_features = bitmap != 0;
654*28b629abSPhilippe Mathieu-Daudé     if (features->has_unknown_dev_features) {
655*28b629abSPhilippe Mathieu-Daudé         features->unknown_dev_features = bitmap;
656*28b629abSPhilippe Mathieu-Daudé     }
657*28b629abSPhilippe Mathieu-Daudé 
658*28b629abSPhilippe Mathieu-Daudé     return features;
659*28b629abSPhilippe Mathieu-Daudé }
660