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 "virtio-qmp.h"
14
15 #include "qapi/error.h"
16 #include "qapi/qapi-commands-virtio.h"
17 #include "qapi/qapi-commands-qom.h"
18 #include "qapi/qmp/qobject.h"
19 #include "qapi/qmp/qjson.h"
20 #include "hw/virtio/vhost-user.h"
21
22 #include "standard-headers/linux/virtio_ids.h"
23 #include "standard-headers/linux/vhost_types.h"
24 #include "standard-headers/linux/virtio_blk.h"
25 #include "standard-headers/linux/virtio_console.h"
26 #include "standard-headers/linux/virtio_gpu.h"
27 #include "standard-headers/linux/virtio_net.h"
28 #include "standard-headers/linux/virtio_scsi.h"
29 #include "standard-headers/linux/virtio_i2c.h"
30 #include "standard-headers/linux/virtio_balloon.h"
31 #include "standard-headers/linux/virtio_iommu.h"
32 #include "standard-headers/linux/virtio_mem.h"
33 #include "standard-headers/linux/virtio_vsock.h"
34 #include "standard-headers/linux/virtio_gpio.h"
35
36 #include CONFIG_DEVICES
37
38 #define FEATURE_ENTRY(name, desc) (qmp_virtio_feature_map_t) \
39 { .virtio_bit = name, .feature_desc = desc }
40
41 /* Virtio transport features mapping */
42 static const qmp_virtio_feature_map_t virtio_transport_map[] = {
43 /* Virtio device transport features */
44 #ifndef VIRTIO_CONFIG_NO_LEGACY
45 FEATURE_ENTRY(VIRTIO_F_NOTIFY_ON_EMPTY, \
46 "VIRTIO_F_NOTIFY_ON_EMPTY: Notify when device runs out of avail. "
47 "descs. on VQ"),
48 FEATURE_ENTRY(VIRTIO_F_ANY_LAYOUT, \
49 "VIRTIO_F_ANY_LAYOUT: Device accepts arbitrary desc. layouts"),
50 #endif /* !VIRTIO_CONFIG_NO_LEGACY */
51 FEATURE_ENTRY(VIRTIO_F_VERSION_1, \
52 "VIRTIO_F_VERSION_1: Device compliant for v1 spec (legacy)"),
53 FEATURE_ENTRY(VIRTIO_F_IOMMU_PLATFORM, \
54 "VIRTIO_F_IOMMU_PLATFORM: Device can be used on IOMMU platform"),
55 FEATURE_ENTRY(VIRTIO_F_RING_PACKED, \
56 "VIRTIO_F_RING_PACKED: Device supports packed VQ layout"),
57 FEATURE_ENTRY(VIRTIO_F_IN_ORDER, \
58 "VIRTIO_F_IN_ORDER: Device uses buffers in same order as made "
59 "available by driver"),
60 FEATURE_ENTRY(VIRTIO_F_ORDER_PLATFORM, \
61 "VIRTIO_F_ORDER_PLATFORM: Memory accesses ordered by platform"),
62 FEATURE_ENTRY(VIRTIO_F_SR_IOV, \
63 "VIRTIO_F_SR_IOV: Device supports single root I/O virtualization"),
64 FEATURE_ENTRY(VIRTIO_F_RING_RESET, \
65 "VIRTIO_F_RING_RESET: Driver can reset a queue individually"),
66 /* Virtio ring transport features */
67 FEATURE_ENTRY(VIRTIO_RING_F_INDIRECT_DESC, \
68 "VIRTIO_RING_F_INDIRECT_DESC: Indirect descriptors supported"),
69 FEATURE_ENTRY(VIRTIO_RING_F_EVENT_IDX, \
70 "VIRTIO_RING_F_EVENT_IDX: Used & avail. event fields enabled"),
71 { -1, "" }
72 };
73
74 /* Vhost-user protocol features mapping */
75 static const qmp_virtio_feature_map_t vhost_user_protocol_map[] = {
76 FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_MQ, \
77 "VHOST_USER_PROTOCOL_F_MQ: Multiqueue protocol supported"),
78 FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_LOG_SHMFD, \
79 "VHOST_USER_PROTOCOL_F_LOG_SHMFD: Shared log memory fd supported"),
80 FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_RARP, \
81 "VHOST_USER_PROTOCOL_F_RARP: Vhost-user back-end RARP broadcasting "
82 "supported"),
83 FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_REPLY_ACK, \
84 "VHOST_USER_PROTOCOL_F_REPLY_ACK: Requested operation status ack. "
85 "supported"),
86 FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_NET_MTU, \
87 "VHOST_USER_PROTOCOL_F_NET_MTU: Expose host MTU to guest supported"),
88 FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_BACKEND_REQ, \
89 "VHOST_USER_PROTOCOL_F_BACKEND_REQ: Socket fd for back-end initiated "
90 "requests supported"),
91 FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_CROSS_ENDIAN, \
92 "VHOST_USER_PROTOCOL_F_CROSS_ENDIAN: Endianness of VQs for legacy "
93 "devices supported"),
94 FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_CRYPTO_SESSION, \
95 "VHOST_USER_PROTOCOL_F_CRYPTO_SESSION: Session creation for crypto "
96 "operations supported"),
97 FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_PAGEFAULT, \
98 "VHOST_USER_PROTOCOL_F_PAGEFAULT: Request servicing on userfaultfd "
99 "for accessed pages supported"),
100 FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_CONFIG, \
101 "VHOST_USER_PROTOCOL_F_CONFIG: Vhost-user messaging for virtio "
102 "device configuration space supported"),
103 FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_BACKEND_SEND_FD, \
104 "VHOST_USER_PROTOCOL_F_BACKEND_SEND_FD: Backend fd communication "
105 "channel supported"),
106 FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_HOST_NOTIFIER, \
107 "VHOST_USER_PROTOCOL_F_HOST_NOTIFIER: Host notifiers for specified "
108 "VQs supported"),
109 FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD, \
110 "VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD: Shared inflight I/O buffers "
111 "supported"),
112 FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_RESET_DEVICE, \
113 "VHOST_USER_PROTOCOL_F_RESET_DEVICE: Disabling all rings and "
114 "resetting internal device state supported"),
115 FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS, \
116 "VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS: In-band messaging "
117 "supported"),
118 FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS, \
119 "VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS: Configuration for "
120 "memory slots supported"),
121 FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_STATUS, \
122 "VHOST_USER_PROTOCOL_F_STATUS: Querying and notifying back-end "
123 "device status supported"),
124 { -1, "" }
125 };
126
127 /* virtio device configuration statuses */
128 static const qmp_virtio_feature_map_t virtio_config_status_map[] = {
129 FEATURE_ENTRY(VIRTIO_CONFIG_S_DRIVER_OK, \
130 "VIRTIO_CONFIG_S_DRIVER_OK: Driver setup and ready"),
131 FEATURE_ENTRY(VIRTIO_CONFIG_S_FEATURES_OK, \
132 "VIRTIO_CONFIG_S_FEATURES_OK: Feature negotiation complete"),
133 FEATURE_ENTRY(VIRTIO_CONFIG_S_DRIVER, \
134 "VIRTIO_CONFIG_S_DRIVER: Guest OS compatible with device"),
135 FEATURE_ENTRY(VIRTIO_CONFIG_S_NEEDS_RESET, \
136 "VIRTIO_CONFIG_S_NEEDS_RESET: Irrecoverable error, device needs "
137 "reset"),
138 FEATURE_ENTRY(VIRTIO_CONFIG_S_FAILED, \
139 "VIRTIO_CONFIG_S_FAILED: Error in guest, device failed"),
140 FEATURE_ENTRY(VIRTIO_CONFIG_S_ACKNOWLEDGE, \
141 "VIRTIO_CONFIG_S_ACKNOWLEDGE: Valid virtio device found"),
142 { -1, "" }
143 };
144
145 /* virtio-blk features mapping */
146 #ifdef CONFIG_VIRTIO_BLK
147 static const qmp_virtio_feature_map_t virtio_blk_feature_map[] = {
148 FEATURE_ENTRY(VIRTIO_BLK_F_SIZE_MAX, \
149 "VIRTIO_BLK_F_SIZE_MAX: Max segment size is size_max"),
150 FEATURE_ENTRY(VIRTIO_BLK_F_SEG_MAX, \
151 "VIRTIO_BLK_F_SEG_MAX: Max segments in a request is seg_max"),
152 FEATURE_ENTRY(VIRTIO_BLK_F_GEOMETRY, \
153 "VIRTIO_BLK_F_GEOMETRY: Legacy geometry available"),
154 FEATURE_ENTRY(VIRTIO_BLK_F_RO, \
155 "VIRTIO_BLK_F_RO: Device is read-only"),
156 FEATURE_ENTRY(VIRTIO_BLK_F_BLK_SIZE, \
157 "VIRTIO_BLK_F_BLK_SIZE: Block size of disk available"),
158 FEATURE_ENTRY(VIRTIO_BLK_F_TOPOLOGY, \
159 "VIRTIO_BLK_F_TOPOLOGY: Topology information available"),
160 FEATURE_ENTRY(VIRTIO_BLK_F_MQ, \
161 "VIRTIO_BLK_F_MQ: Multiqueue supported"),
162 FEATURE_ENTRY(VIRTIO_BLK_F_DISCARD, \
163 "VIRTIO_BLK_F_DISCARD: Discard command supported"),
164 FEATURE_ENTRY(VIRTIO_BLK_F_WRITE_ZEROES, \
165 "VIRTIO_BLK_F_WRITE_ZEROES: Write zeroes command supported"),
166 FEATURE_ENTRY(VIRTIO_BLK_F_SECURE_ERASE, \
167 "VIRTIO_BLK_F_SECURE_ERASE: Secure erase supported"),
168 FEATURE_ENTRY(VIRTIO_BLK_F_ZONED, \
169 "VIRTIO_BLK_F_ZONED: Zoned block devices"),
170 #ifndef VIRTIO_BLK_NO_LEGACY
171 FEATURE_ENTRY(VIRTIO_BLK_F_BARRIER, \
172 "VIRTIO_BLK_F_BARRIER: Request barriers supported"),
173 FEATURE_ENTRY(VIRTIO_BLK_F_SCSI, \
174 "VIRTIO_BLK_F_SCSI: SCSI packet commands supported"),
175 FEATURE_ENTRY(VIRTIO_BLK_F_FLUSH, \
176 "VIRTIO_BLK_F_FLUSH: Flush command supported"),
177 FEATURE_ENTRY(VIRTIO_BLK_F_CONFIG_WCE, \
178 "VIRTIO_BLK_F_CONFIG_WCE: Cache writeback and writethrough modes "
179 "supported"),
180 #endif /* !VIRTIO_BLK_NO_LEGACY */
181 FEATURE_ENTRY(VHOST_F_LOG_ALL, \
182 "VHOST_F_LOG_ALL: Logging write descriptors supported"),
183 FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
184 "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
185 "negotiation supported"),
186 { -1, "" }
187 };
188 #endif
189
190 /* virtio-serial features mapping */
191 #ifdef CONFIG_VIRTIO_SERIAL
192 static const qmp_virtio_feature_map_t virtio_serial_feature_map[] = {
193 FEATURE_ENTRY(VIRTIO_CONSOLE_F_SIZE, \
194 "VIRTIO_CONSOLE_F_SIZE: Host providing console size"),
195 FEATURE_ENTRY(VIRTIO_CONSOLE_F_MULTIPORT, \
196 "VIRTIO_CONSOLE_F_MULTIPORT: Multiple ports for device supported"),
197 FEATURE_ENTRY(VIRTIO_CONSOLE_F_EMERG_WRITE, \
198 "VIRTIO_CONSOLE_F_EMERG_WRITE: Emergency write supported"),
199 { -1, "" }
200 };
201 #endif
202
203 /* virtio-gpu features mapping */
204 #ifdef CONFIG_VIRTIO_GPU
205 static const qmp_virtio_feature_map_t virtio_gpu_feature_map[] = {
206 FEATURE_ENTRY(VIRTIO_GPU_F_VIRGL, \
207 "VIRTIO_GPU_F_VIRGL: Virgl 3D mode supported"),
208 FEATURE_ENTRY(VIRTIO_GPU_F_EDID, \
209 "VIRTIO_GPU_F_EDID: EDID metadata supported"),
210 FEATURE_ENTRY(VIRTIO_GPU_F_RESOURCE_UUID, \
211 "VIRTIO_GPU_F_RESOURCE_UUID: Resource UUID assigning supported"),
212 FEATURE_ENTRY(VIRTIO_GPU_F_RESOURCE_BLOB, \
213 "VIRTIO_GPU_F_RESOURCE_BLOB: Size-based blob resources supported"),
214 FEATURE_ENTRY(VIRTIO_GPU_F_CONTEXT_INIT, \
215 "VIRTIO_GPU_F_CONTEXT_INIT: Context types and synchronization "
216 "timelines supported"),
217 FEATURE_ENTRY(VHOST_F_LOG_ALL, \
218 "VHOST_F_LOG_ALL: Logging write descriptors supported"),
219 FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
220 "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
221 "negotiation supported"),
222 { -1, "" }
223 };
224 #endif
225
226 /* virtio-input features mapping */
227 #ifdef CONFIG_VIRTIO_INPUT
228 static const qmp_virtio_feature_map_t virtio_input_feature_map[] = {
229 FEATURE_ENTRY(VHOST_F_LOG_ALL, \
230 "VHOST_F_LOG_ALL: Logging write descriptors supported"),
231 FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
232 "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
233 "negotiation supported"),
234 { -1, "" }
235 };
236 #endif
237
238 /* virtio-net features mapping */
239 #ifdef CONFIG_VIRTIO_NET
240 static const qmp_virtio_feature_map_t virtio_net_feature_map[] = {
241 FEATURE_ENTRY(VIRTIO_NET_F_CSUM, \
242 "VIRTIO_NET_F_CSUM: Device handling packets with partial checksum "
243 "supported"),
244 FEATURE_ENTRY(VIRTIO_NET_F_GUEST_CSUM, \
245 "VIRTIO_NET_F_GUEST_CSUM: Driver handling packets with partial "
246 "checksum supported"),
247 FEATURE_ENTRY(VIRTIO_NET_F_CTRL_GUEST_OFFLOADS, \
248 "VIRTIO_NET_F_CTRL_GUEST_OFFLOADS: Control channel offloading "
249 "reconfig. supported"),
250 FEATURE_ENTRY(VIRTIO_NET_F_MTU, \
251 "VIRTIO_NET_F_MTU: Device max MTU reporting supported"),
252 FEATURE_ENTRY(VIRTIO_NET_F_MAC, \
253 "VIRTIO_NET_F_MAC: Device has given MAC address"),
254 FEATURE_ENTRY(VIRTIO_NET_F_GUEST_TSO4, \
255 "VIRTIO_NET_F_GUEST_TSO4: Driver can receive TSOv4"),
256 FEATURE_ENTRY(VIRTIO_NET_F_GUEST_TSO6, \
257 "VIRTIO_NET_F_GUEST_TSO6: Driver can receive TSOv6"),
258 FEATURE_ENTRY(VIRTIO_NET_F_GUEST_ECN, \
259 "VIRTIO_NET_F_GUEST_ECN: Driver can receive TSO with ECN"),
260 FEATURE_ENTRY(VIRTIO_NET_F_GUEST_UFO, \
261 "VIRTIO_NET_F_GUEST_UFO: Driver can receive UFO"),
262 FEATURE_ENTRY(VIRTIO_NET_F_HOST_TSO4, \
263 "VIRTIO_NET_F_HOST_TSO4: Device can receive TSOv4"),
264 FEATURE_ENTRY(VIRTIO_NET_F_HOST_TSO6, \
265 "VIRTIO_NET_F_HOST_TSO6: Device can receive TSOv6"),
266 FEATURE_ENTRY(VIRTIO_NET_F_HOST_ECN, \
267 "VIRTIO_NET_F_HOST_ECN: Device can receive TSO with ECN"),
268 FEATURE_ENTRY(VIRTIO_NET_F_HOST_UFO, \
269 "VIRTIO_NET_F_HOST_UFO: Device can receive UFO"),
270 FEATURE_ENTRY(VIRTIO_NET_F_MRG_RXBUF, \
271 "VIRTIO_NET_F_MRG_RXBUF: Driver can merge receive buffers"),
272 FEATURE_ENTRY(VIRTIO_NET_F_STATUS, \
273 "VIRTIO_NET_F_STATUS: Configuration status field available"),
274 FEATURE_ENTRY(VIRTIO_NET_F_CTRL_VQ, \
275 "VIRTIO_NET_F_CTRL_VQ: Control channel available"),
276 FEATURE_ENTRY(VIRTIO_NET_F_CTRL_RX, \
277 "VIRTIO_NET_F_CTRL_RX: Control channel RX mode supported"),
278 FEATURE_ENTRY(VIRTIO_NET_F_CTRL_VLAN, \
279 "VIRTIO_NET_F_CTRL_VLAN: Control channel VLAN filtering supported"),
280 FEATURE_ENTRY(VIRTIO_NET_F_CTRL_RX_EXTRA, \
281 "VIRTIO_NET_F_CTRL_RX_EXTRA: Extra RX mode control supported"),
282 FEATURE_ENTRY(VIRTIO_NET_F_GUEST_ANNOUNCE, \
283 "VIRTIO_NET_F_GUEST_ANNOUNCE: Driver sending gratuitous packets "
284 "supported"),
285 FEATURE_ENTRY(VIRTIO_NET_F_MQ, \
286 "VIRTIO_NET_F_MQ: Multiqueue with automatic receive steering "
287 "supported"),
288 FEATURE_ENTRY(VIRTIO_NET_F_CTRL_MAC_ADDR, \
289 "VIRTIO_NET_F_CTRL_MAC_ADDR: MAC address set through control "
290 "channel"),
291 FEATURE_ENTRY(VIRTIO_NET_F_NOTF_COAL, \
292 "VIRTIO_NET_F_NOTF_COAL: Device supports coalescing notifications"),
293 FEATURE_ENTRY(VIRTIO_NET_F_GUEST_USO4, \
294 "VIRTIO_NET_F_GUEST_USO4: Driver can receive USOv4"),
295 FEATURE_ENTRY(VIRTIO_NET_F_GUEST_USO6, \
296 "VIRTIO_NET_F_GUEST_USO4: Driver can receive USOv6"),
297 FEATURE_ENTRY(VIRTIO_NET_F_HOST_USO, \
298 "VIRTIO_NET_F_HOST_USO: Device can receive USO"),
299 FEATURE_ENTRY(VIRTIO_NET_F_HASH_REPORT, \
300 "VIRTIO_NET_F_HASH_REPORT: Hash reporting supported"),
301 FEATURE_ENTRY(VIRTIO_NET_F_RSS, \
302 "VIRTIO_NET_F_RSS: RSS RX steering supported"),
303 FEATURE_ENTRY(VIRTIO_NET_F_RSC_EXT, \
304 "VIRTIO_NET_F_RSC_EXT: Extended coalescing info supported"),
305 FEATURE_ENTRY(VIRTIO_NET_F_STANDBY, \
306 "VIRTIO_NET_F_STANDBY: Device acting as standby for primary "
307 "device with same MAC addr. supported"),
308 FEATURE_ENTRY(VIRTIO_NET_F_SPEED_DUPLEX, \
309 "VIRTIO_NET_F_SPEED_DUPLEX: Device set linkspeed and duplex"),
310 #ifndef VIRTIO_NET_NO_LEGACY
311 FEATURE_ENTRY(VIRTIO_NET_F_GSO, \
312 "VIRTIO_NET_F_GSO: Handling GSO-type packets supported"),
313 #endif /* !VIRTIO_NET_NO_LEGACY */
314 FEATURE_ENTRY(VHOST_NET_F_VIRTIO_NET_HDR, \
315 "VHOST_NET_F_VIRTIO_NET_HDR: Virtio-net headers for RX and TX "
316 "packets supported"),
317 FEATURE_ENTRY(VHOST_F_LOG_ALL, \
318 "VHOST_F_LOG_ALL: Logging write descriptors supported"),
319 FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
320 "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
321 "negotiation supported"),
322 { -1, "" }
323 };
324 #endif
325
326 /* virtio-scsi features mapping */
327 #ifdef CONFIG_VIRTIO_SCSI
328 static const qmp_virtio_feature_map_t virtio_scsi_feature_map[] = {
329 FEATURE_ENTRY(VIRTIO_SCSI_F_INOUT, \
330 "VIRTIO_SCSI_F_INOUT: Requests including read and writable data "
331 "buffers supported"),
332 FEATURE_ENTRY(VIRTIO_SCSI_F_HOTPLUG, \
333 "VIRTIO_SCSI_F_HOTPLUG: Reporting and handling hot-plug events "
334 "supported"),
335 FEATURE_ENTRY(VIRTIO_SCSI_F_CHANGE, \
336 "VIRTIO_SCSI_F_CHANGE: Reporting and handling LUN changes "
337 "supported"),
338 FEATURE_ENTRY(VIRTIO_SCSI_F_T10_PI, \
339 "VIRTIO_SCSI_F_T10_PI: T10 info included in request header"),
340 FEATURE_ENTRY(VHOST_F_LOG_ALL, \
341 "VHOST_F_LOG_ALL: Logging write descriptors supported"),
342 FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
343 "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
344 "negotiation supported"),
345 { -1, "" }
346 };
347 #endif
348
349 /* virtio/vhost-user-fs features mapping */
350 #ifdef CONFIG_VHOST_USER_FS
351 static const qmp_virtio_feature_map_t virtio_fs_feature_map[] = {
352 FEATURE_ENTRY(VHOST_F_LOG_ALL, \
353 "VHOST_F_LOG_ALL: Logging write descriptors supported"),
354 FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
355 "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
356 "negotiation supported"),
357 { -1, "" }
358 };
359 #endif
360
361 /* virtio/vhost-user-i2c features mapping */
362 #ifdef CONFIG_VIRTIO_I2C_ADAPTER
363 static const qmp_virtio_feature_map_t virtio_i2c_feature_map[] = {
364 FEATURE_ENTRY(VIRTIO_I2C_F_ZERO_LENGTH_REQUEST, \
365 "VIRTIO_I2C_F_ZERO_LEGNTH_REQUEST: Zero length requests supported"),
366 FEATURE_ENTRY(VHOST_F_LOG_ALL, \
367 "VHOST_F_LOG_ALL: Logging write descriptors supported"),
368 FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
369 "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
370 "negotiation supported"),
371 { -1, "" }
372 };
373 #endif
374
375 /* virtio/vhost-vsock features mapping */
376 #ifdef CONFIG_VHOST_VSOCK
377 static const qmp_virtio_feature_map_t virtio_vsock_feature_map[] = {
378 FEATURE_ENTRY(VIRTIO_VSOCK_F_SEQPACKET, \
379 "VIRTIO_VSOCK_F_SEQPACKET: SOCK_SEQPACKET supported"),
380 FEATURE_ENTRY(VHOST_F_LOG_ALL, \
381 "VHOST_F_LOG_ALL: Logging write descriptors supported"),
382 FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
383 "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
384 "negotiation supported"),
385 { -1, "" }
386 };
387 #endif
388
389 /* virtio-balloon features mapping */
390 #ifdef CONFIG_VIRTIO_BALLOON
391 static const qmp_virtio_feature_map_t virtio_balloon_feature_map[] = {
392 FEATURE_ENTRY(VIRTIO_BALLOON_F_MUST_TELL_HOST, \
393 "VIRTIO_BALLOON_F_MUST_TELL_HOST: Tell host before reclaiming "
394 "pages"),
395 FEATURE_ENTRY(VIRTIO_BALLOON_F_STATS_VQ, \
396 "VIRTIO_BALLOON_F_STATS_VQ: Guest memory stats VQ available"),
397 FEATURE_ENTRY(VIRTIO_BALLOON_F_DEFLATE_ON_OOM, \
398 "VIRTIO_BALLOON_F_DEFLATE_ON_OOM: Deflate balloon when guest OOM"),
399 FEATURE_ENTRY(VIRTIO_BALLOON_F_FREE_PAGE_HINT, \
400 "VIRTIO_BALLOON_F_FREE_PAGE_HINT: VQ reporting free pages enabled"),
401 FEATURE_ENTRY(VIRTIO_BALLOON_F_PAGE_POISON, \
402 "VIRTIO_BALLOON_F_PAGE_POISON: Guest page poisoning enabled"),
403 FEATURE_ENTRY(VIRTIO_BALLOON_F_REPORTING, \
404 "VIRTIO_BALLOON_F_REPORTING: Page reporting VQ enabled"),
405 { -1, "" }
406 };
407 #endif
408
409 /* virtio-crypto features mapping */
410 #ifdef CONFIG_VIRTIO_CRYPTO
411 static const qmp_virtio_feature_map_t virtio_crypto_feature_map[] = {
412 FEATURE_ENTRY(VHOST_F_LOG_ALL, \
413 "VHOST_F_LOG_ALL: Logging write descriptors supported"),
414 { -1, "" }
415 };
416 #endif
417
418 /* virtio-iommu features mapping */
419 #ifdef CONFIG_VIRTIO_IOMMU
420 static const qmp_virtio_feature_map_t virtio_iommu_feature_map[] = {
421 FEATURE_ENTRY(VIRTIO_IOMMU_F_INPUT_RANGE, \
422 "VIRTIO_IOMMU_F_INPUT_RANGE: Range of available virtual addrs. "
423 "available"),
424 FEATURE_ENTRY(VIRTIO_IOMMU_F_DOMAIN_RANGE, \
425 "VIRTIO_IOMMU_F_DOMAIN_RANGE: Number of supported domains "
426 "available"),
427 FEATURE_ENTRY(VIRTIO_IOMMU_F_MAP_UNMAP, \
428 "VIRTIO_IOMMU_F_MAP_UNMAP: Map and unmap requests available"),
429 FEATURE_ENTRY(VIRTIO_IOMMU_F_BYPASS, \
430 "VIRTIO_IOMMU_F_BYPASS: Endpoints not attached to domains are in "
431 "bypass mode"),
432 FEATURE_ENTRY(VIRTIO_IOMMU_F_PROBE, \
433 "VIRTIO_IOMMU_F_PROBE: Probe requests available"),
434 FEATURE_ENTRY(VIRTIO_IOMMU_F_MMIO, \
435 "VIRTIO_IOMMU_F_MMIO: VIRTIO_IOMMU_MAP_F_MMIO flag available"),
436 FEATURE_ENTRY(VIRTIO_IOMMU_F_BYPASS_CONFIG, \
437 "VIRTIO_IOMMU_F_BYPASS_CONFIG: Bypass field of IOMMU config "
438 "available"),
439 { -1, "" }
440 };
441 #endif
442
443 /* virtio-mem features mapping */
444 #ifdef CONFIG_VIRTIO_MEM
445 static const qmp_virtio_feature_map_t virtio_mem_feature_map[] = {
446 #ifndef CONFIG_ACPI
447 FEATURE_ENTRY(VIRTIO_MEM_F_ACPI_PXM, \
448 "VIRTIO_MEM_F_ACPI_PXM: node_id is an ACPI PXM and is valid"),
449 #endif /* !CONFIG_ACPI */
450 FEATURE_ENTRY(VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE, \
451 "VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE: Unplugged memory cannot be "
452 "accessed"),
453 FEATURE_ENTRY(VIRTIO_MEM_F_PERSISTENT_SUSPEND, \
454 "VIRTIO_MEM_F_PERSISTENT_SUSPND: Plugged memory will remain "
455 "plugged when suspending+resuming"),
456 { -1, "" }
457 };
458 #endif
459
460 /* virtio-rng features mapping */
461 #ifdef CONFIG_VIRTIO_RNG
462 static const qmp_virtio_feature_map_t virtio_rng_feature_map[] = {
463 FEATURE_ENTRY(VHOST_F_LOG_ALL, \
464 "VHOST_F_LOG_ALL: Logging write descriptors supported"),
465 FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
466 "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
467 "negotiation supported"),
468 { -1, "" }
469 };
470 #endif
471
472 /* virtio/vhost-gpio features mapping */
473 #ifdef CONFIG_VHOST_USER_GPIO
474 static const qmp_virtio_feature_map_t virtio_gpio_feature_map[] = {
475 FEATURE_ENTRY(VIRTIO_GPIO_F_IRQ, \
476 "VIRTIO_GPIO_F_IRQ: Device supports interrupts on GPIO lines"),
477 FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
478 "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
479 "negotiation supported"),
480 { -1, "" }
481 };
482 #endif
483
484 #define CONVERT_FEATURES(type, map, is_status, bitmap) \
485 ({ \
486 type *list = NULL; \
487 type *node; \
488 for (i = 0; map[i].virtio_bit != -1; i++) { \
489 if (is_status) { \
490 bit = map[i].virtio_bit; \
491 } \
492 else { \
493 bit = 1ULL << map[i].virtio_bit; \
494 } \
495 if ((bitmap & bit) == 0) { \
496 continue; \
497 } \
498 node = g_new0(type, 1); \
499 node->value = g_strdup(map[i].feature_desc); \
500 node->next = list; \
501 list = node; \
502 bitmap ^= bit; \
503 } \
504 list; \
505 })
506
qmp_decode_status(uint8_t bitmap)507 VirtioDeviceStatus *qmp_decode_status(uint8_t bitmap)
508 {
509 VirtioDeviceStatus *status;
510 uint8_t bit;
511 int i;
512
513 status = g_new0(VirtioDeviceStatus, 1);
514 status->statuses = CONVERT_FEATURES(strList, virtio_config_status_map,
515 1, bitmap);
516 status->has_unknown_statuses = bitmap != 0;
517 if (status->has_unknown_statuses) {
518 status->unknown_statuses = bitmap;
519 }
520
521 return status;
522 }
523
qmp_decode_protocols(uint64_t bitmap)524 VhostDeviceProtocols *qmp_decode_protocols(uint64_t bitmap)
525 {
526 VhostDeviceProtocols *vhu_protocols;
527 uint64_t bit;
528 int i;
529
530 vhu_protocols = g_new0(VhostDeviceProtocols, 1);
531 vhu_protocols->protocols =
532 CONVERT_FEATURES(strList,
533 vhost_user_protocol_map, 0, bitmap);
534 vhu_protocols->has_unknown_protocols = bitmap != 0;
535 if (vhu_protocols->has_unknown_protocols) {
536 vhu_protocols->unknown_protocols = bitmap;
537 }
538
539 return vhu_protocols;
540 }
541
qmp_decode_features(uint16_t device_id,uint64_t bitmap)542 VirtioDeviceFeatures *qmp_decode_features(uint16_t device_id, uint64_t bitmap)
543 {
544 VirtioDeviceFeatures *features;
545 uint64_t bit;
546 int i;
547
548 features = g_new0(VirtioDeviceFeatures, 1);
549 features->has_dev_features = true;
550
551 /* transport features */
552 features->transports = CONVERT_FEATURES(strList, virtio_transport_map, 0,
553 bitmap);
554
555 /* device features */
556 switch (device_id) {
557 #ifdef CONFIG_VIRTIO_SERIAL
558 case VIRTIO_ID_CONSOLE:
559 features->dev_features =
560 CONVERT_FEATURES(strList, virtio_serial_feature_map, 0, bitmap);
561 break;
562 #endif
563 #ifdef CONFIG_VIRTIO_BLK
564 case VIRTIO_ID_BLOCK:
565 features->dev_features =
566 CONVERT_FEATURES(strList, virtio_blk_feature_map, 0, bitmap);
567 break;
568 #endif
569 #ifdef CONFIG_VIRTIO_GPU
570 case VIRTIO_ID_GPU:
571 features->dev_features =
572 CONVERT_FEATURES(strList, virtio_gpu_feature_map, 0, bitmap);
573 break;
574 #endif
575 #ifdef CONFIG_VIRTIO_NET
576 case VIRTIO_ID_NET:
577 features->dev_features =
578 CONVERT_FEATURES(strList, virtio_net_feature_map, 0, bitmap);
579 break;
580 #endif
581 #ifdef CONFIG_VIRTIO_SCSI
582 case VIRTIO_ID_SCSI:
583 features->dev_features =
584 CONVERT_FEATURES(strList, virtio_scsi_feature_map, 0, bitmap);
585 break;
586 #endif
587 #ifdef CONFIG_VIRTIO_BALLOON
588 case VIRTIO_ID_BALLOON:
589 features->dev_features =
590 CONVERT_FEATURES(strList, virtio_balloon_feature_map, 0, bitmap);
591 break;
592 #endif
593 #ifdef CONFIG_VIRTIO_IOMMU
594 case VIRTIO_ID_IOMMU:
595 features->dev_features =
596 CONVERT_FEATURES(strList, virtio_iommu_feature_map, 0, bitmap);
597 break;
598 #endif
599 #ifdef CONFIG_VIRTIO_INPUT
600 case VIRTIO_ID_INPUT:
601 features->dev_features =
602 CONVERT_FEATURES(strList, virtio_input_feature_map, 0, bitmap);
603 break;
604 #endif
605 #ifdef CONFIG_VHOST_USER_FS
606 case VIRTIO_ID_FS:
607 features->dev_features =
608 CONVERT_FEATURES(strList, virtio_fs_feature_map, 0, bitmap);
609 break;
610 #endif
611 #ifdef CONFIG_VHOST_VSOCK
612 case VIRTIO_ID_VSOCK:
613 features->dev_features =
614 CONVERT_FEATURES(strList, virtio_vsock_feature_map, 0, bitmap);
615 break;
616 #endif
617 #ifdef CONFIG_VIRTIO_CRYPTO
618 case VIRTIO_ID_CRYPTO:
619 features->dev_features =
620 CONVERT_FEATURES(strList, virtio_crypto_feature_map, 0, bitmap);
621 break;
622 #endif
623 #ifdef CONFIG_VIRTIO_MEM
624 case VIRTIO_ID_MEM:
625 features->dev_features =
626 CONVERT_FEATURES(strList, virtio_mem_feature_map, 0, bitmap);
627 break;
628 #endif
629 #ifdef CONFIG_VIRTIO_I2C_ADAPTER
630 case VIRTIO_ID_I2C_ADAPTER:
631 features->dev_features =
632 CONVERT_FEATURES(strList, virtio_i2c_feature_map, 0, bitmap);
633 break;
634 #endif
635 #ifdef CONFIG_VIRTIO_RNG
636 case VIRTIO_ID_RNG:
637 features->dev_features =
638 CONVERT_FEATURES(strList, virtio_rng_feature_map, 0, bitmap);
639 break;
640 #endif
641 #ifdef CONFIG_VHOST_USER_GPIO
642 case VIRTIO_ID_GPIO:
643 features->dev_features =
644 CONVERT_FEATURES(strList, virtio_gpio_feature_map, 0, bitmap);
645 break;
646 #endif
647 /* No features */
648 case VIRTIO_ID_9P:
649 case VIRTIO_ID_PMEM:
650 case VIRTIO_ID_IOMEM:
651 case VIRTIO_ID_RPMSG:
652 case VIRTIO_ID_CLOCK:
653 case VIRTIO_ID_MAC80211_WLAN:
654 case VIRTIO_ID_MAC80211_HWSIM:
655 case VIRTIO_ID_RPROC_SERIAL:
656 case VIRTIO_ID_MEMORY_BALLOON:
657 case VIRTIO_ID_CAIF:
658 case VIRTIO_ID_SIGNAL_DIST:
659 case VIRTIO_ID_PSTORE:
660 case VIRTIO_ID_SOUND:
661 case VIRTIO_ID_BT:
662 case VIRTIO_ID_RPMB:
663 case VIRTIO_ID_VIDEO_ENCODER:
664 case VIRTIO_ID_VIDEO_DECODER:
665 case VIRTIO_ID_SCMI:
666 case VIRTIO_ID_NITRO_SEC_MOD:
667 case VIRTIO_ID_WATCHDOG:
668 case VIRTIO_ID_CAN:
669 case VIRTIO_ID_DMABUF:
670 case VIRTIO_ID_PARAM_SERV:
671 case VIRTIO_ID_AUDIO_POLICY:
672 break;
673 default:
674 g_assert_not_reached();
675 }
676
677 features->has_unknown_dev_features = bitmap != 0;
678 if (features->has_unknown_dev_features) {
679 features->unknown_dev_features = bitmap;
680 }
681
682 return features;
683 }
684
query_dev_child(Object * child,void * opaque)685 static int query_dev_child(Object *child, void *opaque)
686 {
687 VirtioInfoList **vdevs = opaque;
688 Object *dev = object_dynamic_cast(child, TYPE_VIRTIO_DEVICE);
689 if (dev != NULL && DEVICE(dev)->realized) {
690 VirtIODevice *vdev = VIRTIO_DEVICE(dev);
691 VirtioInfo *info = g_new(VirtioInfo, 1);
692
693 /* Get canonical path & name of device */
694 info->path = object_get_canonical_path(dev);
695 info->name = g_strdup(vdev->name);
696 QAPI_LIST_PREPEND(*vdevs, info);
697 }
698 return 0;
699 }
700
qmp_x_query_virtio(Error ** errp)701 VirtioInfoList *qmp_x_query_virtio(Error **errp)
702 {
703 VirtioInfoList *vdevs = NULL;
704
705 /* Query the QOM composition tree recursively for virtio devices */
706 object_child_foreach_recursive(object_get_root(), query_dev_child, &vdevs);
707 if (vdevs == NULL) {
708 error_setg(errp, "No virtio devices found");
709 }
710 return vdevs;
711 }
712
qmp_find_virtio_device(const char * path)713 VirtIODevice *qmp_find_virtio_device(const char *path)
714 {
715 /* Verify the canonical path is a realized virtio device */
716 Object *dev = object_dynamic_cast(object_resolve_path(path, NULL),
717 TYPE_VIRTIO_DEVICE);
718 if (!dev || !DEVICE(dev)->realized) {
719 return NULL;
720 }
721 return VIRTIO_DEVICE(dev);
722 }
723
qmp_x_query_virtio_status(const char * path,Error ** errp)724 VirtioStatus *qmp_x_query_virtio_status(const char *path, Error **errp)
725 {
726 VirtIODevice *vdev;
727 VirtioStatus *status;
728
729 vdev = qmp_find_virtio_device(path);
730 if (vdev == NULL) {
731 error_setg(errp, "Path %s is not a realized VirtIODevice", path);
732 return NULL;
733 }
734
735 status = g_new0(VirtioStatus, 1);
736 status->name = g_strdup(vdev->name);
737 status->device_id = vdev->device_id;
738 status->vhost_started = vdev->vhost_started;
739 status->guest_features = qmp_decode_features(vdev->device_id,
740 vdev->guest_features);
741 status->host_features = qmp_decode_features(vdev->device_id,
742 vdev->host_features);
743 status->backend_features = qmp_decode_features(vdev->device_id,
744 vdev->backend_features);
745
746 switch (vdev->device_endian) {
747 case VIRTIO_DEVICE_ENDIAN_LITTLE:
748 status->device_endian = g_strdup("little");
749 break;
750 case VIRTIO_DEVICE_ENDIAN_BIG:
751 status->device_endian = g_strdup("big");
752 break;
753 default:
754 status->device_endian = g_strdup("unknown");
755 break;
756 }
757
758 status->num_vqs = virtio_get_num_queues(vdev);
759 status->status = qmp_decode_status(vdev->status);
760 status->isr = vdev->isr;
761 status->queue_sel = vdev->queue_sel;
762 status->vm_running = vdev->vm_running;
763 status->broken = vdev->broken;
764 status->disabled = vdev->disabled;
765 status->use_started = vdev->use_started;
766 status->started = vdev->started;
767 status->start_on_kick = vdev->start_on_kick;
768 status->disable_legacy_check = vdev->disable_legacy_check;
769 status->bus_name = g_strdup(vdev->bus_name);
770 status->use_guest_notifier_mask = vdev->use_guest_notifier_mask;
771
772 if (vdev->vhost_started) {
773 VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
774 struct vhost_dev *hdev = vdc->get_vhost(vdev);
775
776 status->vhost_dev = g_new0(VhostStatus, 1);
777 status->vhost_dev->n_mem_sections = hdev->n_mem_sections;
778 status->vhost_dev->n_tmp_sections = hdev->n_tmp_sections;
779 status->vhost_dev->nvqs = hdev->nvqs;
780 status->vhost_dev->vq_index = hdev->vq_index;
781 status->vhost_dev->features =
782 qmp_decode_features(vdev->device_id, hdev->features);
783 status->vhost_dev->acked_features =
784 qmp_decode_features(vdev->device_id, hdev->acked_features);
785 status->vhost_dev->backend_features =
786 qmp_decode_features(vdev->device_id, hdev->backend_features);
787 status->vhost_dev->protocol_features =
788 qmp_decode_protocols(hdev->protocol_features);
789 status->vhost_dev->max_queues = hdev->max_queues;
790 status->vhost_dev->backend_cap = hdev->backend_cap;
791 status->vhost_dev->log_enabled = hdev->log_enabled;
792 status->vhost_dev->log_size = hdev->log_size;
793 }
794
795 return status;
796 }
797
qmp_x_query_virtio_vhost_queue_status(const char * path,uint16_t queue,Error ** errp)798 VirtVhostQueueStatus *qmp_x_query_virtio_vhost_queue_status(const char *path,
799 uint16_t queue,
800 Error **errp)
801 {
802 VirtIODevice *vdev;
803 VirtVhostQueueStatus *status;
804
805 vdev = qmp_find_virtio_device(path);
806 if (vdev == NULL) {
807 error_setg(errp, "Path %s is not a VirtIODevice", path);
808 return NULL;
809 }
810
811 if (!vdev->vhost_started) {
812 error_setg(errp, "Error: vhost device has not started yet");
813 return NULL;
814 }
815
816 VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
817 struct vhost_dev *hdev = vdc->get_vhost(vdev);
818
819 if (queue < hdev->vq_index || queue >= hdev->vq_index + hdev->nvqs) {
820 error_setg(errp, "Invalid vhost virtqueue number %d", queue);
821 return NULL;
822 }
823
824 status = g_new0(VirtVhostQueueStatus, 1);
825 status->name = g_strdup(vdev->name);
826 status->kick = hdev->vqs[queue].kick;
827 status->call = hdev->vqs[queue].call;
828 status->desc = (uintptr_t)hdev->vqs[queue].desc;
829 status->avail = (uintptr_t)hdev->vqs[queue].avail;
830 status->used = (uintptr_t)hdev->vqs[queue].used;
831 status->num = hdev->vqs[queue].num;
832 status->desc_phys = hdev->vqs[queue].desc_phys;
833 status->desc_size = hdev->vqs[queue].desc_size;
834 status->avail_phys = hdev->vqs[queue].avail_phys;
835 status->avail_size = hdev->vqs[queue].avail_size;
836 status->used_phys = hdev->vqs[queue].used_phys;
837 status->used_size = hdev->vqs[queue].used_size;
838
839 return status;
840 }
841