4 * Copyright IBM, Corp. 2007
7 * Anthony Liguori <aliguori@us.ibm.com>
9 * SPDX-License-Identifier: GPL-2.0-or-later
12 #include "qemu/osdep.h"
13 #include "virtio-qmp.h"
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"
21 #include "standard-headers/linux/virtio_ids.h"
22 #include "standard-headers/linux/vhost_types.h"
23 #include "standard-headers/linux/virtio_blk.h"
24 #include "standard-headers/linux/virtio_console.h"
25 #include "standard-headers/linux/virtio_gpu.h"
26 #include "standard-headers/linux/virtio_net.h"
27 #include "standard-headers/linux/virtio_scsi.h"
28 #include "standard-headers/linux/virtio_i2c.h"
29 #include "standard-headers/linux/virtio_balloon.h"
30 #include "standard-headers/linux/virtio_iommu.h"
31 #include "standard-headers/linux/virtio_mem.h"
32 #include "standard-headers/linux/virtio_vsock.h"
34 #include CONFIG_DEVICES
36 #define FEATURE_ENTRY(name, desc) (qmp_virtio_feature_map_t) \
37 { .virtio_bit = name, .feature_desc = desc }
39 enum VhostUserProtocolFeature
{
40 VHOST_USER_PROTOCOL_F_MQ
= 0,
41 VHOST_USER_PROTOCOL_F_LOG_SHMFD
= 1,
42 VHOST_USER_PROTOCOL_F_RARP
= 2,
43 VHOST_USER_PROTOCOL_F_REPLY_ACK
= 3,
44 VHOST_USER_PROTOCOL_F_NET_MTU
= 4,
45 VHOST_USER_PROTOCOL_F_BACKEND_REQ
= 5,
46 VHOST_USER_PROTOCOL_F_CROSS_ENDIAN
= 6,
47 VHOST_USER_PROTOCOL_F_CRYPTO_SESSION
= 7,
48 VHOST_USER_PROTOCOL_F_PAGEFAULT
= 8,
49 VHOST_USER_PROTOCOL_F_CONFIG
= 9,
50 VHOST_USER_PROTOCOL_F_BACKEND_SEND_FD
= 10,
51 VHOST_USER_PROTOCOL_F_HOST_NOTIFIER
= 11,
52 VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD
= 12,
53 VHOST_USER_PROTOCOL_F_RESET_DEVICE
= 13,
54 VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS
= 14,
55 VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS
= 15,
56 VHOST_USER_PROTOCOL_F_MAX
59 /* Virtio transport features mapping */
60 static const qmp_virtio_feature_map_t virtio_transport_map
[] = {
61 /* Virtio device transport features */
62 #ifndef VIRTIO_CONFIG_NO_LEGACY
63 FEATURE_ENTRY(VIRTIO_F_NOTIFY_ON_EMPTY
, \
64 "VIRTIO_F_NOTIFY_ON_EMPTY: Notify when device runs out of avail. "
66 FEATURE_ENTRY(VIRTIO_F_ANY_LAYOUT
, \
67 "VIRTIO_F_ANY_LAYOUT: Device accepts arbitrary desc. layouts"),
68 #endif /* !VIRTIO_CONFIG_NO_LEGACY */
69 FEATURE_ENTRY(VIRTIO_F_VERSION_1
, \
70 "VIRTIO_F_VERSION_1: Device compliant for v1 spec (legacy)"),
71 FEATURE_ENTRY(VIRTIO_F_IOMMU_PLATFORM
, \
72 "VIRTIO_F_IOMMU_PLATFORM: Device can be used on IOMMU platform"),
73 FEATURE_ENTRY(VIRTIO_F_RING_PACKED
, \
74 "VIRTIO_F_RING_PACKED: Device supports packed VQ layout"),
75 FEATURE_ENTRY(VIRTIO_F_IN_ORDER
, \
76 "VIRTIO_F_IN_ORDER: Device uses buffers in same order as made "
77 "available by driver"),
78 FEATURE_ENTRY(VIRTIO_F_ORDER_PLATFORM
, \
79 "VIRTIO_F_ORDER_PLATFORM: Memory accesses ordered by platform"),
80 FEATURE_ENTRY(VIRTIO_F_SR_IOV
, \
81 "VIRTIO_F_SR_IOV: Device supports single root I/O virtualization"),
82 /* Virtio ring transport features */
83 FEATURE_ENTRY(VIRTIO_RING_F_INDIRECT_DESC
, \
84 "VIRTIO_RING_F_INDIRECT_DESC: Indirect descriptors supported"),
85 FEATURE_ENTRY(VIRTIO_RING_F_EVENT_IDX
, \
86 "VIRTIO_RING_F_EVENT_IDX: Used & avail. event fields enabled"),
90 /* Vhost-user protocol features mapping */
91 static const qmp_virtio_feature_map_t vhost_user_protocol_map
[] = {
92 FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_MQ
, \
93 "VHOST_USER_PROTOCOL_F_MQ: Multiqueue protocol supported"),
94 FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_LOG_SHMFD
, \
95 "VHOST_USER_PROTOCOL_F_LOG_SHMFD: Shared log memory fd supported"),
96 FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_RARP
, \
97 "VHOST_USER_PROTOCOL_F_RARP: Vhost-user back-end RARP broadcasting "
99 FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_REPLY_ACK
, \
100 "VHOST_USER_PROTOCOL_F_REPLY_ACK: Requested operation status ack. "
102 FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_NET_MTU
, \
103 "VHOST_USER_PROTOCOL_F_NET_MTU: Expose host MTU to guest supported"),
104 FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_BACKEND_REQ
, \
105 "VHOST_USER_PROTOCOL_F_BACKEND_REQ: Socket fd for back-end initiated "
106 "requests supported"),
107 FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_CROSS_ENDIAN
, \
108 "VHOST_USER_PROTOCOL_F_CROSS_ENDIAN: Endianness of VQs for legacy "
109 "devices supported"),
110 FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_CRYPTO_SESSION
, \
111 "VHOST_USER_PROTOCOL_F_CRYPTO_SESSION: Session creation for crypto "
112 "operations supported"),
113 FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_PAGEFAULT
, \
114 "VHOST_USER_PROTOCOL_F_PAGEFAULT: Request servicing on userfaultfd "
115 "for accessed pages supported"),
116 FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_CONFIG
, \
117 "VHOST_USER_PROTOCOL_F_CONFIG: Vhost-user messaging for virtio "
118 "device configuration space supported"),
119 FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_BACKEND_SEND_FD
, \
120 "VHOST_USER_PROTOCOL_F_BACKEND_SEND_FD: Slave fd communication "
121 "channel supported"),
122 FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_HOST_NOTIFIER
, \
123 "VHOST_USER_PROTOCOL_F_HOST_NOTIFIER: Host notifiers for specified "
125 FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD
, \
126 "VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD: Shared inflight I/O buffers "
128 FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_RESET_DEVICE
, \
129 "VHOST_USER_PROTOCOL_F_RESET_DEVICE: Disabling all rings and "
130 "resetting internal device state supported"),
131 FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS
, \
132 "VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS: In-band messaging "
134 FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS
, \
135 "VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS: Configuration for "
136 "memory slots supported"),
140 /* virtio device configuration statuses */
141 static const qmp_virtio_feature_map_t virtio_config_status_map
[] = {
142 FEATURE_ENTRY(VIRTIO_CONFIG_S_DRIVER_OK
, \
143 "VIRTIO_CONFIG_S_DRIVER_OK: Driver setup and ready"),
144 FEATURE_ENTRY(VIRTIO_CONFIG_S_FEATURES_OK
, \
145 "VIRTIO_CONFIG_S_FEATURES_OK: Feature negotiation complete"),
146 FEATURE_ENTRY(VIRTIO_CONFIG_S_DRIVER
, \
147 "VIRTIO_CONFIG_S_DRIVER: Guest OS compatible with device"),
148 FEATURE_ENTRY(VIRTIO_CONFIG_S_NEEDS_RESET
, \
149 "VIRTIO_CONFIG_S_NEEDS_RESET: Irrecoverable error, device needs "
151 FEATURE_ENTRY(VIRTIO_CONFIG_S_FAILED
, \
152 "VIRTIO_CONFIG_S_FAILED: Error in guest, device failed"),
153 FEATURE_ENTRY(VIRTIO_CONFIG_S_ACKNOWLEDGE
, \
154 "VIRTIO_CONFIG_S_ACKNOWLEDGE: Valid virtio device found"),
158 /* virtio-blk features mapping */
159 #ifdef CONFIG_VIRTIO_BLK
160 static const qmp_virtio_feature_map_t virtio_blk_feature_map
[] = {
161 FEATURE_ENTRY(VIRTIO_BLK_F_SIZE_MAX
, \
162 "VIRTIO_BLK_F_SIZE_MAX: Max segment size is size_max"),
163 FEATURE_ENTRY(VIRTIO_BLK_F_SEG_MAX
, \
164 "VIRTIO_BLK_F_SEG_MAX: Max segments in a request is seg_max"),
165 FEATURE_ENTRY(VIRTIO_BLK_F_GEOMETRY
, \
166 "VIRTIO_BLK_F_GEOMETRY: Legacy geometry available"),
167 FEATURE_ENTRY(VIRTIO_BLK_F_RO
, \
168 "VIRTIO_BLK_F_RO: Device is read-only"),
169 FEATURE_ENTRY(VIRTIO_BLK_F_BLK_SIZE
, \
170 "VIRTIO_BLK_F_BLK_SIZE: Block size of disk available"),
171 FEATURE_ENTRY(VIRTIO_BLK_F_TOPOLOGY
, \
172 "VIRTIO_BLK_F_TOPOLOGY: Topology information available"),
173 FEATURE_ENTRY(VIRTIO_BLK_F_MQ
, \
174 "VIRTIO_BLK_F_MQ: Multiqueue supported"),
175 FEATURE_ENTRY(VIRTIO_BLK_F_DISCARD
, \
176 "VIRTIO_BLK_F_DISCARD: Discard command supported"),
177 FEATURE_ENTRY(VIRTIO_BLK_F_WRITE_ZEROES
, \
178 "VIRTIO_BLK_F_WRITE_ZEROES: Write zeroes command supported"),
179 #ifndef VIRTIO_BLK_NO_LEGACY
180 FEATURE_ENTRY(VIRTIO_BLK_F_BARRIER
, \
181 "VIRTIO_BLK_F_BARRIER: Request barriers supported"),
182 FEATURE_ENTRY(VIRTIO_BLK_F_SCSI
, \
183 "VIRTIO_BLK_F_SCSI: SCSI packet commands supported"),
184 FEATURE_ENTRY(VIRTIO_BLK_F_FLUSH
, \
185 "VIRTIO_BLK_F_FLUSH: Flush command supported"),
186 FEATURE_ENTRY(VIRTIO_BLK_F_CONFIG_WCE
, \
187 "VIRTIO_BLK_F_CONFIG_WCE: Cache writeback and writethrough modes "
189 #endif /* !VIRTIO_BLK_NO_LEGACY */
190 FEATURE_ENTRY(VHOST_F_LOG_ALL
, \
191 "VHOST_F_LOG_ALL: Logging write descriptors supported"),
192 FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES
, \
193 "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
194 "negotiation supported"),
199 /* virtio-serial features mapping */
200 #ifdef CONFIG_VIRTIO_SERIAL
201 static const qmp_virtio_feature_map_t virtio_serial_feature_map
[] = {
202 FEATURE_ENTRY(VIRTIO_CONSOLE_F_SIZE
, \
203 "VIRTIO_CONSOLE_F_SIZE: Host providing console size"),
204 FEATURE_ENTRY(VIRTIO_CONSOLE_F_MULTIPORT
, \
205 "VIRTIO_CONSOLE_F_MULTIPORT: Multiple ports for device supported"),
206 FEATURE_ENTRY(VIRTIO_CONSOLE_F_EMERG_WRITE
, \
207 "VIRTIO_CONSOLE_F_EMERG_WRITE: Emergency write supported"),
212 /* virtio-gpu features mapping */
213 #ifdef CONFIG_VIRTIO_GPU
214 static const qmp_virtio_feature_map_t virtio_gpu_feature_map
[] = {
215 FEATURE_ENTRY(VIRTIO_GPU_F_VIRGL
, \
216 "VIRTIO_GPU_F_VIRGL: Virgl 3D mode supported"),
217 FEATURE_ENTRY(VIRTIO_GPU_F_EDID
, \
218 "VIRTIO_GPU_F_EDID: EDID metadata supported"),
219 FEATURE_ENTRY(VIRTIO_GPU_F_RESOURCE_UUID
, \
220 "VIRTIO_GPU_F_RESOURCE_UUID: Resource UUID assigning supported"),
221 FEATURE_ENTRY(VIRTIO_GPU_F_RESOURCE_BLOB
, \
222 "VIRTIO_GPU_F_RESOURCE_BLOB: Size-based blob resources supported"),
223 FEATURE_ENTRY(VIRTIO_GPU_F_CONTEXT_INIT
, \
224 "VIRTIO_GPU_F_CONTEXT_INIT: Context types and synchronization "
225 "timelines supported"),
226 FEATURE_ENTRY(VHOST_F_LOG_ALL
, \
227 "VHOST_F_LOG_ALL: Logging write descriptors supported"),
228 FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES
, \
229 "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
230 "negotiation supported"),
235 /* virtio-input features mapping */
236 #ifdef CONFIG_VIRTIO_INPUT
237 static const qmp_virtio_feature_map_t virtio_input_feature_map
[] = {
238 FEATURE_ENTRY(VHOST_F_LOG_ALL
, \
239 "VHOST_F_LOG_ALL: Logging write descriptors supported"),
240 FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES
, \
241 "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
242 "negotiation supported"),
247 /* virtio-net features mapping */
248 #ifdef CONFIG_VIRTIO_NET
249 static const qmp_virtio_feature_map_t virtio_net_feature_map
[] = {
250 FEATURE_ENTRY(VIRTIO_NET_F_CSUM
, \
251 "VIRTIO_NET_F_CSUM: Device handling packets with partial checksum "
253 FEATURE_ENTRY(VIRTIO_NET_F_GUEST_CSUM
, \
254 "VIRTIO_NET_F_GUEST_CSUM: Driver handling packets with partial "
255 "checksum supported"),
256 FEATURE_ENTRY(VIRTIO_NET_F_CTRL_GUEST_OFFLOADS
, \
257 "VIRTIO_NET_F_CTRL_GUEST_OFFLOADS: Control channel offloading "
258 "reconfig. supported"),
259 FEATURE_ENTRY(VIRTIO_NET_F_MTU
, \
260 "VIRTIO_NET_F_MTU: Device max MTU reporting supported"),
261 FEATURE_ENTRY(VIRTIO_NET_F_MAC
, \
262 "VIRTIO_NET_F_MAC: Device has given MAC address"),
263 FEATURE_ENTRY(VIRTIO_NET_F_GUEST_TSO4
, \
264 "VIRTIO_NET_F_GUEST_TSO4: Driver can receive TSOv4"),
265 FEATURE_ENTRY(VIRTIO_NET_F_GUEST_TSO6
, \
266 "VIRTIO_NET_F_GUEST_TSO6: Driver can receive TSOv6"),
267 FEATURE_ENTRY(VIRTIO_NET_F_GUEST_ECN
, \
268 "VIRTIO_NET_F_GUEST_ECN: Driver can receive TSO with ECN"),
269 FEATURE_ENTRY(VIRTIO_NET_F_GUEST_UFO
, \
270 "VIRTIO_NET_F_GUEST_UFO: Driver can receive UFO"),
271 FEATURE_ENTRY(VIRTIO_NET_F_HOST_TSO4
, \
272 "VIRTIO_NET_F_HOST_TSO4: Device can receive TSOv4"),
273 FEATURE_ENTRY(VIRTIO_NET_F_HOST_TSO6
, \
274 "VIRTIO_NET_F_HOST_TSO6: Device can receive TSOv6"),
275 FEATURE_ENTRY(VIRTIO_NET_F_HOST_ECN
, \
276 "VIRTIO_NET_F_HOST_ECN: Device can receive TSO with ECN"),
277 FEATURE_ENTRY(VIRTIO_NET_F_HOST_UFO
, \
278 "VIRTIO_NET_F_HOST_UFO: Device can receive UFO"),
279 FEATURE_ENTRY(VIRTIO_NET_F_MRG_RXBUF
, \
280 "VIRTIO_NET_F_MRG_RXBUF: Driver can merge receive buffers"),
281 FEATURE_ENTRY(VIRTIO_NET_F_STATUS
, \
282 "VIRTIO_NET_F_STATUS: Configuration status field available"),
283 FEATURE_ENTRY(VIRTIO_NET_F_CTRL_VQ
, \
284 "VIRTIO_NET_F_CTRL_VQ: Control channel available"),
285 FEATURE_ENTRY(VIRTIO_NET_F_CTRL_RX
, \
286 "VIRTIO_NET_F_CTRL_RX: Control channel RX mode supported"),
287 FEATURE_ENTRY(VIRTIO_NET_F_CTRL_VLAN
, \
288 "VIRTIO_NET_F_CTRL_VLAN: Control channel VLAN filtering supported"),
289 FEATURE_ENTRY(VIRTIO_NET_F_CTRL_RX_EXTRA
, \
290 "VIRTIO_NET_F_CTRL_RX_EXTRA: Extra RX mode control supported"),
291 FEATURE_ENTRY(VIRTIO_NET_F_GUEST_ANNOUNCE
, \
292 "VIRTIO_NET_F_GUEST_ANNOUNCE: Driver sending gratuitous packets "
294 FEATURE_ENTRY(VIRTIO_NET_F_MQ
, \
295 "VIRTIO_NET_F_MQ: Multiqueue with automatic receive steering "
297 FEATURE_ENTRY(VIRTIO_NET_F_CTRL_MAC_ADDR
, \
298 "VIRTIO_NET_F_CTRL_MAC_ADDR: MAC address set through control "
300 FEATURE_ENTRY(VIRTIO_NET_F_HASH_REPORT
, \
301 "VIRTIO_NET_F_HASH_REPORT: Hash reporting supported"),
302 FEATURE_ENTRY(VIRTIO_NET_F_RSS
, \
303 "VIRTIO_NET_F_RSS: RSS RX steering supported"),
304 FEATURE_ENTRY(VIRTIO_NET_F_RSC_EXT
, \
305 "VIRTIO_NET_F_RSC_EXT: Extended coalescing info supported"),
306 FEATURE_ENTRY(VIRTIO_NET_F_STANDBY
, \
307 "VIRTIO_NET_F_STANDBY: Device acting as standby for primary "
308 "device with same MAC addr. supported"),
309 FEATURE_ENTRY(VIRTIO_NET_F_SPEED_DUPLEX
, \
310 "VIRTIO_NET_F_SPEED_DUPLEX: Device set linkspeed and duplex"),
311 #ifndef VIRTIO_NET_NO_LEGACY
312 FEATURE_ENTRY(VIRTIO_NET_F_GSO
, \
313 "VIRTIO_NET_F_GSO: Handling GSO-type packets supported"),
314 #endif /* !VIRTIO_NET_NO_LEGACY */
315 FEATURE_ENTRY(VHOST_NET_F_VIRTIO_NET_HDR
, \
316 "VHOST_NET_F_VIRTIO_NET_HDR: Virtio-net headers for RX and TX "
317 "packets supported"),
318 FEATURE_ENTRY(VHOST_F_LOG_ALL
, \
319 "VHOST_F_LOG_ALL: Logging write descriptors supported"),
320 FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES
, \
321 "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
322 "negotiation supported"),
327 /* virtio-scsi features mapping */
328 #ifdef CONFIG_VIRTIO_SCSI
329 static const qmp_virtio_feature_map_t virtio_scsi_feature_map
[] = {
330 FEATURE_ENTRY(VIRTIO_SCSI_F_INOUT
, \
331 "VIRTIO_SCSI_F_INOUT: Requests including read and writable data "
333 FEATURE_ENTRY(VIRTIO_SCSI_F_HOTPLUG
, \
334 "VIRTIO_SCSI_F_HOTPLUG: Reporting and handling hot-plug events "
336 FEATURE_ENTRY(VIRTIO_SCSI_F_CHANGE
, \
337 "VIRTIO_SCSI_F_CHANGE: Reporting and handling LUN changes "
339 FEATURE_ENTRY(VIRTIO_SCSI_F_T10_PI
, \
340 "VIRTIO_SCSI_F_T10_PI: T10 info included in request header"),
341 FEATURE_ENTRY(VHOST_F_LOG_ALL
, \
342 "VHOST_F_LOG_ALL: Logging write descriptors supported"),
343 FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES
, \
344 "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
345 "negotiation supported"),
350 /* virtio/vhost-user-fs features mapping */
351 #ifdef CONFIG_VHOST_USER_FS
352 static const qmp_virtio_feature_map_t virtio_fs_feature_map
[] = {
353 FEATURE_ENTRY(VHOST_F_LOG_ALL
, \
354 "VHOST_F_LOG_ALL: Logging write descriptors supported"),
355 FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES
, \
356 "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
357 "negotiation supported"),
362 /* virtio/vhost-user-i2c features mapping */
363 #ifdef CONFIG_VIRTIO_I2C_ADAPTER
364 static const qmp_virtio_feature_map_t virtio_i2c_feature_map
[] = {
365 FEATURE_ENTRY(VIRTIO_I2C_F_ZERO_LENGTH_REQUEST
, \
366 "VIRTIO_I2C_F_ZERO_LEGNTH_REQUEST: Zero length requests supported"),
367 FEATURE_ENTRY(VHOST_F_LOG_ALL
, \
368 "VHOST_F_LOG_ALL: Logging write descriptors supported"),
369 FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES
, \
370 "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
371 "negotiation supported"),
376 /* virtio/vhost-vsock features mapping */
377 #ifdef CONFIG_VHOST_VSOCK
378 static const qmp_virtio_feature_map_t virtio_vsock_feature_map
[] = {
379 FEATURE_ENTRY(VIRTIO_VSOCK_F_SEQPACKET
, \
380 "VIRTIO_VSOCK_F_SEQPACKET: SOCK_SEQPACKET supported"),
381 FEATURE_ENTRY(VHOST_F_LOG_ALL
, \
382 "VHOST_F_LOG_ALL: Logging write descriptors supported"),
383 FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES
, \
384 "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
385 "negotiation supported"),
390 /* virtio-balloon features mapping */
391 #ifdef CONFIG_VIRTIO_BALLOON
392 static const qmp_virtio_feature_map_t virtio_balloon_feature_map
[] = {
393 FEATURE_ENTRY(VIRTIO_BALLOON_F_MUST_TELL_HOST
, \
394 "VIRTIO_BALLOON_F_MUST_TELL_HOST: Tell host before reclaiming "
396 FEATURE_ENTRY(VIRTIO_BALLOON_F_STATS_VQ
, \
397 "VIRTIO_BALLOON_F_STATS_VQ: Guest memory stats VQ available"),
398 FEATURE_ENTRY(VIRTIO_BALLOON_F_DEFLATE_ON_OOM
, \
399 "VIRTIO_BALLOON_F_DEFLATE_ON_OOM: Deflate balloon when guest OOM"),
400 FEATURE_ENTRY(VIRTIO_BALLOON_F_FREE_PAGE_HINT
, \
401 "VIRTIO_BALLOON_F_FREE_PAGE_HINT: VQ reporting free pages enabled"),
402 FEATURE_ENTRY(VIRTIO_BALLOON_F_PAGE_POISON
, \
403 "VIRTIO_BALLOON_F_PAGE_POISON: Guest page poisoning enabled"),
404 FEATURE_ENTRY(VIRTIO_BALLOON_F_REPORTING
, \
405 "VIRTIO_BALLOON_F_REPORTING: Page reporting VQ enabled"),
410 /* virtio-crypto features mapping */
411 #ifdef CONFIG_VIRTIO_CRYPTO
412 static const qmp_virtio_feature_map_t virtio_crypto_feature_map
[] = {
413 FEATURE_ENTRY(VHOST_F_LOG_ALL
, \
414 "VHOST_F_LOG_ALL: Logging write descriptors supported"),
419 /* virtio-iommu features mapping */
420 #ifdef CONFIG_VIRTIO_IOMMU
421 static const qmp_virtio_feature_map_t virtio_iommu_feature_map
[] = {
422 FEATURE_ENTRY(VIRTIO_IOMMU_F_INPUT_RANGE
, \
423 "VIRTIO_IOMMU_F_INPUT_RANGE: Range of available virtual addrs. "
425 FEATURE_ENTRY(VIRTIO_IOMMU_F_DOMAIN_RANGE
, \
426 "VIRTIO_IOMMU_F_DOMAIN_RANGE: Number of supported domains "
428 FEATURE_ENTRY(VIRTIO_IOMMU_F_MAP_UNMAP
, \
429 "VIRTIO_IOMMU_F_MAP_UNMAP: Map and unmap requests available"),
430 FEATURE_ENTRY(VIRTIO_IOMMU_F_BYPASS
, \
431 "VIRTIO_IOMMU_F_BYPASS: Endpoints not attached to domains are in "
433 FEATURE_ENTRY(VIRTIO_IOMMU_F_PROBE
, \
434 "VIRTIO_IOMMU_F_PROBE: Probe requests available"),
435 FEATURE_ENTRY(VIRTIO_IOMMU_F_MMIO
, \
436 "VIRTIO_IOMMU_F_MMIO: VIRTIO_IOMMU_MAP_F_MMIO flag available"),
437 FEATURE_ENTRY(VIRTIO_IOMMU_F_BYPASS_CONFIG
, \
438 "VIRTIO_IOMMU_F_BYPASS_CONFIG: Bypass field of IOMMU config "
444 /* virtio-mem features mapping */
445 #ifdef CONFIG_VIRTIO_MEM
446 static const qmp_virtio_feature_map_t virtio_mem_feature_map
[] = {
448 FEATURE_ENTRY(VIRTIO_MEM_F_ACPI_PXM
, \
449 "VIRTIO_MEM_F_ACPI_PXM: node_id is an ACPI PXM and is valid"),
450 #endif /* !CONFIG_ACPI */
451 FEATURE_ENTRY(VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE
, \
452 "VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE: Unplugged memory cannot be "
458 /* virtio-rng features mapping */
459 #ifdef CONFIG_VIRTIO_RNG
460 static const qmp_virtio_feature_map_t virtio_rng_feature_map
[] = {
461 FEATURE_ENTRY(VHOST_F_LOG_ALL
, \
462 "VHOST_F_LOG_ALL: Logging write descriptors supported"),
463 FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES
, \
464 "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
465 "negotiation supported"),
470 #define CONVERT_FEATURES(type, map, is_status, bitmap) \
474 for (i = 0; map[i].virtio_bit != -1; i++) { \
476 bit = map[i].virtio_bit; \
479 bit = 1ULL << map[i].virtio_bit; \
481 if ((bitmap & bit) == 0) { \
484 node = g_new0(type, 1); \
485 node->value = g_strdup(map[i].feature_desc); \
493 VirtioDeviceStatus
*qmp_decode_status(uint8_t bitmap
)
495 VirtioDeviceStatus
*status
;
499 status
= g_new0(VirtioDeviceStatus
, 1);
500 status
->statuses
= CONVERT_FEATURES(strList
, virtio_config_status_map
,
502 status
->has_unknown_statuses
= bitmap
!= 0;
503 if (status
->has_unknown_statuses
) {
504 status
->unknown_statuses
= bitmap
;
510 VhostDeviceProtocols
*qmp_decode_protocols(uint64_t bitmap
)
512 VhostDeviceProtocols
*vhu_protocols
;
516 vhu_protocols
= g_new0(VhostDeviceProtocols
, 1);
517 vhu_protocols
->protocols
=
518 CONVERT_FEATURES(strList
,
519 vhost_user_protocol_map
, 0, bitmap
);
520 vhu_protocols
->has_unknown_protocols
= bitmap
!= 0;
521 if (vhu_protocols
->has_unknown_protocols
) {
522 vhu_protocols
->unknown_protocols
= bitmap
;
525 return vhu_protocols
;
528 VirtioDeviceFeatures
*qmp_decode_features(uint16_t device_id
, uint64_t bitmap
)
530 VirtioDeviceFeatures
*features
;
534 features
= g_new0(VirtioDeviceFeatures
, 1);
535 features
->has_dev_features
= true;
537 /* transport features */
538 features
->transports
= CONVERT_FEATURES(strList
, virtio_transport_map
, 0,
541 /* device features */
543 #ifdef CONFIG_VIRTIO_SERIAL
544 case VIRTIO_ID_CONSOLE
:
545 features
->dev_features
=
546 CONVERT_FEATURES(strList
, virtio_serial_feature_map
, 0, bitmap
);
549 #ifdef CONFIG_VIRTIO_BLK
550 case VIRTIO_ID_BLOCK
:
551 features
->dev_features
=
552 CONVERT_FEATURES(strList
, virtio_blk_feature_map
, 0, bitmap
);
555 #ifdef CONFIG_VIRTIO_GPU
557 features
->dev_features
=
558 CONVERT_FEATURES(strList
, virtio_gpu_feature_map
, 0, bitmap
);
561 #ifdef CONFIG_VIRTIO_NET
563 features
->dev_features
=
564 CONVERT_FEATURES(strList
, virtio_net_feature_map
, 0, bitmap
);
567 #ifdef CONFIG_VIRTIO_SCSI
569 features
->dev_features
=
570 CONVERT_FEATURES(strList
, virtio_scsi_feature_map
, 0, bitmap
);
573 #ifdef CONFIG_VIRTIO_BALLOON
574 case VIRTIO_ID_BALLOON
:
575 features
->dev_features
=
576 CONVERT_FEATURES(strList
, virtio_balloon_feature_map
, 0, bitmap
);
579 #ifdef CONFIG_VIRTIO_IOMMU
580 case VIRTIO_ID_IOMMU
:
581 features
->dev_features
=
582 CONVERT_FEATURES(strList
, virtio_iommu_feature_map
, 0, bitmap
);
585 #ifdef CONFIG_VIRTIO_INPUT
586 case VIRTIO_ID_INPUT
:
587 features
->dev_features
=
588 CONVERT_FEATURES(strList
, virtio_input_feature_map
, 0, bitmap
);
591 #ifdef CONFIG_VHOST_USER_FS
593 features
->dev_features
=
594 CONVERT_FEATURES(strList
, virtio_fs_feature_map
, 0, bitmap
);
597 #ifdef CONFIG_VHOST_VSOCK
598 case VIRTIO_ID_VSOCK
:
599 features
->dev_features
=
600 CONVERT_FEATURES(strList
, virtio_vsock_feature_map
, 0, bitmap
);
603 #ifdef CONFIG_VIRTIO_CRYPTO
604 case VIRTIO_ID_CRYPTO
:
605 features
->dev_features
=
606 CONVERT_FEATURES(strList
, virtio_crypto_feature_map
, 0, bitmap
);
609 #ifdef CONFIG_VIRTIO_MEM
611 features
->dev_features
=
612 CONVERT_FEATURES(strList
, virtio_mem_feature_map
, 0, bitmap
);
615 #ifdef CONFIG_VIRTIO_I2C_ADAPTER
616 case VIRTIO_ID_I2C_ADAPTER
:
617 features
->dev_features
=
618 CONVERT_FEATURES(strList
, virtio_i2c_feature_map
, 0, bitmap
);
621 #ifdef CONFIG_VIRTIO_RNG
623 features
->dev_features
=
624 CONVERT_FEATURES(strList
, virtio_rng_feature_map
, 0, bitmap
);
630 case VIRTIO_ID_IOMEM
:
631 case VIRTIO_ID_RPMSG
:
632 case VIRTIO_ID_CLOCK
:
633 case VIRTIO_ID_MAC80211_WLAN
:
634 case VIRTIO_ID_MAC80211_HWSIM
:
635 case VIRTIO_ID_RPROC_SERIAL
:
636 case VIRTIO_ID_MEMORY_BALLOON
:
638 case VIRTIO_ID_SIGNAL_DIST
:
639 case VIRTIO_ID_PSTORE
:
640 case VIRTIO_ID_SOUND
:
643 case VIRTIO_ID_VIDEO_ENCODER
:
644 case VIRTIO_ID_VIDEO_DECODER
:
646 case VIRTIO_ID_NITRO_SEC_MOD
:
647 case VIRTIO_ID_WATCHDOG
:
649 case VIRTIO_ID_DMABUF
:
650 case VIRTIO_ID_PARAM_SERV
:
651 case VIRTIO_ID_AUDIO_POLICY
:
655 g_assert_not_reached();
658 features
->has_unknown_dev_features
= bitmap
!= 0;
659 if (features
->has_unknown_dev_features
) {
660 features
->unknown_dev_features
= bitmap
;
666 VirtioInfoList
*qmp_x_query_virtio(Error
**errp
)
668 VirtioInfoList
*list
= NULL
;
669 VirtioInfoList
*node
;
672 QTAILQ_FOREACH(vdev
, &virtio_list
, next
) {
673 DeviceState
*dev
= DEVICE(vdev
);
675 QObject
*obj
= qmp_qom_get(dev
->canonical_path
, "realized", &err
);
678 GString
*is_realized
= qobject_to_json_pretty(obj
, true);
679 /* virtio device is NOT realized, remove it from list */
680 if (!strncmp(is_realized
->str
, "false", 4)) {
681 QTAILQ_REMOVE(&virtio_list
, vdev
, next
);
683 node
= g_new0(VirtioInfoList
, 1);
684 node
->value
= g_new(VirtioInfo
, 1);
685 node
->value
->path
= g_strdup(dev
->canonical_path
);
686 node
->value
->name
= g_strdup(vdev
->name
);
687 QAPI_LIST_PREPEND(list
, node
->value
);
689 g_string_free(is_realized
, true);
697 VirtIODevice
*qmp_find_virtio_device(const char *path
)
701 QTAILQ_FOREACH(vdev
, &virtio_list
, next
) {
702 DeviceState
*dev
= DEVICE(vdev
);
704 if (strcmp(dev
->canonical_path
, path
) != 0) {
709 QObject
*obj
= qmp_qom_get(dev
->canonical_path
, "realized", &err
);
711 GString
*is_realized
= qobject_to_json_pretty(obj
, true);
712 /* virtio device is NOT realized, remove it from list */
713 if (!strncmp(is_realized
->str
, "false", 4)) {
714 g_string_free(is_realized
, true);
716 QTAILQ_REMOVE(&virtio_list
, vdev
, next
);
719 g_string_free(is_realized
, true);
721 /* virtio device doesn't exist in QOM tree */
722 QTAILQ_REMOVE(&virtio_list
, vdev
, next
);
726 /* device exists in QOM tree & is realized */
733 VirtioStatus
*qmp_x_query_virtio_status(const char *path
, Error
**errp
)
736 VirtioStatus
*status
;
738 vdev
= qmp_find_virtio_device(path
);
740 error_setg(errp
, "Path %s is not a VirtIODevice", path
);
744 status
= g_new0(VirtioStatus
, 1);
745 status
->name
= g_strdup(vdev
->name
);
746 status
->device_id
= vdev
->device_id
;
747 status
->vhost_started
= vdev
->vhost_started
;
748 status
->guest_features
= qmp_decode_features(vdev
->device_id
,
749 vdev
->guest_features
);
750 status
->host_features
= qmp_decode_features(vdev
->device_id
,
751 vdev
->host_features
);
752 status
->backend_features
= qmp_decode_features(vdev
->device_id
,
753 vdev
->backend_features
);
755 switch (vdev
->device_endian
) {
756 case VIRTIO_DEVICE_ENDIAN_LITTLE
:
757 status
->device_endian
= g_strdup("little");
759 case VIRTIO_DEVICE_ENDIAN_BIG
:
760 status
->device_endian
= g_strdup("big");
763 status
->device_endian
= g_strdup("unknown");
767 status
->num_vqs
= virtio_get_num_queues(vdev
);
768 status
->status
= qmp_decode_status(vdev
->status
);
769 status
->isr
= vdev
->isr
;
770 status
->queue_sel
= vdev
->queue_sel
;
771 status
->vm_running
= vdev
->vm_running
;
772 status
->broken
= vdev
->broken
;
773 status
->disabled
= vdev
->disabled
;
774 status
->use_started
= vdev
->use_started
;
775 status
->started
= vdev
->started
;
776 status
->start_on_kick
= vdev
->start_on_kick
;
777 status
->disable_legacy_check
= vdev
->disable_legacy_check
;
778 status
->bus_name
= g_strdup(vdev
->bus_name
);
779 status
->use_guest_notifier_mask
= vdev
->use_guest_notifier_mask
;
781 if (vdev
->vhost_started
) {
782 VirtioDeviceClass
*vdc
= VIRTIO_DEVICE_GET_CLASS(vdev
);
783 struct vhost_dev
*hdev
= vdc
->get_vhost(vdev
);
785 status
->vhost_dev
= g_new0(VhostStatus
, 1);
786 status
->vhost_dev
->n_mem_sections
= hdev
->n_mem_sections
;
787 status
->vhost_dev
->n_tmp_sections
= hdev
->n_tmp_sections
;
788 status
->vhost_dev
->nvqs
= hdev
->nvqs
;
789 status
->vhost_dev
->vq_index
= hdev
->vq_index
;
790 status
->vhost_dev
->features
=
791 qmp_decode_features(vdev
->device_id
, hdev
->features
);
792 status
->vhost_dev
->acked_features
=
793 qmp_decode_features(vdev
->device_id
, hdev
->acked_features
);
794 status
->vhost_dev
->backend_features
=
795 qmp_decode_features(vdev
->device_id
, hdev
->backend_features
);
796 status
->vhost_dev
->protocol_features
=
797 qmp_decode_protocols(hdev
->protocol_features
);
798 status
->vhost_dev
->max_queues
= hdev
->max_queues
;
799 status
->vhost_dev
->backend_cap
= hdev
->backend_cap
;
800 status
->vhost_dev
->log_enabled
= hdev
->log_enabled
;
801 status
->vhost_dev
->log_size
= hdev
->log_size
;
807 VirtVhostQueueStatus
*qmp_x_query_virtio_vhost_queue_status(const char *path
,
812 VirtVhostQueueStatus
*status
;
814 vdev
= qmp_find_virtio_device(path
);
816 error_setg(errp
, "Path %s is not a VirtIODevice", path
);
820 if (!vdev
->vhost_started
) {
821 error_setg(errp
, "Error: vhost device has not started yet");
825 VirtioDeviceClass
*vdc
= VIRTIO_DEVICE_GET_CLASS(vdev
);
826 struct vhost_dev
*hdev
= vdc
->get_vhost(vdev
);
828 if (queue
< hdev
->vq_index
|| queue
>= hdev
->vq_index
+ hdev
->nvqs
) {
829 error_setg(errp
, "Invalid vhost virtqueue number %d", queue
);
833 status
= g_new0(VirtVhostQueueStatus
, 1);
834 status
->name
= g_strdup(vdev
->name
);
835 status
->kick
= hdev
->vqs
[queue
].kick
;
836 status
->call
= hdev
->vqs
[queue
].call
;
837 status
->desc
= (uintptr_t)hdev
->vqs
[queue
].desc
;
838 status
->avail
= (uintptr_t)hdev
->vqs
[queue
].avail
;
839 status
->used
= (uintptr_t)hdev
->vqs
[queue
].used
;
840 status
->num
= hdev
->vqs
[queue
].num
;
841 status
->desc_phys
= hdev
->vqs
[queue
].desc_phys
;
842 status
->desc_size
= hdev
->vqs
[queue
].desc_size
;
843 status
->avail_phys
= hdev
->vqs
[queue
].avail_phys
;
844 status
->avail_size
= hdev
->vqs
[queue
].avail_size
;
845 status
->used_phys
= hdev
->vqs
[queue
].used_phys
;
846 status
->used_size
= hdev
->vqs
[queue
].used_size
;