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