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 { -1, "" } 454 }; 455 #endif 456 457 /* virtio-rng features mapping */ 458 #ifdef CONFIG_VIRTIO_RNG 459 static const qmp_virtio_feature_map_t virtio_rng_feature_map[] = { 460 FEATURE_ENTRY(VHOST_F_LOG_ALL, \ 461 "VHOST_F_LOG_ALL: Logging write descriptors supported"), 462 FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \ 463 "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features " 464 "negotiation supported"), 465 { -1, "" } 466 }; 467 #endif 468 469 /* virtio/vhost-gpio features mapping */ 470 #ifdef CONFIG_VHOST_USER_GPIO 471 static const qmp_virtio_feature_map_t virtio_gpio_feature_map[] = { 472 FEATURE_ENTRY(VIRTIO_GPIO_F_IRQ, \ 473 "VIRTIO_GPIO_F_IRQ: Device supports interrupts on GPIO lines"), 474 FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \ 475 "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features " 476 "negotiation supported"), 477 { -1, "" } 478 }; 479 #endif 480 481 #define CONVERT_FEATURES(type, map, is_status, bitmap) \ 482 ({ \ 483 type *list = NULL; \ 484 type *node; \ 485 for (i = 0; map[i].virtio_bit != -1; i++) { \ 486 if (is_status) { \ 487 bit = map[i].virtio_bit; \ 488 } \ 489 else { \ 490 bit = 1ULL << map[i].virtio_bit; \ 491 } \ 492 if ((bitmap & bit) == 0) { \ 493 continue; \ 494 } \ 495 node = g_new0(type, 1); \ 496 node->value = g_strdup(map[i].feature_desc); \ 497 node->next = list; \ 498 list = node; \ 499 bitmap ^= bit; \ 500 } \ 501 list; \ 502 }) 503 504 VirtioDeviceStatus *qmp_decode_status(uint8_t bitmap) 505 { 506 VirtioDeviceStatus *status; 507 uint8_t bit; 508 int i; 509 510 status = g_new0(VirtioDeviceStatus, 1); 511 status->statuses = CONVERT_FEATURES(strList, virtio_config_status_map, 512 1, bitmap); 513 status->has_unknown_statuses = bitmap != 0; 514 if (status->has_unknown_statuses) { 515 status->unknown_statuses = bitmap; 516 } 517 518 return status; 519 } 520 521 VhostDeviceProtocols *qmp_decode_protocols(uint64_t bitmap) 522 { 523 VhostDeviceProtocols *vhu_protocols; 524 uint64_t bit; 525 int i; 526 527 vhu_protocols = g_new0(VhostDeviceProtocols, 1); 528 vhu_protocols->protocols = 529 CONVERT_FEATURES(strList, 530 vhost_user_protocol_map, 0, bitmap); 531 vhu_protocols->has_unknown_protocols = bitmap != 0; 532 if (vhu_protocols->has_unknown_protocols) { 533 vhu_protocols->unknown_protocols = bitmap; 534 } 535 536 return vhu_protocols; 537 } 538 539 VirtioDeviceFeatures *qmp_decode_features(uint16_t device_id, uint64_t bitmap) 540 { 541 VirtioDeviceFeatures *features; 542 uint64_t bit; 543 int i; 544 545 features = g_new0(VirtioDeviceFeatures, 1); 546 features->has_dev_features = true; 547 548 /* transport features */ 549 features->transports = CONVERT_FEATURES(strList, virtio_transport_map, 0, 550 bitmap); 551 552 /* device features */ 553 switch (device_id) { 554 #ifdef CONFIG_VIRTIO_SERIAL 555 case VIRTIO_ID_CONSOLE: 556 features->dev_features = 557 CONVERT_FEATURES(strList, virtio_serial_feature_map, 0, bitmap); 558 break; 559 #endif 560 #ifdef CONFIG_VIRTIO_BLK 561 case VIRTIO_ID_BLOCK: 562 features->dev_features = 563 CONVERT_FEATURES(strList, virtio_blk_feature_map, 0, bitmap); 564 break; 565 #endif 566 #ifdef CONFIG_VIRTIO_GPU 567 case VIRTIO_ID_GPU: 568 features->dev_features = 569 CONVERT_FEATURES(strList, virtio_gpu_feature_map, 0, bitmap); 570 break; 571 #endif 572 #ifdef CONFIG_VIRTIO_NET 573 case VIRTIO_ID_NET: 574 features->dev_features = 575 CONVERT_FEATURES(strList, virtio_net_feature_map, 0, bitmap); 576 break; 577 #endif 578 #ifdef CONFIG_VIRTIO_SCSI 579 case VIRTIO_ID_SCSI: 580 features->dev_features = 581 CONVERT_FEATURES(strList, virtio_scsi_feature_map, 0, bitmap); 582 break; 583 #endif 584 #ifdef CONFIG_VIRTIO_BALLOON 585 case VIRTIO_ID_BALLOON: 586 features->dev_features = 587 CONVERT_FEATURES(strList, virtio_balloon_feature_map, 0, bitmap); 588 break; 589 #endif 590 #ifdef CONFIG_VIRTIO_IOMMU 591 case VIRTIO_ID_IOMMU: 592 features->dev_features = 593 CONVERT_FEATURES(strList, virtio_iommu_feature_map, 0, bitmap); 594 break; 595 #endif 596 #ifdef CONFIG_VIRTIO_INPUT 597 case VIRTIO_ID_INPUT: 598 features->dev_features = 599 CONVERT_FEATURES(strList, virtio_input_feature_map, 0, bitmap); 600 break; 601 #endif 602 #ifdef CONFIG_VHOST_USER_FS 603 case VIRTIO_ID_FS: 604 features->dev_features = 605 CONVERT_FEATURES(strList, virtio_fs_feature_map, 0, bitmap); 606 break; 607 #endif 608 #ifdef CONFIG_VHOST_VSOCK 609 case VIRTIO_ID_VSOCK: 610 features->dev_features = 611 CONVERT_FEATURES(strList, virtio_vsock_feature_map, 0, bitmap); 612 break; 613 #endif 614 #ifdef CONFIG_VIRTIO_CRYPTO 615 case VIRTIO_ID_CRYPTO: 616 features->dev_features = 617 CONVERT_FEATURES(strList, virtio_crypto_feature_map, 0, bitmap); 618 break; 619 #endif 620 #ifdef CONFIG_VIRTIO_MEM 621 case VIRTIO_ID_MEM: 622 features->dev_features = 623 CONVERT_FEATURES(strList, virtio_mem_feature_map, 0, bitmap); 624 break; 625 #endif 626 #ifdef CONFIG_VIRTIO_I2C_ADAPTER 627 case VIRTIO_ID_I2C_ADAPTER: 628 features->dev_features = 629 CONVERT_FEATURES(strList, virtio_i2c_feature_map, 0, bitmap); 630 break; 631 #endif 632 #ifdef CONFIG_VIRTIO_RNG 633 case VIRTIO_ID_RNG: 634 features->dev_features = 635 CONVERT_FEATURES(strList, virtio_rng_feature_map, 0, bitmap); 636 break; 637 #endif 638 #ifdef CONFIG_VHOST_USER_GPIO 639 case VIRTIO_ID_GPIO: 640 features->dev_features = 641 CONVERT_FEATURES(strList, virtio_gpio_feature_map, 0, bitmap); 642 break; 643 #endif 644 /* No features */ 645 case VIRTIO_ID_9P: 646 case VIRTIO_ID_PMEM: 647 case VIRTIO_ID_IOMEM: 648 case VIRTIO_ID_RPMSG: 649 case VIRTIO_ID_CLOCK: 650 case VIRTIO_ID_MAC80211_WLAN: 651 case VIRTIO_ID_MAC80211_HWSIM: 652 case VIRTIO_ID_RPROC_SERIAL: 653 case VIRTIO_ID_MEMORY_BALLOON: 654 case VIRTIO_ID_CAIF: 655 case VIRTIO_ID_SIGNAL_DIST: 656 case VIRTIO_ID_PSTORE: 657 case VIRTIO_ID_SOUND: 658 case VIRTIO_ID_BT: 659 case VIRTIO_ID_RPMB: 660 case VIRTIO_ID_VIDEO_ENCODER: 661 case VIRTIO_ID_VIDEO_DECODER: 662 case VIRTIO_ID_SCMI: 663 case VIRTIO_ID_NITRO_SEC_MOD: 664 case VIRTIO_ID_WATCHDOG: 665 case VIRTIO_ID_CAN: 666 case VIRTIO_ID_DMABUF: 667 case VIRTIO_ID_PARAM_SERV: 668 case VIRTIO_ID_AUDIO_POLICY: 669 break; 670 default: 671 g_assert_not_reached(); 672 } 673 674 features->has_unknown_dev_features = bitmap != 0; 675 if (features->has_unknown_dev_features) { 676 features->unknown_dev_features = bitmap; 677 } 678 679 return features; 680 } 681 682 static int query_dev_child(Object *child, void *opaque) 683 { 684 VirtioInfoList **vdevs = opaque; 685 Object *dev = object_dynamic_cast(child, TYPE_VIRTIO_DEVICE); 686 if (dev != NULL && DEVICE(dev)->realized) { 687 VirtIODevice *vdev = VIRTIO_DEVICE(dev); 688 VirtioInfo *info = g_new(VirtioInfo, 1); 689 690 /* Get canonical path & name of device */ 691 info->path = object_get_canonical_path(dev); 692 info->name = g_strdup(vdev->name); 693 QAPI_LIST_PREPEND(*vdevs, info); 694 } 695 return 0; 696 } 697 698 VirtioInfoList *qmp_x_query_virtio(Error **errp) 699 { 700 VirtioInfoList *vdevs = NULL; 701 702 /* Query the QOM composition tree recursively for virtio devices */ 703 object_child_foreach_recursive(object_get_root(), query_dev_child, &vdevs); 704 if (vdevs == NULL) { 705 error_setg(errp, "No virtio devices found"); 706 } 707 return vdevs; 708 } 709 710 VirtIODevice *qmp_find_virtio_device(const char *path) 711 { 712 /* Verify the canonical path is a realized virtio device */ 713 Object *dev = object_dynamic_cast(object_resolve_path(path, NULL), 714 TYPE_VIRTIO_DEVICE); 715 if (!dev || !DEVICE(dev)->realized) { 716 return NULL; 717 } 718 return VIRTIO_DEVICE(dev); 719 } 720 721 VirtioStatus *qmp_x_query_virtio_status(const char *path, Error **errp) 722 { 723 VirtIODevice *vdev; 724 VirtioStatus *status; 725 726 vdev = qmp_find_virtio_device(path); 727 if (vdev == NULL) { 728 error_setg(errp, "Path %s is not a realized VirtIODevice", path); 729 return NULL; 730 } 731 732 status = g_new0(VirtioStatus, 1); 733 status->name = g_strdup(vdev->name); 734 status->device_id = vdev->device_id; 735 status->vhost_started = vdev->vhost_started; 736 status->guest_features = qmp_decode_features(vdev->device_id, 737 vdev->guest_features); 738 status->host_features = qmp_decode_features(vdev->device_id, 739 vdev->host_features); 740 status->backend_features = qmp_decode_features(vdev->device_id, 741 vdev->backend_features); 742 743 switch (vdev->device_endian) { 744 case VIRTIO_DEVICE_ENDIAN_LITTLE: 745 status->device_endian = g_strdup("little"); 746 break; 747 case VIRTIO_DEVICE_ENDIAN_BIG: 748 status->device_endian = g_strdup("big"); 749 break; 750 default: 751 status->device_endian = g_strdup("unknown"); 752 break; 753 } 754 755 status->num_vqs = virtio_get_num_queues(vdev); 756 status->status = qmp_decode_status(vdev->status); 757 status->isr = vdev->isr; 758 status->queue_sel = vdev->queue_sel; 759 status->vm_running = vdev->vm_running; 760 status->broken = vdev->broken; 761 status->disabled = vdev->disabled; 762 status->use_started = vdev->use_started; 763 status->started = vdev->started; 764 status->start_on_kick = vdev->start_on_kick; 765 status->disable_legacy_check = vdev->disable_legacy_check; 766 status->bus_name = g_strdup(vdev->bus_name); 767 status->use_guest_notifier_mask = vdev->use_guest_notifier_mask; 768 769 if (vdev->vhost_started) { 770 VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev); 771 struct vhost_dev *hdev = vdc->get_vhost(vdev); 772 773 status->vhost_dev = g_new0(VhostStatus, 1); 774 status->vhost_dev->n_mem_sections = hdev->n_mem_sections; 775 status->vhost_dev->n_tmp_sections = hdev->n_tmp_sections; 776 status->vhost_dev->nvqs = hdev->nvqs; 777 status->vhost_dev->vq_index = hdev->vq_index; 778 status->vhost_dev->features = 779 qmp_decode_features(vdev->device_id, hdev->features); 780 status->vhost_dev->acked_features = 781 qmp_decode_features(vdev->device_id, hdev->acked_features); 782 status->vhost_dev->backend_features = 783 qmp_decode_features(vdev->device_id, hdev->backend_features); 784 status->vhost_dev->protocol_features = 785 qmp_decode_protocols(hdev->protocol_features); 786 status->vhost_dev->max_queues = hdev->max_queues; 787 status->vhost_dev->backend_cap = hdev->backend_cap; 788 status->vhost_dev->log_enabled = hdev->log_enabled; 789 status->vhost_dev->log_size = hdev->log_size; 790 } 791 792 return status; 793 } 794 795 VirtVhostQueueStatus *qmp_x_query_virtio_vhost_queue_status(const char *path, 796 uint16_t queue, 797 Error **errp) 798 { 799 VirtIODevice *vdev; 800 VirtVhostQueueStatus *status; 801 802 vdev = qmp_find_virtio_device(path); 803 if (vdev == NULL) { 804 error_setg(errp, "Path %s is not a VirtIODevice", path); 805 return NULL; 806 } 807 808 if (!vdev->vhost_started) { 809 error_setg(errp, "Error: vhost device has not started yet"); 810 return NULL; 811 } 812 813 VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev); 814 struct vhost_dev *hdev = vdc->get_vhost(vdev); 815 816 if (queue < hdev->vq_index || queue >= hdev->vq_index + hdev->nvqs) { 817 error_setg(errp, "Invalid vhost virtqueue number %d", queue); 818 return NULL; 819 } 820 821 status = g_new0(VirtVhostQueueStatus, 1); 822 status->name = g_strdup(vdev->name); 823 status->kick = hdev->vqs[queue].kick; 824 status->call = hdev->vqs[queue].call; 825 status->desc = (uintptr_t)hdev->vqs[queue].desc; 826 status->avail = (uintptr_t)hdev->vqs[queue].avail; 827 status->used = (uintptr_t)hdev->vqs[queue].used; 828 status->num = hdev->vqs[queue].num; 829 status->desc_phys = hdev->vqs[queue].desc_phys; 830 status->desc_size = hdev->vqs[queue].desc_size; 831 status->avail_phys = hdev->vqs[queue].avail_phys; 832 status->avail_size = hdev->vqs[queue].avail_size; 833 status->used_phys = hdev->vqs[queue].used_phys; 834 status->used_size = hdev->vqs[queue].used_size; 835 836 return status; 837 } 838