128b629abSPhilippe Mathieu-Daudé /* 228b629abSPhilippe Mathieu-Daudé * Virtio QMP helpers 328b629abSPhilippe Mathieu-Daudé * 428b629abSPhilippe Mathieu-Daudé * Copyright IBM, Corp. 2007 528b629abSPhilippe Mathieu-Daudé * 628b629abSPhilippe Mathieu-Daudé * Authors: 728b629abSPhilippe Mathieu-Daudé * Anthony Liguori <aliguori@us.ibm.com> 828b629abSPhilippe Mathieu-Daudé * 928b629abSPhilippe Mathieu-Daudé * SPDX-License-Identifier: GPL-2.0-or-later 1028b629abSPhilippe Mathieu-Daudé */ 1128b629abSPhilippe Mathieu-Daudé 1228b629abSPhilippe Mathieu-Daudé #include "qemu/osdep.h" 1328b629abSPhilippe Mathieu-Daudé #include "virtio-qmp.h" 1428b629abSPhilippe Mathieu-Daudé 159d94c213SPhilippe Mathieu-Daudé #include "qapi/error.h" 169d94c213SPhilippe Mathieu-Daudé #include "qapi/qapi-commands-virtio.h" 179d94c213SPhilippe Mathieu-Daudé #include "qapi/qapi-commands-qom.h" 189d94c213SPhilippe Mathieu-Daudé #include "qapi/qmp/qobject.h" 199d94c213SPhilippe Mathieu-Daudé #include "qapi/qmp/qjson.h" 209d94c213SPhilippe Mathieu-Daudé 2128b629abSPhilippe Mathieu-Daudé #include "standard-headers/linux/virtio_ids.h" 2228b629abSPhilippe Mathieu-Daudé #include "standard-headers/linux/vhost_types.h" 2328b629abSPhilippe Mathieu-Daudé #include "standard-headers/linux/virtio_blk.h" 2428b629abSPhilippe Mathieu-Daudé #include "standard-headers/linux/virtio_console.h" 2528b629abSPhilippe Mathieu-Daudé #include "standard-headers/linux/virtio_gpu.h" 2628b629abSPhilippe Mathieu-Daudé #include "standard-headers/linux/virtio_net.h" 2728b629abSPhilippe Mathieu-Daudé #include "standard-headers/linux/virtio_scsi.h" 2828b629abSPhilippe Mathieu-Daudé #include "standard-headers/linux/virtio_i2c.h" 2928b629abSPhilippe Mathieu-Daudé #include "standard-headers/linux/virtio_balloon.h" 3028b629abSPhilippe Mathieu-Daudé #include "standard-headers/linux/virtio_iommu.h" 3128b629abSPhilippe Mathieu-Daudé #include "standard-headers/linux/virtio_mem.h" 3228b629abSPhilippe Mathieu-Daudé #include "standard-headers/linux/virtio_vsock.h" 33*58f81689SJonah Palmer #include "standard-headers/linux/virtio_gpio.h" 3428b629abSPhilippe Mathieu-Daudé 3528b629abSPhilippe Mathieu-Daudé #include CONFIG_DEVICES 3628b629abSPhilippe Mathieu-Daudé 3728b629abSPhilippe Mathieu-Daudé #define FEATURE_ENTRY(name, desc) (qmp_virtio_feature_map_t) \ 3828b629abSPhilippe Mathieu-Daudé { .virtio_bit = name, .feature_desc = desc } 3928b629abSPhilippe Mathieu-Daudé 4028b629abSPhilippe Mathieu-Daudé enum VhostUserProtocolFeature { 4128b629abSPhilippe Mathieu-Daudé VHOST_USER_PROTOCOL_F_MQ = 0, 4228b629abSPhilippe Mathieu-Daudé VHOST_USER_PROTOCOL_F_LOG_SHMFD = 1, 4328b629abSPhilippe Mathieu-Daudé VHOST_USER_PROTOCOL_F_RARP = 2, 4428b629abSPhilippe Mathieu-Daudé VHOST_USER_PROTOCOL_F_REPLY_ACK = 3, 4528b629abSPhilippe Mathieu-Daudé VHOST_USER_PROTOCOL_F_NET_MTU = 4, 46a84ec993SMaxime Coquelin VHOST_USER_PROTOCOL_F_BACKEND_REQ = 5, 4728b629abSPhilippe Mathieu-Daudé VHOST_USER_PROTOCOL_F_CROSS_ENDIAN = 6, 4828b629abSPhilippe Mathieu-Daudé VHOST_USER_PROTOCOL_F_CRYPTO_SESSION = 7, 4928b629abSPhilippe Mathieu-Daudé VHOST_USER_PROTOCOL_F_PAGEFAULT = 8, 5028b629abSPhilippe Mathieu-Daudé VHOST_USER_PROTOCOL_F_CONFIG = 9, 51a84ec993SMaxime Coquelin VHOST_USER_PROTOCOL_F_BACKEND_SEND_FD = 10, 5228b629abSPhilippe Mathieu-Daudé VHOST_USER_PROTOCOL_F_HOST_NOTIFIER = 11, 5328b629abSPhilippe Mathieu-Daudé VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD = 12, 5428b629abSPhilippe Mathieu-Daudé VHOST_USER_PROTOCOL_F_RESET_DEVICE = 13, 5528b629abSPhilippe Mathieu-Daudé VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS = 14, 5628b629abSPhilippe Mathieu-Daudé VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS = 15, 57*58f81689SJonah Palmer VHOST_USER_PROTOCOL_F_STATUS = 16, 5828b629abSPhilippe Mathieu-Daudé VHOST_USER_PROTOCOL_F_MAX 5928b629abSPhilippe Mathieu-Daudé }; 6028b629abSPhilippe Mathieu-Daudé 6128b629abSPhilippe Mathieu-Daudé /* Virtio transport features mapping */ 6228b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_transport_map[] = { 6328b629abSPhilippe Mathieu-Daudé /* Virtio device transport features */ 6428b629abSPhilippe Mathieu-Daudé #ifndef VIRTIO_CONFIG_NO_LEGACY 6528b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_F_NOTIFY_ON_EMPTY, \ 6628b629abSPhilippe Mathieu-Daudé "VIRTIO_F_NOTIFY_ON_EMPTY: Notify when device runs out of avail. " 6728b629abSPhilippe Mathieu-Daudé "descs. on VQ"), 6828b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_F_ANY_LAYOUT, \ 6928b629abSPhilippe Mathieu-Daudé "VIRTIO_F_ANY_LAYOUT: Device accepts arbitrary desc. layouts"), 7028b629abSPhilippe Mathieu-Daudé #endif /* !VIRTIO_CONFIG_NO_LEGACY */ 7128b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_F_VERSION_1, \ 7228b629abSPhilippe Mathieu-Daudé "VIRTIO_F_VERSION_1: Device compliant for v1 spec (legacy)"), 7328b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_F_IOMMU_PLATFORM, \ 7428b629abSPhilippe Mathieu-Daudé "VIRTIO_F_IOMMU_PLATFORM: Device can be used on IOMMU platform"), 7528b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_F_RING_PACKED, \ 7628b629abSPhilippe Mathieu-Daudé "VIRTIO_F_RING_PACKED: Device supports packed VQ layout"), 7728b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_F_IN_ORDER, \ 7828b629abSPhilippe Mathieu-Daudé "VIRTIO_F_IN_ORDER: Device uses buffers in same order as made " 7928b629abSPhilippe Mathieu-Daudé "available by driver"), 8028b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_F_ORDER_PLATFORM, \ 8128b629abSPhilippe Mathieu-Daudé "VIRTIO_F_ORDER_PLATFORM: Memory accesses ordered by platform"), 8228b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_F_SR_IOV, \ 8328b629abSPhilippe Mathieu-Daudé "VIRTIO_F_SR_IOV: Device supports single root I/O virtualization"), 8492f04221SDavid Edmondson FEATURE_ENTRY(VIRTIO_F_RING_RESET, \ 8592f04221SDavid Edmondson "VIRTIO_F_RING_RESET: Driver can reset a queue individually"), 8628b629abSPhilippe Mathieu-Daudé /* Virtio ring transport features */ 8728b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_RING_F_INDIRECT_DESC, \ 8828b629abSPhilippe Mathieu-Daudé "VIRTIO_RING_F_INDIRECT_DESC: Indirect descriptors supported"), 8928b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_RING_F_EVENT_IDX, \ 9028b629abSPhilippe Mathieu-Daudé "VIRTIO_RING_F_EVENT_IDX: Used & avail. event fields enabled"), 9128b629abSPhilippe Mathieu-Daudé { -1, "" } 9228b629abSPhilippe Mathieu-Daudé }; 9328b629abSPhilippe Mathieu-Daudé 9428b629abSPhilippe Mathieu-Daudé /* Vhost-user protocol features mapping */ 9528b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t vhost_user_protocol_map[] = { 9628b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_MQ, \ 9728b629abSPhilippe Mathieu-Daudé "VHOST_USER_PROTOCOL_F_MQ: Multiqueue protocol supported"), 9828b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_LOG_SHMFD, \ 9928b629abSPhilippe Mathieu-Daudé "VHOST_USER_PROTOCOL_F_LOG_SHMFD: Shared log memory fd supported"), 10028b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_RARP, \ 10128b629abSPhilippe Mathieu-Daudé "VHOST_USER_PROTOCOL_F_RARP: Vhost-user back-end RARP broadcasting " 10228b629abSPhilippe Mathieu-Daudé "supported"), 10328b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_REPLY_ACK, \ 10428b629abSPhilippe Mathieu-Daudé "VHOST_USER_PROTOCOL_F_REPLY_ACK: Requested operation status ack. " 10528b629abSPhilippe Mathieu-Daudé "supported"), 10628b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_NET_MTU, \ 10728b629abSPhilippe Mathieu-Daudé "VHOST_USER_PROTOCOL_F_NET_MTU: Expose host MTU to guest supported"), 108a84ec993SMaxime Coquelin FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_BACKEND_REQ, \ 109a84ec993SMaxime Coquelin "VHOST_USER_PROTOCOL_F_BACKEND_REQ: Socket fd for back-end initiated " 11028b629abSPhilippe Mathieu-Daudé "requests supported"), 11128b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_CROSS_ENDIAN, \ 11228b629abSPhilippe Mathieu-Daudé "VHOST_USER_PROTOCOL_F_CROSS_ENDIAN: Endianness of VQs for legacy " 11328b629abSPhilippe Mathieu-Daudé "devices supported"), 11428b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_CRYPTO_SESSION, \ 11528b629abSPhilippe Mathieu-Daudé "VHOST_USER_PROTOCOL_F_CRYPTO_SESSION: Session creation for crypto " 11628b629abSPhilippe Mathieu-Daudé "operations supported"), 11728b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_PAGEFAULT, \ 11828b629abSPhilippe Mathieu-Daudé "VHOST_USER_PROTOCOL_F_PAGEFAULT: Request servicing on userfaultfd " 11928b629abSPhilippe Mathieu-Daudé "for accessed pages supported"), 12028b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_CONFIG, \ 12128b629abSPhilippe Mathieu-Daudé "VHOST_USER_PROTOCOL_F_CONFIG: Vhost-user messaging for virtio " 12228b629abSPhilippe Mathieu-Daudé "device configuration space supported"), 123a84ec993SMaxime Coquelin FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_BACKEND_SEND_FD, \ 124f8ed3648SManos Pitsidianakis "VHOST_USER_PROTOCOL_F_BACKEND_SEND_FD: Backend fd communication " 12528b629abSPhilippe Mathieu-Daudé "channel supported"), 12628b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_HOST_NOTIFIER, \ 12728b629abSPhilippe Mathieu-Daudé "VHOST_USER_PROTOCOL_F_HOST_NOTIFIER: Host notifiers for specified " 12828b629abSPhilippe Mathieu-Daudé "VQs supported"), 12928b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD, \ 13028b629abSPhilippe Mathieu-Daudé "VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD: Shared inflight I/O buffers " 13128b629abSPhilippe Mathieu-Daudé "supported"), 13228b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_RESET_DEVICE, \ 13328b629abSPhilippe Mathieu-Daudé "VHOST_USER_PROTOCOL_F_RESET_DEVICE: Disabling all rings and " 13428b629abSPhilippe Mathieu-Daudé "resetting internal device state supported"), 13528b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS, \ 13628b629abSPhilippe Mathieu-Daudé "VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS: In-band messaging " 13728b629abSPhilippe Mathieu-Daudé "supported"), 13828b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS, \ 13928b629abSPhilippe Mathieu-Daudé "VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS: Configuration for " 14028b629abSPhilippe Mathieu-Daudé "memory slots supported"), 141*58f81689SJonah Palmer FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_STATUS, \ 142*58f81689SJonah Palmer "VHOST_USER_PROTOCOL_F_STATUS: Querying and notifying back-end " 143*58f81689SJonah Palmer "device status supported"), 14428b629abSPhilippe Mathieu-Daudé { -1, "" } 14528b629abSPhilippe Mathieu-Daudé }; 14628b629abSPhilippe Mathieu-Daudé 14728b629abSPhilippe Mathieu-Daudé /* virtio device configuration statuses */ 14828b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_config_status_map[] = { 14928b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_CONFIG_S_DRIVER_OK, \ 15028b629abSPhilippe Mathieu-Daudé "VIRTIO_CONFIG_S_DRIVER_OK: Driver setup and ready"), 15128b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_CONFIG_S_FEATURES_OK, \ 15228b629abSPhilippe Mathieu-Daudé "VIRTIO_CONFIG_S_FEATURES_OK: Feature negotiation complete"), 15328b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_CONFIG_S_DRIVER, \ 15428b629abSPhilippe Mathieu-Daudé "VIRTIO_CONFIG_S_DRIVER: Guest OS compatible with device"), 15528b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_CONFIG_S_NEEDS_RESET, \ 15628b629abSPhilippe Mathieu-Daudé "VIRTIO_CONFIG_S_NEEDS_RESET: Irrecoverable error, device needs " 15728b629abSPhilippe Mathieu-Daudé "reset"), 15828b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_CONFIG_S_FAILED, \ 15928b629abSPhilippe Mathieu-Daudé "VIRTIO_CONFIG_S_FAILED: Error in guest, device failed"), 16028b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_CONFIG_S_ACKNOWLEDGE, \ 16128b629abSPhilippe Mathieu-Daudé "VIRTIO_CONFIG_S_ACKNOWLEDGE: Valid virtio device found"), 16228b629abSPhilippe Mathieu-Daudé { -1, "" } 16328b629abSPhilippe Mathieu-Daudé }; 16428b629abSPhilippe Mathieu-Daudé 16528b629abSPhilippe Mathieu-Daudé /* virtio-blk features mapping */ 16628b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_BLK 16728b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_blk_feature_map[] = { 16828b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_BLK_F_SIZE_MAX, \ 16928b629abSPhilippe Mathieu-Daudé "VIRTIO_BLK_F_SIZE_MAX: Max segment size is size_max"), 17028b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_BLK_F_SEG_MAX, \ 17128b629abSPhilippe Mathieu-Daudé "VIRTIO_BLK_F_SEG_MAX: Max segments in a request is seg_max"), 17228b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_BLK_F_GEOMETRY, \ 17328b629abSPhilippe Mathieu-Daudé "VIRTIO_BLK_F_GEOMETRY: Legacy geometry available"), 17428b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_BLK_F_RO, \ 17528b629abSPhilippe Mathieu-Daudé "VIRTIO_BLK_F_RO: Device is read-only"), 17628b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_BLK_F_BLK_SIZE, \ 17728b629abSPhilippe Mathieu-Daudé "VIRTIO_BLK_F_BLK_SIZE: Block size of disk available"), 17828b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_BLK_F_TOPOLOGY, \ 17928b629abSPhilippe Mathieu-Daudé "VIRTIO_BLK_F_TOPOLOGY: Topology information available"), 18028b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_BLK_F_MQ, \ 18128b629abSPhilippe Mathieu-Daudé "VIRTIO_BLK_F_MQ: Multiqueue supported"), 18228b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_BLK_F_DISCARD, \ 18328b629abSPhilippe Mathieu-Daudé "VIRTIO_BLK_F_DISCARD: Discard command supported"), 18428b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_BLK_F_WRITE_ZEROES, \ 18528b629abSPhilippe Mathieu-Daudé "VIRTIO_BLK_F_WRITE_ZEROES: Write zeroes command supported"), 186*58f81689SJonah Palmer FEATURE_ENTRY(VIRTIO_BLK_F_SECURE_ERASE, \ 187*58f81689SJonah Palmer "VIRTIO_BLK_F_SECURE_ERASE: Secure erase supported"), 1884f736650SSam Li FEATURE_ENTRY(VIRTIO_BLK_F_ZONED, \ 1894f736650SSam Li "VIRTIO_BLK_F_ZONED: Zoned block devices"), 19028b629abSPhilippe Mathieu-Daudé #ifndef VIRTIO_BLK_NO_LEGACY 19128b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_BLK_F_BARRIER, \ 19228b629abSPhilippe Mathieu-Daudé "VIRTIO_BLK_F_BARRIER: Request barriers supported"), 19328b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_BLK_F_SCSI, \ 19428b629abSPhilippe Mathieu-Daudé "VIRTIO_BLK_F_SCSI: SCSI packet commands supported"), 19528b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_BLK_F_FLUSH, \ 19628b629abSPhilippe Mathieu-Daudé "VIRTIO_BLK_F_FLUSH: Flush command supported"), 19728b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_BLK_F_CONFIG_WCE, \ 19828b629abSPhilippe Mathieu-Daudé "VIRTIO_BLK_F_CONFIG_WCE: Cache writeback and writethrough modes " 19928b629abSPhilippe Mathieu-Daudé "supported"), 20028b629abSPhilippe Mathieu-Daudé #endif /* !VIRTIO_BLK_NO_LEGACY */ 20128b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VHOST_F_LOG_ALL, \ 20228b629abSPhilippe Mathieu-Daudé "VHOST_F_LOG_ALL: Logging write descriptors supported"), 20328b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \ 20428b629abSPhilippe Mathieu-Daudé "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features " 20528b629abSPhilippe Mathieu-Daudé "negotiation supported"), 20628b629abSPhilippe Mathieu-Daudé { -1, "" } 20728b629abSPhilippe Mathieu-Daudé }; 20828b629abSPhilippe Mathieu-Daudé #endif 20928b629abSPhilippe Mathieu-Daudé 21028b629abSPhilippe Mathieu-Daudé /* virtio-serial features mapping */ 21128b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_SERIAL 21228b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_serial_feature_map[] = { 21328b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_CONSOLE_F_SIZE, \ 21428b629abSPhilippe Mathieu-Daudé "VIRTIO_CONSOLE_F_SIZE: Host providing console size"), 21528b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_CONSOLE_F_MULTIPORT, \ 21628b629abSPhilippe Mathieu-Daudé "VIRTIO_CONSOLE_F_MULTIPORT: Multiple ports for device supported"), 21728b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_CONSOLE_F_EMERG_WRITE, \ 21828b629abSPhilippe Mathieu-Daudé "VIRTIO_CONSOLE_F_EMERG_WRITE: Emergency write supported"), 21928b629abSPhilippe Mathieu-Daudé { -1, "" } 22028b629abSPhilippe Mathieu-Daudé }; 22128b629abSPhilippe Mathieu-Daudé #endif 22228b629abSPhilippe Mathieu-Daudé 22328b629abSPhilippe Mathieu-Daudé /* virtio-gpu features mapping */ 22428b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_GPU 22528b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_gpu_feature_map[] = { 22628b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_GPU_F_VIRGL, \ 22728b629abSPhilippe Mathieu-Daudé "VIRTIO_GPU_F_VIRGL: Virgl 3D mode supported"), 22828b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_GPU_F_EDID, \ 22928b629abSPhilippe Mathieu-Daudé "VIRTIO_GPU_F_EDID: EDID metadata supported"), 23028b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_GPU_F_RESOURCE_UUID, \ 23128b629abSPhilippe Mathieu-Daudé "VIRTIO_GPU_F_RESOURCE_UUID: Resource UUID assigning supported"), 23228b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_GPU_F_RESOURCE_BLOB, \ 23328b629abSPhilippe Mathieu-Daudé "VIRTIO_GPU_F_RESOURCE_BLOB: Size-based blob resources supported"), 23428b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_GPU_F_CONTEXT_INIT, \ 23528b629abSPhilippe Mathieu-Daudé "VIRTIO_GPU_F_CONTEXT_INIT: Context types and synchronization " 23628b629abSPhilippe Mathieu-Daudé "timelines supported"), 23728b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VHOST_F_LOG_ALL, \ 23828b629abSPhilippe Mathieu-Daudé "VHOST_F_LOG_ALL: Logging write descriptors supported"), 23928b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \ 24028b629abSPhilippe Mathieu-Daudé "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features " 24128b629abSPhilippe Mathieu-Daudé "negotiation supported"), 24228b629abSPhilippe Mathieu-Daudé { -1, "" } 24328b629abSPhilippe Mathieu-Daudé }; 24428b629abSPhilippe Mathieu-Daudé #endif 24528b629abSPhilippe Mathieu-Daudé 24628b629abSPhilippe Mathieu-Daudé /* virtio-input features mapping */ 24728b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_INPUT 24828b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_input_feature_map[] = { 24928b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VHOST_F_LOG_ALL, \ 25028b629abSPhilippe Mathieu-Daudé "VHOST_F_LOG_ALL: Logging write descriptors supported"), 25128b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \ 25228b629abSPhilippe Mathieu-Daudé "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features " 25328b629abSPhilippe Mathieu-Daudé "negotiation supported"), 25428b629abSPhilippe Mathieu-Daudé { -1, "" } 25528b629abSPhilippe Mathieu-Daudé }; 25628b629abSPhilippe Mathieu-Daudé #endif 25728b629abSPhilippe Mathieu-Daudé 25828b629abSPhilippe Mathieu-Daudé /* virtio-net features mapping */ 25928b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_NET 26028b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_net_feature_map[] = { 26128b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_NET_F_CSUM, \ 26228b629abSPhilippe Mathieu-Daudé "VIRTIO_NET_F_CSUM: Device handling packets with partial checksum " 26328b629abSPhilippe Mathieu-Daudé "supported"), 26428b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_NET_F_GUEST_CSUM, \ 26528b629abSPhilippe Mathieu-Daudé "VIRTIO_NET_F_GUEST_CSUM: Driver handling packets with partial " 26628b629abSPhilippe Mathieu-Daudé "checksum supported"), 26728b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_NET_F_CTRL_GUEST_OFFLOADS, \ 26828b629abSPhilippe Mathieu-Daudé "VIRTIO_NET_F_CTRL_GUEST_OFFLOADS: Control channel offloading " 26928b629abSPhilippe Mathieu-Daudé "reconfig. supported"), 27028b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_NET_F_MTU, \ 27128b629abSPhilippe Mathieu-Daudé "VIRTIO_NET_F_MTU: Device max MTU reporting supported"), 27228b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_NET_F_MAC, \ 27328b629abSPhilippe Mathieu-Daudé "VIRTIO_NET_F_MAC: Device has given MAC address"), 27428b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_NET_F_GUEST_TSO4, \ 27528b629abSPhilippe Mathieu-Daudé "VIRTIO_NET_F_GUEST_TSO4: Driver can receive TSOv4"), 27628b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_NET_F_GUEST_TSO6, \ 27728b629abSPhilippe Mathieu-Daudé "VIRTIO_NET_F_GUEST_TSO6: Driver can receive TSOv6"), 27828b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_NET_F_GUEST_ECN, \ 27928b629abSPhilippe Mathieu-Daudé "VIRTIO_NET_F_GUEST_ECN: Driver can receive TSO with ECN"), 28028b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_NET_F_GUEST_UFO, \ 28128b629abSPhilippe Mathieu-Daudé "VIRTIO_NET_F_GUEST_UFO: Driver can receive UFO"), 28228b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_NET_F_HOST_TSO4, \ 28328b629abSPhilippe Mathieu-Daudé "VIRTIO_NET_F_HOST_TSO4: Device can receive TSOv4"), 28428b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_NET_F_HOST_TSO6, \ 28528b629abSPhilippe Mathieu-Daudé "VIRTIO_NET_F_HOST_TSO6: Device can receive TSOv6"), 28628b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_NET_F_HOST_ECN, \ 28728b629abSPhilippe Mathieu-Daudé "VIRTIO_NET_F_HOST_ECN: Device can receive TSO with ECN"), 28828b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_NET_F_HOST_UFO, \ 28928b629abSPhilippe Mathieu-Daudé "VIRTIO_NET_F_HOST_UFO: Device can receive UFO"), 29028b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_NET_F_MRG_RXBUF, \ 29128b629abSPhilippe Mathieu-Daudé "VIRTIO_NET_F_MRG_RXBUF: Driver can merge receive buffers"), 29228b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_NET_F_STATUS, \ 29328b629abSPhilippe Mathieu-Daudé "VIRTIO_NET_F_STATUS: Configuration status field available"), 29428b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_NET_F_CTRL_VQ, \ 29528b629abSPhilippe Mathieu-Daudé "VIRTIO_NET_F_CTRL_VQ: Control channel available"), 29628b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_NET_F_CTRL_RX, \ 29728b629abSPhilippe Mathieu-Daudé "VIRTIO_NET_F_CTRL_RX: Control channel RX mode supported"), 29828b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_NET_F_CTRL_VLAN, \ 29928b629abSPhilippe Mathieu-Daudé "VIRTIO_NET_F_CTRL_VLAN: Control channel VLAN filtering supported"), 30028b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_NET_F_CTRL_RX_EXTRA, \ 30128b629abSPhilippe Mathieu-Daudé "VIRTIO_NET_F_CTRL_RX_EXTRA: Extra RX mode control supported"), 30228b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_NET_F_GUEST_ANNOUNCE, \ 30328b629abSPhilippe Mathieu-Daudé "VIRTIO_NET_F_GUEST_ANNOUNCE: Driver sending gratuitous packets " 30428b629abSPhilippe Mathieu-Daudé "supported"), 30528b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_NET_F_MQ, \ 30628b629abSPhilippe Mathieu-Daudé "VIRTIO_NET_F_MQ: Multiqueue with automatic receive steering " 30728b629abSPhilippe Mathieu-Daudé "supported"), 30828b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_NET_F_CTRL_MAC_ADDR, \ 30928b629abSPhilippe Mathieu-Daudé "VIRTIO_NET_F_CTRL_MAC_ADDR: MAC address set through control " 31028b629abSPhilippe Mathieu-Daudé "channel"), 311*58f81689SJonah Palmer FEATURE_ENTRY(VIRTIO_NET_F_NOTF_COAL, \ 312*58f81689SJonah Palmer "VIRTIO_NET_F_NOTF_COAL: Device supports coalescing notifications"), 313*58f81689SJonah Palmer FEATURE_ENTRY(VIRTIO_NET_F_GUEST_USO4, \ 314*58f81689SJonah Palmer "VIRTIO_NET_F_GUEST_USO4: Driver can receive USOv4"), 315*58f81689SJonah Palmer FEATURE_ENTRY(VIRTIO_NET_F_GUEST_USO6, \ 316*58f81689SJonah Palmer "VIRTIO_NET_F_GUEST_USO4: Driver can receive USOv6"), 317*58f81689SJonah Palmer FEATURE_ENTRY(VIRTIO_NET_F_HOST_USO, \ 318*58f81689SJonah Palmer "VIRTIO_NET_F_HOST_USO: Device can receive USO"), 31928b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_NET_F_HASH_REPORT, \ 32028b629abSPhilippe Mathieu-Daudé "VIRTIO_NET_F_HASH_REPORT: Hash reporting supported"), 32128b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_NET_F_RSS, \ 32228b629abSPhilippe Mathieu-Daudé "VIRTIO_NET_F_RSS: RSS RX steering supported"), 32328b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_NET_F_RSC_EXT, \ 32428b629abSPhilippe Mathieu-Daudé "VIRTIO_NET_F_RSC_EXT: Extended coalescing info supported"), 32528b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_NET_F_STANDBY, \ 32628b629abSPhilippe Mathieu-Daudé "VIRTIO_NET_F_STANDBY: Device acting as standby for primary " 32728b629abSPhilippe Mathieu-Daudé "device with same MAC addr. supported"), 32828b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_NET_F_SPEED_DUPLEX, \ 32928b629abSPhilippe Mathieu-Daudé "VIRTIO_NET_F_SPEED_DUPLEX: Device set linkspeed and duplex"), 33028b629abSPhilippe Mathieu-Daudé #ifndef VIRTIO_NET_NO_LEGACY 33128b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_NET_F_GSO, \ 33228b629abSPhilippe Mathieu-Daudé "VIRTIO_NET_F_GSO: Handling GSO-type packets supported"), 33328b629abSPhilippe Mathieu-Daudé #endif /* !VIRTIO_NET_NO_LEGACY */ 33428b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VHOST_NET_F_VIRTIO_NET_HDR, \ 33528b629abSPhilippe Mathieu-Daudé "VHOST_NET_F_VIRTIO_NET_HDR: Virtio-net headers for RX and TX " 33628b629abSPhilippe Mathieu-Daudé "packets supported"), 33728b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VHOST_F_LOG_ALL, \ 33828b629abSPhilippe Mathieu-Daudé "VHOST_F_LOG_ALL: Logging write descriptors supported"), 33928b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \ 34028b629abSPhilippe Mathieu-Daudé "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features " 34128b629abSPhilippe Mathieu-Daudé "negotiation supported"), 34228b629abSPhilippe Mathieu-Daudé { -1, "" } 34328b629abSPhilippe Mathieu-Daudé }; 34428b629abSPhilippe Mathieu-Daudé #endif 34528b629abSPhilippe Mathieu-Daudé 34628b629abSPhilippe Mathieu-Daudé /* virtio-scsi features mapping */ 34728b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_SCSI 34828b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_scsi_feature_map[] = { 34928b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_SCSI_F_INOUT, \ 35028b629abSPhilippe Mathieu-Daudé "VIRTIO_SCSI_F_INOUT: Requests including read and writable data " 35146e75a77SMichael Tokarev "buffers supported"), 35228b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_SCSI_F_HOTPLUG, \ 35328b629abSPhilippe Mathieu-Daudé "VIRTIO_SCSI_F_HOTPLUG: Reporting and handling hot-plug events " 35428b629abSPhilippe Mathieu-Daudé "supported"), 35528b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_SCSI_F_CHANGE, \ 35628b629abSPhilippe Mathieu-Daudé "VIRTIO_SCSI_F_CHANGE: Reporting and handling LUN changes " 35728b629abSPhilippe Mathieu-Daudé "supported"), 35828b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_SCSI_F_T10_PI, \ 35928b629abSPhilippe Mathieu-Daudé "VIRTIO_SCSI_F_T10_PI: T10 info included in request header"), 36028b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VHOST_F_LOG_ALL, \ 36128b629abSPhilippe Mathieu-Daudé "VHOST_F_LOG_ALL: Logging write descriptors supported"), 36228b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \ 36328b629abSPhilippe Mathieu-Daudé "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features " 36428b629abSPhilippe Mathieu-Daudé "negotiation supported"), 36528b629abSPhilippe Mathieu-Daudé { -1, "" } 36628b629abSPhilippe Mathieu-Daudé }; 36728b629abSPhilippe Mathieu-Daudé #endif 36828b629abSPhilippe Mathieu-Daudé 36928b629abSPhilippe Mathieu-Daudé /* virtio/vhost-user-fs features mapping */ 37028b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VHOST_USER_FS 37128b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_fs_feature_map[] = { 37228b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VHOST_F_LOG_ALL, \ 37328b629abSPhilippe Mathieu-Daudé "VHOST_F_LOG_ALL: Logging write descriptors supported"), 37428b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \ 37528b629abSPhilippe Mathieu-Daudé "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features " 37628b629abSPhilippe Mathieu-Daudé "negotiation supported"), 37728b629abSPhilippe Mathieu-Daudé { -1, "" } 37828b629abSPhilippe Mathieu-Daudé }; 37928b629abSPhilippe Mathieu-Daudé #endif 38028b629abSPhilippe Mathieu-Daudé 38128b629abSPhilippe Mathieu-Daudé /* virtio/vhost-user-i2c features mapping */ 38228b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_I2C_ADAPTER 38328b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_i2c_feature_map[] = { 38428b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_I2C_F_ZERO_LENGTH_REQUEST, \ 38528b629abSPhilippe Mathieu-Daudé "VIRTIO_I2C_F_ZERO_LEGNTH_REQUEST: Zero length requests supported"), 38628b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VHOST_F_LOG_ALL, \ 38728b629abSPhilippe Mathieu-Daudé "VHOST_F_LOG_ALL: Logging write descriptors supported"), 38828b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \ 38928b629abSPhilippe Mathieu-Daudé "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features " 39028b629abSPhilippe Mathieu-Daudé "negotiation supported"), 39128b629abSPhilippe Mathieu-Daudé { -1, "" } 39228b629abSPhilippe Mathieu-Daudé }; 39328b629abSPhilippe Mathieu-Daudé #endif 39428b629abSPhilippe Mathieu-Daudé 39528b629abSPhilippe Mathieu-Daudé /* virtio/vhost-vsock features mapping */ 39628b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VHOST_VSOCK 39728b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_vsock_feature_map[] = { 39828b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_VSOCK_F_SEQPACKET, \ 39928b629abSPhilippe Mathieu-Daudé "VIRTIO_VSOCK_F_SEQPACKET: SOCK_SEQPACKET supported"), 40028b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VHOST_F_LOG_ALL, \ 40128b629abSPhilippe Mathieu-Daudé "VHOST_F_LOG_ALL: Logging write descriptors supported"), 40228b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \ 40328b629abSPhilippe Mathieu-Daudé "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features " 40428b629abSPhilippe Mathieu-Daudé "negotiation supported"), 40528b629abSPhilippe Mathieu-Daudé { -1, "" } 40628b629abSPhilippe Mathieu-Daudé }; 40728b629abSPhilippe Mathieu-Daudé #endif 40828b629abSPhilippe Mathieu-Daudé 40928b629abSPhilippe Mathieu-Daudé /* virtio-balloon features mapping */ 41028b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_BALLOON 41128b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_balloon_feature_map[] = { 41228b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_BALLOON_F_MUST_TELL_HOST, \ 41328b629abSPhilippe Mathieu-Daudé "VIRTIO_BALLOON_F_MUST_TELL_HOST: Tell host before reclaiming " 41428b629abSPhilippe Mathieu-Daudé "pages"), 41528b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_BALLOON_F_STATS_VQ, \ 41628b629abSPhilippe Mathieu-Daudé "VIRTIO_BALLOON_F_STATS_VQ: Guest memory stats VQ available"), 41728b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_BALLOON_F_DEFLATE_ON_OOM, \ 41828b629abSPhilippe Mathieu-Daudé "VIRTIO_BALLOON_F_DEFLATE_ON_OOM: Deflate balloon when guest OOM"), 41928b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_BALLOON_F_FREE_PAGE_HINT, \ 42028b629abSPhilippe Mathieu-Daudé "VIRTIO_BALLOON_F_FREE_PAGE_HINT: VQ reporting free pages enabled"), 42128b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_BALLOON_F_PAGE_POISON, \ 42228b629abSPhilippe Mathieu-Daudé "VIRTIO_BALLOON_F_PAGE_POISON: Guest page poisoning enabled"), 42328b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_BALLOON_F_REPORTING, \ 42428b629abSPhilippe Mathieu-Daudé "VIRTIO_BALLOON_F_REPORTING: Page reporting VQ enabled"), 42528b629abSPhilippe Mathieu-Daudé { -1, "" } 42628b629abSPhilippe Mathieu-Daudé }; 42728b629abSPhilippe Mathieu-Daudé #endif 42828b629abSPhilippe Mathieu-Daudé 42928b629abSPhilippe Mathieu-Daudé /* virtio-crypto features mapping */ 43028b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_CRYPTO 43128b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_crypto_feature_map[] = { 43228b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VHOST_F_LOG_ALL, \ 43328b629abSPhilippe Mathieu-Daudé "VHOST_F_LOG_ALL: Logging write descriptors supported"), 43428b629abSPhilippe Mathieu-Daudé { -1, "" } 43528b629abSPhilippe Mathieu-Daudé }; 43628b629abSPhilippe Mathieu-Daudé #endif 43728b629abSPhilippe Mathieu-Daudé 43828b629abSPhilippe Mathieu-Daudé /* virtio-iommu features mapping */ 43928b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_IOMMU 44028b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_iommu_feature_map[] = { 44128b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_IOMMU_F_INPUT_RANGE, \ 44228b629abSPhilippe Mathieu-Daudé "VIRTIO_IOMMU_F_INPUT_RANGE: Range of available virtual addrs. " 44328b629abSPhilippe Mathieu-Daudé "available"), 44428b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_IOMMU_F_DOMAIN_RANGE, \ 44528b629abSPhilippe Mathieu-Daudé "VIRTIO_IOMMU_F_DOMAIN_RANGE: Number of supported domains " 44628b629abSPhilippe Mathieu-Daudé "available"), 44728b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_IOMMU_F_MAP_UNMAP, \ 44828b629abSPhilippe Mathieu-Daudé "VIRTIO_IOMMU_F_MAP_UNMAP: Map and unmap requests available"), 44928b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_IOMMU_F_BYPASS, \ 45028b629abSPhilippe Mathieu-Daudé "VIRTIO_IOMMU_F_BYPASS: Endpoints not attached to domains are in " 45128b629abSPhilippe Mathieu-Daudé "bypass mode"), 45228b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_IOMMU_F_PROBE, \ 45328b629abSPhilippe Mathieu-Daudé "VIRTIO_IOMMU_F_PROBE: Probe requests available"), 45428b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_IOMMU_F_MMIO, \ 45528b629abSPhilippe Mathieu-Daudé "VIRTIO_IOMMU_F_MMIO: VIRTIO_IOMMU_MAP_F_MMIO flag available"), 45628b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_IOMMU_F_BYPASS_CONFIG, \ 45728b629abSPhilippe Mathieu-Daudé "VIRTIO_IOMMU_F_BYPASS_CONFIG: Bypass field of IOMMU config " 45828b629abSPhilippe Mathieu-Daudé "available"), 45928b629abSPhilippe Mathieu-Daudé { -1, "" } 46028b629abSPhilippe Mathieu-Daudé }; 46128b629abSPhilippe Mathieu-Daudé #endif 46228b629abSPhilippe Mathieu-Daudé 46328b629abSPhilippe Mathieu-Daudé /* virtio-mem features mapping */ 46428b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_MEM 46528b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_mem_feature_map[] = { 46628b629abSPhilippe Mathieu-Daudé #ifndef CONFIG_ACPI 46728b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_MEM_F_ACPI_PXM, \ 46828b629abSPhilippe Mathieu-Daudé "VIRTIO_MEM_F_ACPI_PXM: node_id is an ACPI PXM and is valid"), 46928b629abSPhilippe Mathieu-Daudé #endif /* !CONFIG_ACPI */ 47028b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE, \ 47128b629abSPhilippe Mathieu-Daudé "VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE: Unplugged memory cannot be " 47228b629abSPhilippe Mathieu-Daudé "accessed"), 47328b629abSPhilippe Mathieu-Daudé { -1, "" } 47428b629abSPhilippe Mathieu-Daudé }; 47528b629abSPhilippe Mathieu-Daudé #endif 47628b629abSPhilippe Mathieu-Daudé 47728b629abSPhilippe Mathieu-Daudé /* virtio-rng features mapping */ 47828b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_RNG 47928b629abSPhilippe Mathieu-Daudé static const qmp_virtio_feature_map_t virtio_rng_feature_map[] = { 48028b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VHOST_F_LOG_ALL, \ 48128b629abSPhilippe Mathieu-Daudé "VHOST_F_LOG_ALL: Logging write descriptors supported"), 48228b629abSPhilippe Mathieu-Daudé FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \ 48328b629abSPhilippe Mathieu-Daudé "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features " 48428b629abSPhilippe Mathieu-Daudé "negotiation supported"), 48528b629abSPhilippe Mathieu-Daudé { -1, "" } 48628b629abSPhilippe Mathieu-Daudé }; 48728b629abSPhilippe Mathieu-Daudé #endif 48828b629abSPhilippe Mathieu-Daudé 489*58f81689SJonah Palmer /* virtio/vhost-gpio features mapping */ 490*58f81689SJonah Palmer #ifdef CONFIG_VHOST_USER_GPIO 491*58f81689SJonah Palmer static const qmp_virtio_feature_map_t virtio_gpio_feature_map[] = { 492*58f81689SJonah Palmer FEATURE_ENTRY(VIRTIO_GPIO_F_IRQ, \ 493*58f81689SJonah Palmer "VIRTIO_GPIO_F_IRQ: Device supports interrupts on GPIO lines"), 494*58f81689SJonah Palmer FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \ 495*58f81689SJonah Palmer "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features " 496*58f81689SJonah Palmer "negotiation supported"), 497*58f81689SJonah Palmer { -1, "" } 498*58f81689SJonah Palmer }; 499*58f81689SJonah Palmer #endif 500*58f81689SJonah Palmer 50128b629abSPhilippe Mathieu-Daudé #define CONVERT_FEATURES(type, map, is_status, bitmap) \ 50228b629abSPhilippe Mathieu-Daudé ({ \ 50328b629abSPhilippe Mathieu-Daudé type *list = NULL; \ 50428b629abSPhilippe Mathieu-Daudé type *node; \ 50528b629abSPhilippe Mathieu-Daudé for (i = 0; map[i].virtio_bit != -1; i++) { \ 50628b629abSPhilippe Mathieu-Daudé if (is_status) { \ 50728b629abSPhilippe Mathieu-Daudé bit = map[i].virtio_bit; \ 50828b629abSPhilippe Mathieu-Daudé } \ 50928b629abSPhilippe Mathieu-Daudé else { \ 51028b629abSPhilippe Mathieu-Daudé bit = 1ULL << map[i].virtio_bit; \ 51128b629abSPhilippe Mathieu-Daudé } \ 51228b629abSPhilippe Mathieu-Daudé if ((bitmap & bit) == 0) { \ 51328b629abSPhilippe Mathieu-Daudé continue; \ 51428b629abSPhilippe Mathieu-Daudé } \ 51528b629abSPhilippe Mathieu-Daudé node = g_new0(type, 1); \ 51628b629abSPhilippe Mathieu-Daudé node->value = g_strdup(map[i].feature_desc); \ 51728b629abSPhilippe Mathieu-Daudé node->next = list; \ 51828b629abSPhilippe Mathieu-Daudé list = node; \ 51928b629abSPhilippe Mathieu-Daudé bitmap ^= bit; \ 52028b629abSPhilippe Mathieu-Daudé } \ 52128b629abSPhilippe Mathieu-Daudé list; \ 52228b629abSPhilippe Mathieu-Daudé }) 52328b629abSPhilippe Mathieu-Daudé 52428b629abSPhilippe Mathieu-Daudé VirtioDeviceStatus *qmp_decode_status(uint8_t bitmap) 52528b629abSPhilippe Mathieu-Daudé { 52628b629abSPhilippe Mathieu-Daudé VirtioDeviceStatus *status; 52728b629abSPhilippe Mathieu-Daudé uint8_t bit; 52828b629abSPhilippe Mathieu-Daudé int i; 52928b629abSPhilippe Mathieu-Daudé 53028b629abSPhilippe Mathieu-Daudé status = g_new0(VirtioDeviceStatus, 1); 53128b629abSPhilippe Mathieu-Daudé status->statuses = CONVERT_FEATURES(strList, virtio_config_status_map, 53228b629abSPhilippe Mathieu-Daudé 1, bitmap); 53328b629abSPhilippe Mathieu-Daudé status->has_unknown_statuses = bitmap != 0; 53428b629abSPhilippe Mathieu-Daudé if (status->has_unknown_statuses) { 53528b629abSPhilippe Mathieu-Daudé status->unknown_statuses = bitmap; 53628b629abSPhilippe Mathieu-Daudé } 53728b629abSPhilippe Mathieu-Daudé 53828b629abSPhilippe Mathieu-Daudé return status; 53928b629abSPhilippe Mathieu-Daudé } 54028b629abSPhilippe Mathieu-Daudé 54128b629abSPhilippe Mathieu-Daudé VhostDeviceProtocols *qmp_decode_protocols(uint64_t bitmap) 54228b629abSPhilippe Mathieu-Daudé { 54328b629abSPhilippe Mathieu-Daudé VhostDeviceProtocols *vhu_protocols; 54428b629abSPhilippe Mathieu-Daudé uint64_t bit; 54528b629abSPhilippe Mathieu-Daudé int i; 54628b629abSPhilippe Mathieu-Daudé 54728b629abSPhilippe Mathieu-Daudé vhu_protocols = g_new0(VhostDeviceProtocols, 1); 54828b629abSPhilippe Mathieu-Daudé vhu_protocols->protocols = 54928b629abSPhilippe Mathieu-Daudé CONVERT_FEATURES(strList, 55028b629abSPhilippe Mathieu-Daudé vhost_user_protocol_map, 0, bitmap); 55128b629abSPhilippe Mathieu-Daudé vhu_protocols->has_unknown_protocols = bitmap != 0; 55228b629abSPhilippe Mathieu-Daudé if (vhu_protocols->has_unknown_protocols) { 55328b629abSPhilippe Mathieu-Daudé vhu_protocols->unknown_protocols = bitmap; 55428b629abSPhilippe Mathieu-Daudé } 55528b629abSPhilippe Mathieu-Daudé 55628b629abSPhilippe Mathieu-Daudé return vhu_protocols; 55728b629abSPhilippe Mathieu-Daudé } 55828b629abSPhilippe Mathieu-Daudé 55928b629abSPhilippe Mathieu-Daudé VirtioDeviceFeatures *qmp_decode_features(uint16_t device_id, uint64_t bitmap) 56028b629abSPhilippe Mathieu-Daudé { 56128b629abSPhilippe Mathieu-Daudé VirtioDeviceFeatures *features; 56228b629abSPhilippe Mathieu-Daudé uint64_t bit; 56328b629abSPhilippe Mathieu-Daudé int i; 56428b629abSPhilippe Mathieu-Daudé 56528b629abSPhilippe Mathieu-Daudé features = g_new0(VirtioDeviceFeatures, 1); 56628b629abSPhilippe Mathieu-Daudé features->has_dev_features = true; 56728b629abSPhilippe Mathieu-Daudé 56828b629abSPhilippe Mathieu-Daudé /* transport features */ 56928b629abSPhilippe Mathieu-Daudé features->transports = CONVERT_FEATURES(strList, virtio_transport_map, 0, 57028b629abSPhilippe Mathieu-Daudé bitmap); 57128b629abSPhilippe Mathieu-Daudé 57228b629abSPhilippe Mathieu-Daudé /* device features */ 57328b629abSPhilippe Mathieu-Daudé switch (device_id) { 57428b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_SERIAL 57528b629abSPhilippe Mathieu-Daudé case VIRTIO_ID_CONSOLE: 57628b629abSPhilippe Mathieu-Daudé features->dev_features = 57728b629abSPhilippe Mathieu-Daudé CONVERT_FEATURES(strList, virtio_serial_feature_map, 0, bitmap); 57828b629abSPhilippe Mathieu-Daudé break; 57928b629abSPhilippe Mathieu-Daudé #endif 58028b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_BLK 58128b629abSPhilippe Mathieu-Daudé case VIRTIO_ID_BLOCK: 58228b629abSPhilippe Mathieu-Daudé features->dev_features = 58328b629abSPhilippe Mathieu-Daudé CONVERT_FEATURES(strList, virtio_blk_feature_map, 0, bitmap); 58428b629abSPhilippe Mathieu-Daudé break; 58528b629abSPhilippe Mathieu-Daudé #endif 58628b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_GPU 58728b629abSPhilippe Mathieu-Daudé case VIRTIO_ID_GPU: 58828b629abSPhilippe Mathieu-Daudé features->dev_features = 58928b629abSPhilippe Mathieu-Daudé CONVERT_FEATURES(strList, virtio_gpu_feature_map, 0, bitmap); 59028b629abSPhilippe Mathieu-Daudé break; 59128b629abSPhilippe Mathieu-Daudé #endif 59228b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_NET 59328b629abSPhilippe Mathieu-Daudé case VIRTIO_ID_NET: 59428b629abSPhilippe Mathieu-Daudé features->dev_features = 59528b629abSPhilippe Mathieu-Daudé CONVERT_FEATURES(strList, virtio_net_feature_map, 0, bitmap); 59628b629abSPhilippe Mathieu-Daudé break; 59728b629abSPhilippe Mathieu-Daudé #endif 59828b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_SCSI 59928b629abSPhilippe Mathieu-Daudé case VIRTIO_ID_SCSI: 60028b629abSPhilippe Mathieu-Daudé features->dev_features = 60128b629abSPhilippe Mathieu-Daudé CONVERT_FEATURES(strList, virtio_scsi_feature_map, 0, bitmap); 60228b629abSPhilippe Mathieu-Daudé break; 60328b629abSPhilippe Mathieu-Daudé #endif 60428b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_BALLOON 60528b629abSPhilippe Mathieu-Daudé case VIRTIO_ID_BALLOON: 60628b629abSPhilippe Mathieu-Daudé features->dev_features = 60728b629abSPhilippe Mathieu-Daudé CONVERT_FEATURES(strList, virtio_balloon_feature_map, 0, bitmap); 60828b629abSPhilippe Mathieu-Daudé break; 60928b629abSPhilippe Mathieu-Daudé #endif 61028b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_IOMMU 61128b629abSPhilippe Mathieu-Daudé case VIRTIO_ID_IOMMU: 61228b629abSPhilippe Mathieu-Daudé features->dev_features = 61328b629abSPhilippe Mathieu-Daudé CONVERT_FEATURES(strList, virtio_iommu_feature_map, 0, bitmap); 61428b629abSPhilippe Mathieu-Daudé break; 61528b629abSPhilippe Mathieu-Daudé #endif 61628b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_INPUT 61728b629abSPhilippe Mathieu-Daudé case VIRTIO_ID_INPUT: 61828b629abSPhilippe Mathieu-Daudé features->dev_features = 61928b629abSPhilippe Mathieu-Daudé CONVERT_FEATURES(strList, virtio_input_feature_map, 0, bitmap); 62028b629abSPhilippe Mathieu-Daudé break; 62128b629abSPhilippe Mathieu-Daudé #endif 62228b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VHOST_USER_FS 62328b629abSPhilippe Mathieu-Daudé case VIRTIO_ID_FS: 62428b629abSPhilippe Mathieu-Daudé features->dev_features = 62528b629abSPhilippe Mathieu-Daudé CONVERT_FEATURES(strList, virtio_fs_feature_map, 0, bitmap); 62628b629abSPhilippe Mathieu-Daudé break; 62728b629abSPhilippe Mathieu-Daudé #endif 62828b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VHOST_VSOCK 62928b629abSPhilippe Mathieu-Daudé case VIRTIO_ID_VSOCK: 63028b629abSPhilippe Mathieu-Daudé features->dev_features = 63128b629abSPhilippe Mathieu-Daudé CONVERT_FEATURES(strList, virtio_vsock_feature_map, 0, bitmap); 63228b629abSPhilippe Mathieu-Daudé break; 63328b629abSPhilippe Mathieu-Daudé #endif 63428b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_CRYPTO 63528b629abSPhilippe Mathieu-Daudé case VIRTIO_ID_CRYPTO: 63628b629abSPhilippe Mathieu-Daudé features->dev_features = 63728b629abSPhilippe Mathieu-Daudé CONVERT_FEATURES(strList, virtio_crypto_feature_map, 0, bitmap); 63828b629abSPhilippe Mathieu-Daudé break; 63928b629abSPhilippe Mathieu-Daudé #endif 64028b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_MEM 64128b629abSPhilippe Mathieu-Daudé case VIRTIO_ID_MEM: 64228b629abSPhilippe Mathieu-Daudé features->dev_features = 64328b629abSPhilippe Mathieu-Daudé CONVERT_FEATURES(strList, virtio_mem_feature_map, 0, bitmap); 64428b629abSPhilippe Mathieu-Daudé break; 64528b629abSPhilippe Mathieu-Daudé #endif 64628b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_I2C_ADAPTER 64728b629abSPhilippe Mathieu-Daudé case VIRTIO_ID_I2C_ADAPTER: 64828b629abSPhilippe Mathieu-Daudé features->dev_features = 64928b629abSPhilippe Mathieu-Daudé CONVERT_FEATURES(strList, virtio_i2c_feature_map, 0, bitmap); 65028b629abSPhilippe Mathieu-Daudé break; 65128b629abSPhilippe Mathieu-Daudé #endif 65228b629abSPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTIO_RNG 65328b629abSPhilippe Mathieu-Daudé case VIRTIO_ID_RNG: 65428b629abSPhilippe Mathieu-Daudé features->dev_features = 65528b629abSPhilippe Mathieu-Daudé CONVERT_FEATURES(strList, virtio_rng_feature_map, 0, bitmap); 65628b629abSPhilippe Mathieu-Daudé break; 65728b629abSPhilippe Mathieu-Daudé #endif 658*58f81689SJonah Palmer #ifdef CONFIG_VHOST_USER_GPIO 659*58f81689SJonah Palmer case VIRTIO_ID_GPIO: 660*58f81689SJonah Palmer features->dev_features = 661*58f81689SJonah Palmer CONVERT_FEATURES(strList, virtio_gpio_feature_map, 0, bitmap); 662*58f81689SJonah Palmer break; 663*58f81689SJonah Palmer #endif 66428b629abSPhilippe Mathieu-Daudé /* No features */ 66528b629abSPhilippe Mathieu-Daudé case VIRTIO_ID_9P: 66628b629abSPhilippe Mathieu-Daudé case VIRTIO_ID_PMEM: 66728b629abSPhilippe Mathieu-Daudé case VIRTIO_ID_IOMEM: 66828b629abSPhilippe Mathieu-Daudé case VIRTIO_ID_RPMSG: 66928b629abSPhilippe Mathieu-Daudé case VIRTIO_ID_CLOCK: 67028b629abSPhilippe Mathieu-Daudé case VIRTIO_ID_MAC80211_WLAN: 67128b629abSPhilippe Mathieu-Daudé case VIRTIO_ID_MAC80211_HWSIM: 67228b629abSPhilippe Mathieu-Daudé case VIRTIO_ID_RPROC_SERIAL: 67328b629abSPhilippe Mathieu-Daudé case VIRTIO_ID_MEMORY_BALLOON: 67428b629abSPhilippe Mathieu-Daudé case VIRTIO_ID_CAIF: 67528b629abSPhilippe Mathieu-Daudé case VIRTIO_ID_SIGNAL_DIST: 67628b629abSPhilippe Mathieu-Daudé case VIRTIO_ID_PSTORE: 67728b629abSPhilippe Mathieu-Daudé case VIRTIO_ID_SOUND: 67828b629abSPhilippe Mathieu-Daudé case VIRTIO_ID_BT: 67928b629abSPhilippe Mathieu-Daudé case VIRTIO_ID_RPMB: 68028b629abSPhilippe Mathieu-Daudé case VIRTIO_ID_VIDEO_ENCODER: 68128b629abSPhilippe Mathieu-Daudé case VIRTIO_ID_VIDEO_DECODER: 68228b629abSPhilippe Mathieu-Daudé case VIRTIO_ID_SCMI: 68328b629abSPhilippe Mathieu-Daudé case VIRTIO_ID_NITRO_SEC_MOD: 68428b629abSPhilippe Mathieu-Daudé case VIRTIO_ID_WATCHDOG: 68528b629abSPhilippe Mathieu-Daudé case VIRTIO_ID_CAN: 68628b629abSPhilippe Mathieu-Daudé case VIRTIO_ID_DMABUF: 68728b629abSPhilippe Mathieu-Daudé case VIRTIO_ID_PARAM_SERV: 68828b629abSPhilippe Mathieu-Daudé case VIRTIO_ID_AUDIO_POLICY: 68928b629abSPhilippe Mathieu-Daudé break; 69028b629abSPhilippe Mathieu-Daudé default: 69128b629abSPhilippe Mathieu-Daudé g_assert_not_reached(); 69228b629abSPhilippe Mathieu-Daudé } 69328b629abSPhilippe Mathieu-Daudé 69428b629abSPhilippe Mathieu-Daudé features->has_unknown_dev_features = bitmap != 0; 69528b629abSPhilippe Mathieu-Daudé if (features->has_unknown_dev_features) { 69628b629abSPhilippe Mathieu-Daudé features->unknown_dev_features = bitmap; 69728b629abSPhilippe Mathieu-Daudé } 69828b629abSPhilippe Mathieu-Daudé 69928b629abSPhilippe Mathieu-Daudé return features; 70028b629abSPhilippe Mathieu-Daudé } 7019d94c213SPhilippe Mathieu-Daudé 702b532c684SJonah Palmer static int query_dev_child(Object *child, void *opaque) 703b532c684SJonah Palmer { 704b532c684SJonah Palmer VirtioInfoList **vdevs = opaque; 705b532c684SJonah Palmer Object *dev = object_dynamic_cast(child, TYPE_VIRTIO_DEVICE); 706b532c684SJonah Palmer if (dev != NULL && DEVICE(dev)->realized) { 707b532c684SJonah Palmer VirtIODevice *vdev = VIRTIO_DEVICE(dev); 708b532c684SJonah Palmer VirtioInfo *info = g_new(VirtioInfo, 1); 709b532c684SJonah Palmer 710b532c684SJonah Palmer /* Get canonical path & name of device */ 711b532c684SJonah Palmer info->path = object_get_canonical_path(dev); 712b532c684SJonah Palmer info->name = g_strdup(vdev->name); 713b532c684SJonah Palmer QAPI_LIST_PREPEND(*vdevs, info); 714b532c684SJonah Palmer } 715b532c684SJonah Palmer return 0; 716b532c684SJonah Palmer } 717b532c684SJonah Palmer 7189d94c213SPhilippe Mathieu-Daudé VirtioInfoList *qmp_x_query_virtio(Error **errp) 7199d94c213SPhilippe Mathieu-Daudé { 720b532c684SJonah Palmer VirtioInfoList *vdevs = NULL; 7219d94c213SPhilippe Mathieu-Daudé 722b532c684SJonah Palmer /* Query the QOM composition tree recursively for virtio devices */ 723b532c684SJonah Palmer object_child_foreach_recursive(object_get_root(), query_dev_child, &vdevs); 724b532c684SJonah Palmer if (vdevs == NULL) { 725b532c684SJonah Palmer error_setg(errp, "No virtio devices found"); 7269d94c213SPhilippe Mathieu-Daudé } 727b532c684SJonah Palmer return vdevs; 7289d94c213SPhilippe Mathieu-Daudé } 7299d94c213SPhilippe Mathieu-Daudé 7309d94c213SPhilippe Mathieu-Daudé VirtIODevice *qmp_find_virtio_device(const char *path) 7319d94c213SPhilippe Mathieu-Daudé { 732b532c684SJonah Palmer /* Verify the canonical path is a realized virtio device */ 733b532c684SJonah Palmer Object *dev = object_dynamic_cast(object_resolve_path(path, NULL), 734b532c684SJonah Palmer TYPE_VIRTIO_DEVICE); 735b532c684SJonah Palmer if (!dev || !DEVICE(dev)->realized) { 7369d94c213SPhilippe Mathieu-Daudé return NULL; 7379d94c213SPhilippe Mathieu-Daudé } 738b532c684SJonah Palmer return VIRTIO_DEVICE(dev); 7399d94c213SPhilippe Mathieu-Daudé } 7409d94c213SPhilippe Mathieu-Daudé 7419d94c213SPhilippe Mathieu-Daudé VirtioStatus *qmp_x_query_virtio_status(const char *path, Error **errp) 7429d94c213SPhilippe Mathieu-Daudé { 7439d94c213SPhilippe Mathieu-Daudé VirtIODevice *vdev; 7449d94c213SPhilippe Mathieu-Daudé VirtioStatus *status; 7459d94c213SPhilippe Mathieu-Daudé 7469d94c213SPhilippe Mathieu-Daudé vdev = qmp_find_virtio_device(path); 7479d94c213SPhilippe Mathieu-Daudé if (vdev == NULL) { 748b532c684SJonah Palmer error_setg(errp, "Path %s is not a realized VirtIODevice", path); 7499d94c213SPhilippe Mathieu-Daudé return NULL; 7509d94c213SPhilippe Mathieu-Daudé } 7519d94c213SPhilippe Mathieu-Daudé 7529d94c213SPhilippe Mathieu-Daudé status = g_new0(VirtioStatus, 1); 7539d94c213SPhilippe Mathieu-Daudé status->name = g_strdup(vdev->name); 7549d94c213SPhilippe Mathieu-Daudé status->device_id = vdev->device_id; 7559d94c213SPhilippe Mathieu-Daudé status->vhost_started = vdev->vhost_started; 7569d94c213SPhilippe Mathieu-Daudé status->guest_features = qmp_decode_features(vdev->device_id, 7579d94c213SPhilippe Mathieu-Daudé vdev->guest_features); 7589d94c213SPhilippe Mathieu-Daudé status->host_features = qmp_decode_features(vdev->device_id, 7599d94c213SPhilippe Mathieu-Daudé vdev->host_features); 7609d94c213SPhilippe Mathieu-Daudé status->backend_features = qmp_decode_features(vdev->device_id, 7619d94c213SPhilippe Mathieu-Daudé vdev->backend_features); 7629d94c213SPhilippe Mathieu-Daudé 7639d94c213SPhilippe Mathieu-Daudé switch (vdev->device_endian) { 7649d94c213SPhilippe Mathieu-Daudé case VIRTIO_DEVICE_ENDIAN_LITTLE: 7659d94c213SPhilippe Mathieu-Daudé status->device_endian = g_strdup("little"); 7669d94c213SPhilippe Mathieu-Daudé break; 7679d94c213SPhilippe Mathieu-Daudé case VIRTIO_DEVICE_ENDIAN_BIG: 7689d94c213SPhilippe Mathieu-Daudé status->device_endian = g_strdup("big"); 7699d94c213SPhilippe Mathieu-Daudé break; 7709d94c213SPhilippe Mathieu-Daudé default: 7719d94c213SPhilippe Mathieu-Daudé status->device_endian = g_strdup("unknown"); 7729d94c213SPhilippe Mathieu-Daudé break; 7739d94c213SPhilippe Mathieu-Daudé } 7749d94c213SPhilippe Mathieu-Daudé 7759d94c213SPhilippe Mathieu-Daudé status->num_vqs = virtio_get_num_queues(vdev); 7769d94c213SPhilippe Mathieu-Daudé status->status = qmp_decode_status(vdev->status); 7779d94c213SPhilippe Mathieu-Daudé status->isr = vdev->isr; 7789d94c213SPhilippe Mathieu-Daudé status->queue_sel = vdev->queue_sel; 7799d94c213SPhilippe Mathieu-Daudé status->vm_running = vdev->vm_running; 7809d94c213SPhilippe Mathieu-Daudé status->broken = vdev->broken; 7819d94c213SPhilippe Mathieu-Daudé status->disabled = vdev->disabled; 7829d94c213SPhilippe Mathieu-Daudé status->use_started = vdev->use_started; 7839d94c213SPhilippe Mathieu-Daudé status->started = vdev->started; 7849d94c213SPhilippe Mathieu-Daudé status->start_on_kick = vdev->start_on_kick; 7859d94c213SPhilippe Mathieu-Daudé status->disable_legacy_check = vdev->disable_legacy_check; 7869d94c213SPhilippe Mathieu-Daudé status->bus_name = g_strdup(vdev->bus_name); 7879d94c213SPhilippe Mathieu-Daudé status->use_guest_notifier_mask = vdev->use_guest_notifier_mask; 7889d94c213SPhilippe Mathieu-Daudé 7899d94c213SPhilippe Mathieu-Daudé if (vdev->vhost_started) { 7909d94c213SPhilippe Mathieu-Daudé VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev); 7919d94c213SPhilippe Mathieu-Daudé struct vhost_dev *hdev = vdc->get_vhost(vdev); 7929d94c213SPhilippe Mathieu-Daudé 7939d94c213SPhilippe Mathieu-Daudé status->vhost_dev = g_new0(VhostStatus, 1); 7949d94c213SPhilippe Mathieu-Daudé status->vhost_dev->n_mem_sections = hdev->n_mem_sections; 7959d94c213SPhilippe Mathieu-Daudé status->vhost_dev->n_tmp_sections = hdev->n_tmp_sections; 7969d94c213SPhilippe Mathieu-Daudé status->vhost_dev->nvqs = hdev->nvqs; 7979d94c213SPhilippe Mathieu-Daudé status->vhost_dev->vq_index = hdev->vq_index; 7989d94c213SPhilippe Mathieu-Daudé status->vhost_dev->features = 7999d94c213SPhilippe Mathieu-Daudé qmp_decode_features(vdev->device_id, hdev->features); 8009d94c213SPhilippe Mathieu-Daudé status->vhost_dev->acked_features = 8019d94c213SPhilippe Mathieu-Daudé qmp_decode_features(vdev->device_id, hdev->acked_features); 8029d94c213SPhilippe Mathieu-Daudé status->vhost_dev->backend_features = 8039d94c213SPhilippe Mathieu-Daudé qmp_decode_features(vdev->device_id, hdev->backend_features); 8049d94c213SPhilippe Mathieu-Daudé status->vhost_dev->protocol_features = 8059d94c213SPhilippe Mathieu-Daudé qmp_decode_protocols(hdev->protocol_features); 8069d94c213SPhilippe Mathieu-Daudé status->vhost_dev->max_queues = hdev->max_queues; 8079d94c213SPhilippe Mathieu-Daudé status->vhost_dev->backend_cap = hdev->backend_cap; 8089d94c213SPhilippe Mathieu-Daudé status->vhost_dev->log_enabled = hdev->log_enabled; 8099d94c213SPhilippe Mathieu-Daudé status->vhost_dev->log_size = hdev->log_size; 8109d94c213SPhilippe Mathieu-Daudé } 8119d94c213SPhilippe Mathieu-Daudé 8129d94c213SPhilippe Mathieu-Daudé return status; 8139d94c213SPhilippe Mathieu-Daudé } 8149d94c213SPhilippe Mathieu-Daudé 8159d94c213SPhilippe Mathieu-Daudé VirtVhostQueueStatus *qmp_x_query_virtio_vhost_queue_status(const char *path, 8169d94c213SPhilippe Mathieu-Daudé uint16_t queue, 8179d94c213SPhilippe Mathieu-Daudé Error **errp) 8189d94c213SPhilippe Mathieu-Daudé { 8199d94c213SPhilippe Mathieu-Daudé VirtIODevice *vdev; 8209d94c213SPhilippe Mathieu-Daudé VirtVhostQueueStatus *status; 8219d94c213SPhilippe Mathieu-Daudé 8229d94c213SPhilippe Mathieu-Daudé vdev = qmp_find_virtio_device(path); 8239d94c213SPhilippe Mathieu-Daudé if (vdev == NULL) { 8249d94c213SPhilippe Mathieu-Daudé error_setg(errp, "Path %s is not a VirtIODevice", path); 8259d94c213SPhilippe Mathieu-Daudé return NULL; 8269d94c213SPhilippe Mathieu-Daudé } 8279d94c213SPhilippe Mathieu-Daudé 8289d94c213SPhilippe Mathieu-Daudé if (!vdev->vhost_started) { 8299d94c213SPhilippe Mathieu-Daudé error_setg(errp, "Error: vhost device has not started yet"); 8309d94c213SPhilippe Mathieu-Daudé return NULL; 8319d94c213SPhilippe Mathieu-Daudé } 8329d94c213SPhilippe Mathieu-Daudé 8339d94c213SPhilippe Mathieu-Daudé VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev); 8349d94c213SPhilippe Mathieu-Daudé struct vhost_dev *hdev = vdc->get_vhost(vdev); 8359d94c213SPhilippe Mathieu-Daudé 8369d94c213SPhilippe Mathieu-Daudé if (queue < hdev->vq_index || queue >= hdev->vq_index + hdev->nvqs) { 8379d94c213SPhilippe Mathieu-Daudé error_setg(errp, "Invalid vhost virtqueue number %d", queue); 8389d94c213SPhilippe Mathieu-Daudé return NULL; 8399d94c213SPhilippe Mathieu-Daudé } 8409d94c213SPhilippe Mathieu-Daudé 8419d94c213SPhilippe Mathieu-Daudé status = g_new0(VirtVhostQueueStatus, 1); 8429d94c213SPhilippe Mathieu-Daudé status->name = g_strdup(vdev->name); 8439d94c213SPhilippe Mathieu-Daudé status->kick = hdev->vqs[queue].kick; 8449d94c213SPhilippe Mathieu-Daudé status->call = hdev->vqs[queue].call; 8459d94c213SPhilippe Mathieu-Daudé status->desc = (uintptr_t)hdev->vqs[queue].desc; 8469d94c213SPhilippe Mathieu-Daudé status->avail = (uintptr_t)hdev->vqs[queue].avail; 8479d94c213SPhilippe Mathieu-Daudé status->used = (uintptr_t)hdev->vqs[queue].used; 8489d94c213SPhilippe Mathieu-Daudé status->num = hdev->vqs[queue].num; 8499d94c213SPhilippe Mathieu-Daudé status->desc_phys = hdev->vqs[queue].desc_phys; 8509d94c213SPhilippe Mathieu-Daudé status->desc_size = hdev->vqs[queue].desc_size; 8519d94c213SPhilippe Mathieu-Daudé status->avail_phys = hdev->vqs[queue].avail_phys; 8529d94c213SPhilippe Mathieu-Daudé status->avail_size = hdev->vqs[queue].avail_size; 8539d94c213SPhilippe Mathieu-Daudé status->used_phys = hdev->vqs[queue].used_phys; 8549d94c213SPhilippe Mathieu-Daudé status->used_size = hdev->vqs[queue].used_size; 8559d94c213SPhilippe Mathieu-Daudé 8569d94c213SPhilippe Mathieu-Daudé return status; 8579d94c213SPhilippe Mathieu-Daudé } 858