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 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 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 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 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 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 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 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 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