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