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