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