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