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