hw/virtio: Extract QMP related code virtio-qmp.c

The monitor decoders are the only functions using the CONFIG_xxx
definitions declared in the target specific CONFIG_DEVICES header.

Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-Id: <20221213111707.34921-7-philmd@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <a class="moz-txt-link-rfc2396E" href="mailto:philmd@linaro.org">&lt;philmd@linaro.org&gt;</a>
This commit is contained in:
Philippe Mathieu-Daudé 2022-12-13 12:17:07 +01:00 committed by Michael S. Tsirkin
parent 0f4b91f146
commit 28b629ab4a
4 changed files with 682 additions and 634 deletions

View File

@ -5,7 +5,7 @@ softmmu_virtio_ss.add(when: 'CONFIG_VIRTIO_MMIO', if_true: files('virtio-mmio.c'
specific_virtio_ss = ss.source_set()
specific_virtio_ss.add(files('virtio.c'))
specific_virtio_ss.add(files('virtio-config-io.c'))
specific_virtio_ss.add(files('virtio-config-io.c', 'virtio-qmp.c'))
if have_vhost
specific_virtio_ss.add(files('vhost.c', 'vhost-backend.c', 'vhost-iova-tree.c'))

659
hw/virtio/virtio-qmp.c Normal file
View File

@ -0,0 +1,659 @@
/*
* Virtio QMP helpers
*
* Copyright IBM, Corp. 2007
*
* Authors:
* Anthony Liguori <aliguori@us.ibm.com>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "qemu/osdep.h"
#include "hw/virtio/virtio.h"
#include "virtio-qmp.h"
#include "standard-headers/linux/virtio_ids.h"
#include "standard-headers/linux/vhost_types.h"
#include "standard-headers/linux/virtio_blk.h"
#include "standard-headers/linux/virtio_console.h"
#include "standard-headers/linux/virtio_gpu.h"
#include "standard-headers/linux/virtio_net.h"
#include "standard-headers/linux/virtio_scsi.h"
#include "standard-headers/linux/virtio_i2c.h"
#include "standard-headers/linux/virtio_balloon.h"
#include "standard-headers/linux/virtio_iommu.h"
#include "standard-headers/linux/virtio_mem.h"
#include "standard-headers/linux/virtio_vsock.h"
#include CONFIG_DEVICES
#define FEATURE_ENTRY(name, desc) (qmp_virtio_feature_map_t) \
{ .virtio_bit = name, .feature_desc = desc }
enum VhostUserProtocolFeature {
VHOST_USER_PROTOCOL_F_MQ = 0,
VHOST_USER_PROTOCOL_F_LOG_SHMFD = 1,
VHOST_USER_PROTOCOL_F_RARP = 2,
VHOST_USER_PROTOCOL_F_REPLY_ACK = 3,
VHOST_USER_PROTOCOL_F_NET_MTU = 4,
VHOST_USER_PROTOCOL_F_SLAVE_REQ = 5,
VHOST_USER_PROTOCOL_F_CROSS_ENDIAN = 6,
VHOST_USER_PROTOCOL_F_CRYPTO_SESSION = 7,
VHOST_USER_PROTOCOL_F_PAGEFAULT = 8,
VHOST_USER_PROTOCOL_F_CONFIG = 9,
VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD = 10,
VHOST_USER_PROTOCOL_F_HOST_NOTIFIER = 11,
VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD = 12,
VHOST_USER_PROTOCOL_F_RESET_DEVICE = 13,
VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS = 14,
VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS = 15,
VHOST_USER_PROTOCOL_F_MAX
};
/* Virtio transport features mapping */
static const qmp_virtio_feature_map_t virtio_transport_map[] = {
/* Virtio device transport features */
#ifndef VIRTIO_CONFIG_NO_LEGACY
FEATURE_ENTRY(VIRTIO_F_NOTIFY_ON_EMPTY, \
"VIRTIO_F_NOTIFY_ON_EMPTY: Notify when device runs out of avail. "
"descs. on VQ"),
FEATURE_ENTRY(VIRTIO_F_ANY_LAYOUT, \
"VIRTIO_F_ANY_LAYOUT: Device accepts arbitrary desc. layouts"),
#endif /* !VIRTIO_CONFIG_NO_LEGACY */
FEATURE_ENTRY(VIRTIO_F_VERSION_1, \
"VIRTIO_F_VERSION_1: Device compliant for v1 spec (legacy)"),
FEATURE_ENTRY(VIRTIO_F_IOMMU_PLATFORM, \
"VIRTIO_F_IOMMU_PLATFORM: Device can be used on IOMMU platform"),
FEATURE_ENTRY(VIRTIO_F_RING_PACKED, \
"VIRTIO_F_RING_PACKED: Device supports packed VQ layout"),
FEATURE_ENTRY(VIRTIO_F_IN_ORDER, \
"VIRTIO_F_IN_ORDER: Device uses buffers in same order as made "
"available by driver"),
FEATURE_ENTRY(VIRTIO_F_ORDER_PLATFORM, \
"VIRTIO_F_ORDER_PLATFORM: Memory accesses ordered by platform"),
FEATURE_ENTRY(VIRTIO_F_SR_IOV, \
"VIRTIO_F_SR_IOV: Device supports single root I/O virtualization"),
/* Virtio ring transport features */
FEATURE_ENTRY(VIRTIO_RING_F_INDIRECT_DESC, \
"VIRTIO_RING_F_INDIRECT_DESC: Indirect descriptors supported"),
FEATURE_ENTRY(VIRTIO_RING_F_EVENT_IDX, \
"VIRTIO_RING_F_EVENT_IDX: Used & avail. event fields enabled"),
{ -1, "" }
};
/* Vhost-user protocol features mapping */
static const qmp_virtio_feature_map_t vhost_user_protocol_map[] = {
FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_MQ, \
"VHOST_USER_PROTOCOL_F_MQ: Multiqueue protocol supported"),
FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_LOG_SHMFD, \
"VHOST_USER_PROTOCOL_F_LOG_SHMFD: Shared log memory fd supported"),
FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_RARP, \
"VHOST_USER_PROTOCOL_F_RARP: Vhost-user back-end RARP broadcasting "
"supported"),
FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_REPLY_ACK, \
"VHOST_USER_PROTOCOL_F_REPLY_ACK: Requested operation status ack. "
"supported"),
FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_NET_MTU, \
"VHOST_USER_PROTOCOL_F_NET_MTU: Expose host MTU to guest supported"),
FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_SLAVE_REQ, \
"VHOST_USER_PROTOCOL_F_SLAVE_REQ: Socket fd for back-end initiated "
"requests supported"),
FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_CROSS_ENDIAN, \
"VHOST_USER_PROTOCOL_F_CROSS_ENDIAN: Endianness of VQs for legacy "
"devices supported"),
FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_CRYPTO_SESSION, \
"VHOST_USER_PROTOCOL_F_CRYPTO_SESSION: Session creation for crypto "
"operations supported"),
FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_PAGEFAULT, \
"VHOST_USER_PROTOCOL_F_PAGEFAULT: Request servicing on userfaultfd "
"for accessed pages supported"),
FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_CONFIG, \
"VHOST_USER_PROTOCOL_F_CONFIG: Vhost-user messaging for virtio "
"device configuration space supported"),
FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD, \
"VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD: Slave fd communication "
"channel supported"),
FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_HOST_NOTIFIER, \
"VHOST_USER_PROTOCOL_F_HOST_NOTIFIER: Host notifiers for specified "
"VQs supported"),
FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD, \
"VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD: Shared inflight I/O buffers "
"supported"),
FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_RESET_DEVICE, \
"VHOST_USER_PROTOCOL_F_RESET_DEVICE: Disabling all rings and "
"resetting internal device state supported"),
FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS, \
"VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS: In-band messaging "
"supported"),
FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS, \
"VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS: Configuration for "
"memory slots supported"),
{ -1, "" }
};
/* virtio device configuration statuses */
static const qmp_virtio_feature_map_t virtio_config_status_map[] = {
FEATURE_ENTRY(VIRTIO_CONFIG_S_DRIVER_OK, \
"VIRTIO_CONFIG_S_DRIVER_OK: Driver setup and ready"),
FEATURE_ENTRY(VIRTIO_CONFIG_S_FEATURES_OK, \
"VIRTIO_CONFIG_S_FEATURES_OK: Feature negotiation complete"),
FEATURE_ENTRY(VIRTIO_CONFIG_S_DRIVER, \
"VIRTIO_CONFIG_S_DRIVER: Guest OS compatible with device"),
FEATURE_ENTRY(VIRTIO_CONFIG_S_NEEDS_RESET, \
"VIRTIO_CONFIG_S_NEEDS_RESET: Irrecoverable error, device needs "
"reset"),
FEATURE_ENTRY(VIRTIO_CONFIG_S_FAILED, \
"VIRTIO_CONFIG_S_FAILED: Error in guest, device failed"),
FEATURE_ENTRY(VIRTIO_CONFIG_S_ACKNOWLEDGE, \
"VIRTIO_CONFIG_S_ACKNOWLEDGE: Valid virtio device found"),
{ -1, "" }
};
/* virtio-blk features mapping */
#ifdef CONFIG_VIRTIO_BLK
static const qmp_virtio_feature_map_t virtio_blk_feature_map[] = {
FEATURE_ENTRY(VIRTIO_BLK_F_SIZE_MAX, \
"VIRTIO_BLK_F_SIZE_MAX: Max segment size is size_max"),
FEATURE_ENTRY(VIRTIO_BLK_F_SEG_MAX, \
"VIRTIO_BLK_F_SEG_MAX: Max segments in a request is seg_max"),
FEATURE_ENTRY(VIRTIO_BLK_F_GEOMETRY, \
"VIRTIO_BLK_F_GEOMETRY: Legacy geometry available"),
FEATURE_ENTRY(VIRTIO_BLK_F_RO, \
"VIRTIO_BLK_F_RO: Device is read-only"),
FEATURE_ENTRY(VIRTIO_BLK_F_BLK_SIZE, \
"VIRTIO_BLK_F_BLK_SIZE: Block size of disk available"),
FEATURE_ENTRY(VIRTIO_BLK_F_TOPOLOGY, \
"VIRTIO_BLK_F_TOPOLOGY: Topology information available"),
FEATURE_ENTRY(VIRTIO_BLK_F_MQ, \
"VIRTIO_BLK_F_MQ: Multiqueue supported"),
FEATURE_ENTRY(VIRTIO_BLK_F_DISCARD, \
"VIRTIO_BLK_F_DISCARD: Discard command supported"),
FEATURE_ENTRY(VIRTIO_BLK_F_WRITE_ZEROES, \
"VIRTIO_BLK_F_WRITE_ZEROES: Write zeroes command supported"),
#ifndef VIRTIO_BLK_NO_LEGACY
FEATURE_ENTRY(VIRTIO_BLK_F_BARRIER, \
"VIRTIO_BLK_F_BARRIER: Request barriers supported"),
FEATURE_ENTRY(VIRTIO_BLK_F_SCSI, \
"VIRTIO_BLK_F_SCSI: SCSI packet commands supported"),
FEATURE_ENTRY(VIRTIO_BLK_F_FLUSH, \
"VIRTIO_BLK_F_FLUSH: Flush command supported"),
FEATURE_ENTRY(VIRTIO_BLK_F_CONFIG_WCE, \
"VIRTIO_BLK_F_CONFIG_WCE: Cache writeback and writethrough modes "
"supported"),
#endif /* !VIRTIO_BLK_NO_LEGACY */
FEATURE_ENTRY(VHOST_F_LOG_ALL, \
"VHOST_F_LOG_ALL: Logging write descriptors supported"),
FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
"VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
"negotiation supported"),
{ -1, "" }
};
#endif
/* virtio-serial features mapping */
#ifdef CONFIG_VIRTIO_SERIAL
static const qmp_virtio_feature_map_t virtio_serial_feature_map[] = {
FEATURE_ENTRY(VIRTIO_CONSOLE_F_SIZE, \
"VIRTIO_CONSOLE_F_SIZE: Host providing console size"),
FEATURE_ENTRY(VIRTIO_CONSOLE_F_MULTIPORT, \
"VIRTIO_CONSOLE_F_MULTIPORT: Multiple ports for device supported"),
FEATURE_ENTRY(VIRTIO_CONSOLE_F_EMERG_WRITE, \
"VIRTIO_CONSOLE_F_EMERG_WRITE: Emergency write supported"),
{ -1, "" }
};
#endif
/* virtio-gpu features mapping */
#ifdef CONFIG_VIRTIO_GPU
static const qmp_virtio_feature_map_t virtio_gpu_feature_map[] = {
FEATURE_ENTRY(VIRTIO_GPU_F_VIRGL, \
"VIRTIO_GPU_F_VIRGL: Virgl 3D mode supported"),
FEATURE_ENTRY(VIRTIO_GPU_F_EDID, \
"VIRTIO_GPU_F_EDID: EDID metadata supported"),
FEATURE_ENTRY(VIRTIO_GPU_F_RESOURCE_UUID, \
"VIRTIO_GPU_F_RESOURCE_UUID: Resource UUID assigning supported"),
FEATURE_ENTRY(VIRTIO_GPU_F_RESOURCE_BLOB, \
"VIRTIO_GPU_F_RESOURCE_BLOB: Size-based blob resources supported"),
FEATURE_ENTRY(VIRTIO_GPU_F_CONTEXT_INIT, \
"VIRTIO_GPU_F_CONTEXT_INIT: Context types and synchronization "
"timelines supported"),
FEATURE_ENTRY(VHOST_F_LOG_ALL, \
"VHOST_F_LOG_ALL: Logging write descriptors supported"),
FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
"VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
"negotiation supported"),
{ -1, "" }
};
#endif
/* virtio-input features mapping */
#ifdef CONFIG_VIRTIO_INPUT
static const qmp_virtio_feature_map_t virtio_input_feature_map[] = {
FEATURE_ENTRY(VHOST_F_LOG_ALL, \
"VHOST_F_LOG_ALL: Logging write descriptors supported"),
FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
"VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
"negotiation supported"),
{ -1, "" }
};
#endif
/* virtio-net features mapping */
#ifdef CONFIG_VIRTIO_NET
static const qmp_virtio_feature_map_t virtio_net_feature_map[] = {
FEATURE_ENTRY(VIRTIO_NET_F_CSUM, \
"VIRTIO_NET_F_CSUM: Device handling packets with partial checksum "
"supported"),
FEATURE_ENTRY(VIRTIO_NET_F_GUEST_CSUM, \
"VIRTIO_NET_F_GUEST_CSUM: Driver handling packets with partial "
"checksum supported"),
FEATURE_ENTRY(VIRTIO_NET_F_CTRL_GUEST_OFFLOADS, \
"VIRTIO_NET_F_CTRL_GUEST_OFFLOADS: Control channel offloading "
"reconfig. supported"),
FEATURE_ENTRY(VIRTIO_NET_F_MTU, \
"VIRTIO_NET_F_MTU: Device max MTU reporting supported"),
FEATURE_ENTRY(VIRTIO_NET_F_MAC, \
"VIRTIO_NET_F_MAC: Device has given MAC address"),
FEATURE_ENTRY(VIRTIO_NET_F_GUEST_TSO4, \
"VIRTIO_NET_F_GUEST_TSO4: Driver can receive TSOv4"),
FEATURE_ENTRY(VIRTIO_NET_F_GUEST_TSO6, \
"VIRTIO_NET_F_GUEST_TSO6: Driver can receive TSOv6"),
FEATURE_ENTRY(VIRTIO_NET_F_GUEST_ECN, \
"VIRTIO_NET_F_GUEST_ECN: Driver can receive TSO with ECN"),
FEATURE_ENTRY(VIRTIO_NET_F_GUEST_UFO, \
"VIRTIO_NET_F_GUEST_UFO: Driver can receive UFO"),
FEATURE_ENTRY(VIRTIO_NET_F_HOST_TSO4, \
"VIRTIO_NET_F_HOST_TSO4: Device can receive TSOv4"),
FEATURE_ENTRY(VIRTIO_NET_F_HOST_TSO6, \
"VIRTIO_NET_F_HOST_TSO6: Device can receive TSOv6"),
FEATURE_ENTRY(VIRTIO_NET_F_HOST_ECN, \
"VIRTIO_NET_F_HOST_ECN: Device can receive TSO with ECN"),
FEATURE_ENTRY(VIRTIO_NET_F_HOST_UFO, \
"VIRTIO_NET_F_HOST_UFO: Device can receive UFO"),
FEATURE_ENTRY(VIRTIO_NET_F_MRG_RXBUF, \
"VIRTIO_NET_F_MRG_RXBUF: Driver can merge receive buffers"),
FEATURE_ENTRY(VIRTIO_NET_F_STATUS, \
"VIRTIO_NET_F_STATUS: Configuration status field available"),
FEATURE_ENTRY(VIRTIO_NET_F_CTRL_VQ, \
"VIRTIO_NET_F_CTRL_VQ: Control channel available"),
FEATURE_ENTRY(VIRTIO_NET_F_CTRL_RX, \
"VIRTIO_NET_F_CTRL_RX: Control channel RX mode supported"),
FEATURE_ENTRY(VIRTIO_NET_F_CTRL_VLAN, \
"VIRTIO_NET_F_CTRL_VLAN: Control channel VLAN filtering supported"),
FEATURE_ENTRY(VIRTIO_NET_F_CTRL_RX_EXTRA, \
"VIRTIO_NET_F_CTRL_RX_EXTRA: Extra RX mode control supported"),
FEATURE_ENTRY(VIRTIO_NET_F_GUEST_ANNOUNCE, \
"VIRTIO_NET_F_GUEST_ANNOUNCE: Driver sending gratuitous packets "
"supported"),
FEATURE_ENTRY(VIRTIO_NET_F_MQ, \
"VIRTIO_NET_F_MQ: Multiqueue with automatic receive steering "
"supported"),
FEATURE_ENTRY(VIRTIO_NET_F_CTRL_MAC_ADDR, \
"VIRTIO_NET_F_CTRL_MAC_ADDR: MAC address set through control "
"channel"),
FEATURE_ENTRY(VIRTIO_NET_F_HASH_REPORT, \
"VIRTIO_NET_F_HASH_REPORT: Hash reporting supported"),
FEATURE_ENTRY(VIRTIO_NET_F_RSS, \
"VIRTIO_NET_F_RSS: RSS RX steering supported"),
FEATURE_ENTRY(VIRTIO_NET_F_RSC_EXT, \
"VIRTIO_NET_F_RSC_EXT: Extended coalescing info supported"),
FEATURE_ENTRY(VIRTIO_NET_F_STANDBY, \
"VIRTIO_NET_F_STANDBY: Device acting as standby for primary "
"device with same MAC addr. supported"),
FEATURE_ENTRY(VIRTIO_NET_F_SPEED_DUPLEX, \
"VIRTIO_NET_F_SPEED_DUPLEX: Device set linkspeed and duplex"),
#ifndef VIRTIO_NET_NO_LEGACY
FEATURE_ENTRY(VIRTIO_NET_F_GSO, \
"VIRTIO_NET_F_GSO: Handling GSO-type packets supported"),
#endif /* !VIRTIO_NET_NO_LEGACY */
FEATURE_ENTRY(VHOST_NET_F_VIRTIO_NET_HDR, \
"VHOST_NET_F_VIRTIO_NET_HDR: Virtio-net headers for RX and TX "
"packets supported"),
FEATURE_ENTRY(VHOST_F_LOG_ALL, \
"VHOST_F_LOG_ALL: Logging write descriptors supported"),
FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
"VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
"negotiation supported"),
{ -1, "" }
};
#endif
/* virtio-scsi features mapping */
#ifdef CONFIG_VIRTIO_SCSI
static const qmp_virtio_feature_map_t virtio_scsi_feature_map[] = {
FEATURE_ENTRY(VIRTIO_SCSI_F_INOUT, \
"VIRTIO_SCSI_F_INOUT: Requests including read and writable data "
"buffers suppoted"),
FEATURE_ENTRY(VIRTIO_SCSI_F_HOTPLUG, \
"VIRTIO_SCSI_F_HOTPLUG: Reporting and handling hot-plug events "
"supported"),
FEATURE_ENTRY(VIRTIO_SCSI_F_CHANGE, \
"VIRTIO_SCSI_F_CHANGE: Reporting and handling LUN changes "
"supported"),
FEATURE_ENTRY(VIRTIO_SCSI_F_T10_PI, \
"VIRTIO_SCSI_F_T10_PI: T10 info included in request header"),
FEATURE_ENTRY(VHOST_F_LOG_ALL, \
"VHOST_F_LOG_ALL: Logging write descriptors supported"),
FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
"VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
"negotiation supported"),
{ -1, "" }
};
#endif
/* virtio/vhost-user-fs features mapping */
#ifdef CONFIG_VHOST_USER_FS
static const qmp_virtio_feature_map_t virtio_fs_feature_map[] = {
FEATURE_ENTRY(VHOST_F_LOG_ALL, \
"VHOST_F_LOG_ALL: Logging write descriptors supported"),
FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
"VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
"negotiation supported"),
{ -1, "" }
};
#endif
/* virtio/vhost-user-i2c features mapping */
#ifdef CONFIG_VIRTIO_I2C_ADAPTER
static const qmp_virtio_feature_map_t virtio_i2c_feature_map[] = {
FEATURE_ENTRY(VIRTIO_I2C_F_ZERO_LENGTH_REQUEST, \
"VIRTIO_I2C_F_ZERO_LEGNTH_REQUEST: Zero length requests supported"),
FEATURE_ENTRY(VHOST_F_LOG_ALL, \
"VHOST_F_LOG_ALL: Logging write descriptors supported"),
FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
"VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
"negotiation supported"),
{ -1, "" }
};
#endif
/* virtio/vhost-vsock features mapping */
#ifdef CONFIG_VHOST_VSOCK
static const qmp_virtio_feature_map_t virtio_vsock_feature_map[] = {
FEATURE_ENTRY(VIRTIO_VSOCK_F_SEQPACKET, \
"VIRTIO_VSOCK_F_SEQPACKET: SOCK_SEQPACKET supported"),
FEATURE_ENTRY(VHOST_F_LOG_ALL, \
"VHOST_F_LOG_ALL: Logging write descriptors supported"),
FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
"VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
"negotiation supported"),
{ -1, "" }
};
#endif
/* virtio-balloon features mapping */
#ifdef CONFIG_VIRTIO_BALLOON
static const qmp_virtio_feature_map_t virtio_balloon_feature_map[] = {
FEATURE_ENTRY(VIRTIO_BALLOON_F_MUST_TELL_HOST, \
"VIRTIO_BALLOON_F_MUST_TELL_HOST: Tell host before reclaiming "
"pages"),
FEATURE_ENTRY(VIRTIO_BALLOON_F_STATS_VQ, \
"VIRTIO_BALLOON_F_STATS_VQ: Guest memory stats VQ available"),
FEATURE_ENTRY(VIRTIO_BALLOON_F_DEFLATE_ON_OOM, \
"VIRTIO_BALLOON_F_DEFLATE_ON_OOM: Deflate balloon when guest OOM"),
FEATURE_ENTRY(VIRTIO_BALLOON_F_FREE_PAGE_HINT, \
"VIRTIO_BALLOON_F_FREE_PAGE_HINT: VQ reporting free pages enabled"),
FEATURE_ENTRY(VIRTIO_BALLOON_F_PAGE_POISON, \
"VIRTIO_BALLOON_F_PAGE_POISON: Guest page poisoning enabled"),
FEATURE_ENTRY(VIRTIO_BALLOON_F_REPORTING, \
"VIRTIO_BALLOON_F_REPORTING: Page reporting VQ enabled"),
{ -1, "" }
};
#endif
/* virtio-crypto features mapping */
#ifdef CONFIG_VIRTIO_CRYPTO
static const qmp_virtio_feature_map_t virtio_crypto_feature_map[] = {
FEATURE_ENTRY(VHOST_F_LOG_ALL, \
"VHOST_F_LOG_ALL: Logging write descriptors supported"),
{ -1, "" }
};
#endif
/* virtio-iommu features mapping */
#ifdef CONFIG_VIRTIO_IOMMU
static const qmp_virtio_feature_map_t virtio_iommu_feature_map[] = {
FEATURE_ENTRY(VIRTIO_IOMMU_F_INPUT_RANGE, \
"VIRTIO_IOMMU_F_INPUT_RANGE: Range of available virtual addrs. "
"available"),
FEATURE_ENTRY(VIRTIO_IOMMU_F_DOMAIN_RANGE, \
"VIRTIO_IOMMU_F_DOMAIN_RANGE: Number of supported domains "
"available"),
FEATURE_ENTRY(VIRTIO_IOMMU_F_MAP_UNMAP, \
"VIRTIO_IOMMU_F_MAP_UNMAP: Map and unmap requests available"),
FEATURE_ENTRY(VIRTIO_IOMMU_F_BYPASS, \
"VIRTIO_IOMMU_F_BYPASS: Endpoints not attached to domains are in "
"bypass mode"),
FEATURE_ENTRY(VIRTIO_IOMMU_F_PROBE, \
"VIRTIO_IOMMU_F_PROBE: Probe requests available"),
FEATURE_ENTRY(VIRTIO_IOMMU_F_MMIO, \
"VIRTIO_IOMMU_F_MMIO: VIRTIO_IOMMU_MAP_F_MMIO flag available"),
FEATURE_ENTRY(VIRTIO_IOMMU_F_BYPASS_CONFIG, \
"VIRTIO_IOMMU_F_BYPASS_CONFIG: Bypass field of IOMMU config "
"available"),
{ -1, "" }
};
#endif
/* virtio-mem features mapping */
#ifdef CONFIG_VIRTIO_MEM
static const qmp_virtio_feature_map_t virtio_mem_feature_map[] = {
#ifndef CONFIG_ACPI
FEATURE_ENTRY(VIRTIO_MEM_F_ACPI_PXM, \
"VIRTIO_MEM_F_ACPI_PXM: node_id is an ACPI PXM and is valid"),
#endif /* !CONFIG_ACPI */
FEATURE_ENTRY(VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE, \
"VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE: Unplugged memory cannot be "
"accessed"),
{ -1, "" }
};
#endif
/* virtio-rng features mapping */
#ifdef CONFIG_VIRTIO_RNG
static const qmp_virtio_feature_map_t virtio_rng_feature_map[] = {
FEATURE_ENTRY(VHOST_F_LOG_ALL, \
"VHOST_F_LOG_ALL: Logging write descriptors supported"),
FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
"VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
"negotiation supported"),
{ -1, "" }
};
#endif
#define CONVERT_FEATURES(type, map, is_status, bitmap) \
({ \
type *list = NULL; \
type *node; \
for (i = 0; map[i].virtio_bit != -1; i++) { \
if (is_status) { \
bit = map[i].virtio_bit; \
} \
else { \
bit = 1ULL << map[i].virtio_bit; \
} \
if ((bitmap & bit) == 0) { \
continue; \
} \
node = g_new0(type, 1); \
node->value = g_strdup(map[i].feature_desc); \
node->next = list; \
list = node; \
bitmap ^= bit; \
} \
list; \
})
VirtioDeviceStatus *qmp_decode_status(uint8_t bitmap)
{
VirtioDeviceStatus *status;
uint8_t bit;
int i;
status = g_new0(VirtioDeviceStatus, 1);
status->statuses = CONVERT_FEATURES(strList, virtio_config_status_map,
1, bitmap);
status->has_unknown_statuses = bitmap != 0;
if (status->has_unknown_statuses) {
status->unknown_statuses = bitmap;
}
return status;
}
VhostDeviceProtocols *qmp_decode_protocols(uint64_t bitmap)
{
VhostDeviceProtocols *vhu_protocols;
uint64_t bit;
int i;
vhu_protocols = g_new0(VhostDeviceProtocols, 1);
vhu_protocols->protocols =
CONVERT_FEATURES(strList,
vhost_user_protocol_map, 0, bitmap);
vhu_protocols->has_unknown_protocols = bitmap != 0;
if (vhu_protocols->has_unknown_protocols) {
vhu_protocols->unknown_protocols = bitmap;
}
return vhu_protocols;
}
VirtioDeviceFeatures *qmp_decode_features(uint16_t device_id, uint64_t bitmap)
{
VirtioDeviceFeatures *features;
uint64_t bit;
int i;
features = g_new0(VirtioDeviceFeatures, 1);
features->has_dev_features = true;
/* transport features */
features->transports = CONVERT_FEATURES(strList, virtio_transport_map, 0,
bitmap);
/* device features */
switch (device_id) {
#ifdef CONFIG_VIRTIO_SERIAL
case VIRTIO_ID_CONSOLE:
features->dev_features =
CONVERT_FEATURES(strList, virtio_serial_feature_map, 0, bitmap);
break;
#endif
#ifdef CONFIG_VIRTIO_BLK
case VIRTIO_ID_BLOCK:
features->dev_features =
CONVERT_FEATURES(strList, virtio_blk_feature_map, 0, bitmap);
break;
#endif
#ifdef CONFIG_VIRTIO_GPU
case VIRTIO_ID_GPU:
features->dev_features =
CONVERT_FEATURES(strList, virtio_gpu_feature_map, 0, bitmap);
break;
#endif
#ifdef CONFIG_VIRTIO_NET
case VIRTIO_ID_NET:
features->dev_features =
CONVERT_FEATURES(strList, virtio_net_feature_map, 0, bitmap);
break;
#endif
#ifdef CONFIG_VIRTIO_SCSI
case VIRTIO_ID_SCSI:
features->dev_features =
CONVERT_FEATURES(strList, virtio_scsi_feature_map, 0, bitmap);
break;
#endif
#ifdef CONFIG_VIRTIO_BALLOON
case VIRTIO_ID_BALLOON:
features->dev_features =
CONVERT_FEATURES(strList, virtio_balloon_feature_map, 0, bitmap);
break;
#endif
#ifdef CONFIG_VIRTIO_IOMMU
case VIRTIO_ID_IOMMU:
features->dev_features =
CONVERT_FEATURES(strList, virtio_iommu_feature_map, 0, bitmap);
break;
#endif
#ifdef CONFIG_VIRTIO_INPUT
case VIRTIO_ID_INPUT:
features->dev_features =
CONVERT_FEATURES(strList, virtio_input_feature_map, 0, bitmap);
break;
#endif
#ifdef CONFIG_VHOST_USER_FS
case VIRTIO_ID_FS:
features->dev_features =
CONVERT_FEATURES(strList, virtio_fs_feature_map, 0, bitmap);
break;
#endif
#ifdef CONFIG_VHOST_VSOCK
case VIRTIO_ID_VSOCK:
features->dev_features =
CONVERT_FEATURES(strList, virtio_vsock_feature_map, 0, bitmap);
break;
#endif
#ifdef CONFIG_VIRTIO_CRYPTO
case VIRTIO_ID_CRYPTO:
features->dev_features =
CONVERT_FEATURES(strList, virtio_crypto_feature_map, 0, bitmap);
break;
#endif
#ifdef CONFIG_VIRTIO_MEM
case VIRTIO_ID_MEM:
features->dev_features =
CONVERT_FEATURES(strList, virtio_mem_feature_map, 0, bitmap);
break;
#endif
#ifdef CONFIG_VIRTIO_I2C_ADAPTER
case VIRTIO_ID_I2C_ADAPTER:
features->dev_features =
CONVERT_FEATURES(strList, virtio_i2c_feature_map, 0, bitmap);
break;
#endif
#ifdef CONFIG_VIRTIO_RNG
case VIRTIO_ID_RNG:
features->dev_features =
CONVERT_FEATURES(strList, virtio_rng_feature_map, 0, bitmap);
break;
#endif
/* No features */
case VIRTIO_ID_9P:
case VIRTIO_ID_PMEM:
case VIRTIO_ID_IOMEM:
case VIRTIO_ID_RPMSG:
case VIRTIO_ID_CLOCK:
case VIRTIO_ID_MAC80211_WLAN:
case VIRTIO_ID_MAC80211_HWSIM:
case VIRTIO_ID_RPROC_SERIAL:
case VIRTIO_ID_MEMORY_BALLOON:
case VIRTIO_ID_CAIF:
case VIRTIO_ID_SIGNAL_DIST:
case VIRTIO_ID_PSTORE:
case VIRTIO_ID_SOUND:
case VIRTIO_ID_BT:
case VIRTIO_ID_RPMB:
case VIRTIO_ID_VIDEO_ENCODER:
case VIRTIO_ID_VIDEO_DECODER:
case VIRTIO_ID_SCMI:
case VIRTIO_ID_NITRO_SEC_MOD:
case VIRTIO_ID_WATCHDOG:
case VIRTIO_ID_CAN:
case VIRTIO_ID_DMABUF:
case VIRTIO_ID_PARAM_SERV:
case VIRTIO_ID_AUDIO_POLICY:
case VIRTIO_ID_GPIO:
break;
default:
g_assert_not_reached();
}
features->has_unknown_dev_features = bitmap != 0;
if (features->has_unknown_dev_features) {
features->unknown_dev_features = bitmap;
}
return features;
}

20
hw/virtio/virtio-qmp.h Normal file
View File

@ -0,0 +1,20 @@
/*
* Virtio QMP helpers
*
* Copyright IBM, Corp. 2007
*
* Authors:
* Anthony Liguori <aliguori@us.ibm.com>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef HW_VIRTIO_QMP_H
#define HW_VIRTIO_QMP_H
#include "qapi/qapi-types-virtio.h"
VirtioDeviceStatus *qmp_decode_status(uint8_t bitmap);
VhostDeviceProtocols *qmp_decode_protocols(uint64_t bitmap);
VirtioDeviceFeatures *qmp_decode_features(uint16_t device_id, uint64_t bitmap);
#endif

View File

@ -16,7 +16,6 @@
#include "qapi/qmp/qdict.h"
#include "qapi/qapi-commands-virtio.h"
#include "qapi/qapi-commands-qom.h"
#include "qapi/qapi-visit-virtio.h"
#include "qapi/qmp/qjson.h"
#include "trace.h"
#include "qemu/error-report.h"
@ -33,6 +32,8 @@
#include "hw/virtio/virtio-access.h"
#include "sysemu/dma.h"
#include "sysemu/runstate.h"
#include "virtio-qmp.h"
#include "standard-headers/linux/virtio_ids.h"
#include "standard-headers/linux/vhost_types.h"
#include "standard-headers/linux/virtio_blk.h"
@ -45,7 +46,6 @@
#include "standard-headers/linux/virtio_iommu.h"
#include "standard-headers/linux/virtio_mem.h"
#include "standard-headers/linux/virtio_vsock.h"
#include CONFIG_DEVICES
/* QAPI list of realized VirtIODevices */
static QTAILQ_HEAD(, VirtIODevice) virtio_list;
@ -55,440 +55,6 @@ static QTAILQ_HEAD(, VirtIODevice) virtio_list;
*/
#define VHOST_USER_MAX_CONFIG_SIZE 256
#define FEATURE_ENTRY(name, desc) (qmp_virtio_feature_map_t) \
{ .virtio_bit = name, .feature_desc = desc }
enum VhostUserProtocolFeature {
VHOST_USER_PROTOCOL_F_MQ = 0,
VHOST_USER_PROTOCOL_F_LOG_SHMFD = 1,
VHOST_USER_PROTOCOL_F_RARP = 2,
VHOST_USER_PROTOCOL_F_REPLY_ACK = 3,
VHOST_USER_PROTOCOL_F_NET_MTU = 4,
VHOST_USER_PROTOCOL_F_SLAVE_REQ = 5,
VHOST_USER_PROTOCOL_F_CROSS_ENDIAN = 6,
VHOST_USER_PROTOCOL_F_CRYPTO_SESSION = 7,
VHOST_USER_PROTOCOL_F_PAGEFAULT = 8,
VHOST_USER_PROTOCOL_F_CONFIG = 9,
VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD = 10,
VHOST_USER_PROTOCOL_F_HOST_NOTIFIER = 11,
VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD = 12,
VHOST_USER_PROTOCOL_F_RESET_DEVICE = 13,
VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS = 14,
VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS = 15,
VHOST_USER_PROTOCOL_F_MAX
};
/* Virtio transport features mapping */
static const qmp_virtio_feature_map_t virtio_transport_map[] = {
/* Virtio device transport features */
#ifndef VIRTIO_CONFIG_NO_LEGACY
FEATURE_ENTRY(VIRTIO_F_NOTIFY_ON_EMPTY, \
"VIRTIO_F_NOTIFY_ON_EMPTY: Notify when device runs out of avail. "
"descs. on VQ"),
FEATURE_ENTRY(VIRTIO_F_ANY_LAYOUT, \
"VIRTIO_F_ANY_LAYOUT: Device accepts arbitrary desc. layouts"),
#endif /* !VIRTIO_CONFIG_NO_LEGACY */
FEATURE_ENTRY(VIRTIO_F_VERSION_1, \
"VIRTIO_F_VERSION_1: Device compliant for v1 spec (legacy)"),
FEATURE_ENTRY(VIRTIO_F_IOMMU_PLATFORM, \
"VIRTIO_F_IOMMU_PLATFORM: Device can be used on IOMMU platform"),
FEATURE_ENTRY(VIRTIO_F_RING_PACKED, \
"VIRTIO_F_RING_PACKED: Device supports packed VQ layout"),
FEATURE_ENTRY(VIRTIO_F_IN_ORDER, \
"VIRTIO_F_IN_ORDER: Device uses buffers in same order as made "
"available by driver"),
FEATURE_ENTRY(VIRTIO_F_ORDER_PLATFORM, \
"VIRTIO_F_ORDER_PLATFORM: Memory accesses ordered by platform"),
FEATURE_ENTRY(VIRTIO_F_SR_IOV, \
"VIRTIO_F_SR_IOV: Device supports single root I/O virtualization"),
/* Virtio ring transport features */
FEATURE_ENTRY(VIRTIO_RING_F_INDIRECT_DESC, \
"VIRTIO_RING_F_INDIRECT_DESC: Indirect descriptors supported"),
FEATURE_ENTRY(VIRTIO_RING_F_EVENT_IDX, \
"VIRTIO_RING_F_EVENT_IDX: Used & avail. event fields enabled"),
{ -1, "" }
};
/* Vhost-user protocol features mapping */
static const qmp_virtio_feature_map_t vhost_user_protocol_map[] = {
FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_MQ, \
"VHOST_USER_PROTOCOL_F_MQ: Multiqueue protocol supported"),
FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_LOG_SHMFD, \
"VHOST_USER_PROTOCOL_F_LOG_SHMFD: Shared log memory fd supported"),
FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_RARP, \
"VHOST_USER_PROTOCOL_F_RARP: Vhost-user back-end RARP broadcasting "
"supported"),
FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_REPLY_ACK, \
"VHOST_USER_PROTOCOL_F_REPLY_ACK: Requested operation status ack. "
"supported"),
FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_NET_MTU, \
"VHOST_USER_PROTOCOL_F_NET_MTU: Expose host MTU to guest supported"),
FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_SLAVE_REQ, \
"VHOST_USER_PROTOCOL_F_SLAVE_REQ: Socket fd for back-end initiated "
"requests supported"),
FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_CROSS_ENDIAN, \
"VHOST_USER_PROTOCOL_F_CROSS_ENDIAN: Endianness of VQs for legacy "
"devices supported"),
FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_CRYPTO_SESSION, \
"VHOST_USER_PROTOCOL_F_CRYPTO_SESSION: Session creation for crypto "
"operations supported"),
FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_PAGEFAULT, \
"VHOST_USER_PROTOCOL_F_PAGEFAULT: Request servicing on userfaultfd "
"for accessed pages supported"),
FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_CONFIG, \
"VHOST_USER_PROTOCOL_F_CONFIG: Vhost-user messaging for virtio "
"device configuration space supported"),
FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD, \
"VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD: Slave fd communication "
"channel supported"),
FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_HOST_NOTIFIER, \
"VHOST_USER_PROTOCOL_F_HOST_NOTIFIER: Host notifiers for specified "
"VQs supported"),
FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD, \
"VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD: Shared inflight I/O buffers "
"supported"),
FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_RESET_DEVICE, \
"VHOST_USER_PROTOCOL_F_RESET_DEVICE: Disabling all rings and "
"resetting internal device state supported"),
FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS, \
"VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS: In-band messaging "
"supported"),
FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS, \
"VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS: Configuration for "
"memory slots supported"),
{ -1, "" }
};
/* virtio device configuration statuses */
static const qmp_virtio_feature_map_t virtio_config_status_map[] = {
FEATURE_ENTRY(VIRTIO_CONFIG_S_DRIVER_OK, \
"VIRTIO_CONFIG_S_DRIVER_OK: Driver setup and ready"),
FEATURE_ENTRY(VIRTIO_CONFIG_S_FEATURES_OK, \
"VIRTIO_CONFIG_S_FEATURES_OK: Feature negotiation complete"),
FEATURE_ENTRY(VIRTIO_CONFIG_S_DRIVER, \
"VIRTIO_CONFIG_S_DRIVER: Guest OS compatible with device"),
FEATURE_ENTRY(VIRTIO_CONFIG_S_NEEDS_RESET, \
"VIRTIO_CONFIG_S_NEEDS_RESET: Irrecoverable error, device needs "
"reset"),
FEATURE_ENTRY(VIRTIO_CONFIG_S_FAILED, \
"VIRTIO_CONFIG_S_FAILED: Error in guest, device failed"),
FEATURE_ENTRY(VIRTIO_CONFIG_S_ACKNOWLEDGE, \
"VIRTIO_CONFIG_S_ACKNOWLEDGE: Valid virtio device found"),
{ -1, "" }
};
/* virtio-blk features mapping */
#ifdef CONFIG_VIRTIO_BLK
static const qmp_virtio_feature_map_t virtio_blk_feature_map[] = {
FEATURE_ENTRY(VIRTIO_BLK_F_SIZE_MAX, \
"VIRTIO_BLK_F_SIZE_MAX: Max segment size is size_max"),
FEATURE_ENTRY(VIRTIO_BLK_F_SEG_MAX, \
"VIRTIO_BLK_F_SEG_MAX: Max segments in a request is seg_max"),
FEATURE_ENTRY(VIRTIO_BLK_F_GEOMETRY, \
"VIRTIO_BLK_F_GEOMETRY: Legacy geometry available"),
FEATURE_ENTRY(VIRTIO_BLK_F_RO, \
"VIRTIO_BLK_F_RO: Device is read-only"),
FEATURE_ENTRY(VIRTIO_BLK_F_BLK_SIZE, \
"VIRTIO_BLK_F_BLK_SIZE: Block size of disk available"),
FEATURE_ENTRY(VIRTIO_BLK_F_TOPOLOGY, \
"VIRTIO_BLK_F_TOPOLOGY: Topology information available"),
FEATURE_ENTRY(VIRTIO_BLK_F_MQ, \
"VIRTIO_BLK_F_MQ: Multiqueue supported"),
FEATURE_ENTRY(VIRTIO_BLK_F_DISCARD, \
"VIRTIO_BLK_F_DISCARD: Discard command supported"),
FEATURE_ENTRY(VIRTIO_BLK_F_WRITE_ZEROES, \
"VIRTIO_BLK_F_WRITE_ZEROES: Write zeroes command supported"),
#ifndef VIRTIO_BLK_NO_LEGACY
FEATURE_ENTRY(VIRTIO_BLK_F_BARRIER, \
"VIRTIO_BLK_F_BARRIER: Request barriers supported"),
FEATURE_ENTRY(VIRTIO_BLK_F_SCSI, \
"VIRTIO_BLK_F_SCSI: SCSI packet commands supported"),
FEATURE_ENTRY(VIRTIO_BLK_F_FLUSH, \
"VIRTIO_BLK_F_FLUSH: Flush command supported"),
FEATURE_ENTRY(VIRTIO_BLK_F_CONFIG_WCE, \
"VIRTIO_BLK_F_CONFIG_WCE: Cache writeback and writethrough modes "
"supported"),
#endif /* !VIRTIO_BLK_NO_LEGACY */
FEATURE_ENTRY(VHOST_F_LOG_ALL, \
"VHOST_F_LOG_ALL: Logging write descriptors supported"),
FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
"VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
"negotiation supported"),
{ -1, "" }
};
#endif
/* virtio-serial features mapping */
#ifdef CONFIG_VIRTIO_SERIAL
static const qmp_virtio_feature_map_t virtio_serial_feature_map[] = {
FEATURE_ENTRY(VIRTIO_CONSOLE_F_SIZE, \
"VIRTIO_CONSOLE_F_SIZE: Host providing console size"),
FEATURE_ENTRY(VIRTIO_CONSOLE_F_MULTIPORT, \
"VIRTIO_CONSOLE_F_MULTIPORT: Multiple ports for device supported"),
FEATURE_ENTRY(VIRTIO_CONSOLE_F_EMERG_WRITE, \
"VIRTIO_CONSOLE_F_EMERG_WRITE: Emergency write supported"),
{ -1, "" }
};
#endif
/* virtio-gpu features mapping */
#ifdef CONFIG_VIRTIO_GPU
static const qmp_virtio_feature_map_t virtio_gpu_feature_map[] = {
FEATURE_ENTRY(VIRTIO_GPU_F_VIRGL, \
"VIRTIO_GPU_F_VIRGL: Virgl 3D mode supported"),
FEATURE_ENTRY(VIRTIO_GPU_F_EDID, \
"VIRTIO_GPU_F_EDID: EDID metadata supported"),
FEATURE_ENTRY(VIRTIO_GPU_F_RESOURCE_UUID, \
"VIRTIO_GPU_F_RESOURCE_UUID: Resource UUID assigning supported"),
FEATURE_ENTRY(VIRTIO_GPU_F_RESOURCE_BLOB, \
"VIRTIO_GPU_F_RESOURCE_BLOB: Size-based blob resources supported"),
FEATURE_ENTRY(VIRTIO_GPU_F_CONTEXT_INIT, \
"VIRTIO_GPU_F_CONTEXT_INIT: Context types and synchronization "
"timelines supported"),
FEATURE_ENTRY(VHOST_F_LOG_ALL, \
"VHOST_F_LOG_ALL: Logging write descriptors supported"),
FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
"VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
"negotiation supported"),
{ -1, "" }
};
#endif
/* virtio-input features mapping */
#ifdef CONFIG_VIRTIO_INPUT
static const qmp_virtio_feature_map_t virtio_input_feature_map[] = {
FEATURE_ENTRY(VHOST_F_LOG_ALL, \
"VHOST_F_LOG_ALL: Logging write descriptors supported"),
FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
"VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
"negotiation supported"),
{ -1, "" }
};
#endif
/* virtio-net features mapping */
#ifdef CONFIG_VIRTIO_NET
static const qmp_virtio_feature_map_t virtio_net_feature_map[] = {
FEATURE_ENTRY(VIRTIO_NET_F_CSUM, \
"VIRTIO_NET_F_CSUM: Device handling packets with partial checksum "
"supported"),
FEATURE_ENTRY(VIRTIO_NET_F_GUEST_CSUM, \
"VIRTIO_NET_F_GUEST_CSUM: Driver handling packets with partial "
"checksum supported"),
FEATURE_ENTRY(VIRTIO_NET_F_CTRL_GUEST_OFFLOADS, \
"VIRTIO_NET_F_CTRL_GUEST_OFFLOADS: Control channel offloading "
"reconfig. supported"),
FEATURE_ENTRY(VIRTIO_NET_F_MTU, \
"VIRTIO_NET_F_MTU: Device max MTU reporting supported"),
FEATURE_ENTRY(VIRTIO_NET_F_MAC, \
"VIRTIO_NET_F_MAC: Device has given MAC address"),
FEATURE_ENTRY(VIRTIO_NET_F_GUEST_TSO4, \
"VIRTIO_NET_F_GUEST_TSO4: Driver can receive TSOv4"),
FEATURE_ENTRY(VIRTIO_NET_F_GUEST_TSO6, \
"VIRTIO_NET_F_GUEST_TSO6: Driver can receive TSOv6"),
FEATURE_ENTRY(VIRTIO_NET_F_GUEST_ECN, \
"VIRTIO_NET_F_GUEST_ECN: Driver can receive TSO with ECN"),
FEATURE_ENTRY(VIRTIO_NET_F_GUEST_UFO, \
"VIRTIO_NET_F_GUEST_UFO: Driver can receive UFO"),
FEATURE_ENTRY(VIRTIO_NET_F_HOST_TSO4, \
"VIRTIO_NET_F_HOST_TSO4: Device can receive TSOv4"),
FEATURE_ENTRY(VIRTIO_NET_F_HOST_TSO6, \
"VIRTIO_NET_F_HOST_TSO6: Device can receive TSOv6"),
FEATURE_ENTRY(VIRTIO_NET_F_HOST_ECN, \
"VIRTIO_NET_F_HOST_ECN: Device can receive TSO with ECN"),
FEATURE_ENTRY(VIRTIO_NET_F_HOST_UFO, \
"VIRTIO_NET_F_HOST_UFO: Device can receive UFO"),
FEATURE_ENTRY(VIRTIO_NET_F_MRG_RXBUF, \
"VIRTIO_NET_F_MRG_RXBUF: Driver can merge receive buffers"),
FEATURE_ENTRY(VIRTIO_NET_F_STATUS, \
"VIRTIO_NET_F_STATUS: Configuration status field available"),
FEATURE_ENTRY(VIRTIO_NET_F_CTRL_VQ, \
"VIRTIO_NET_F_CTRL_VQ: Control channel available"),
FEATURE_ENTRY(VIRTIO_NET_F_CTRL_RX, \
"VIRTIO_NET_F_CTRL_RX: Control channel RX mode supported"),
FEATURE_ENTRY(VIRTIO_NET_F_CTRL_VLAN, \
"VIRTIO_NET_F_CTRL_VLAN: Control channel VLAN filtering supported"),
FEATURE_ENTRY(VIRTIO_NET_F_CTRL_RX_EXTRA, \
"VIRTIO_NET_F_CTRL_RX_EXTRA: Extra RX mode control supported"),
FEATURE_ENTRY(VIRTIO_NET_F_GUEST_ANNOUNCE, \
"VIRTIO_NET_F_GUEST_ANNOUNCE: Driver sending gratuitous packets "
"supported"),
FEATURE_ENTRY(VIRTIO_NET_F_MQ, \
"VIRTIO_NET_F_MQ: Multiqueue with automatic receive steering "
"supported"),
FEATURE_ENTRY(VIRTIO_NET_F_CTRL_MAC_ADDR, \
"VIRTIO_NET_F_CTRL_MAC_ADDR: MAC address set through control "
"channel"),
FEATURE_ENTRY(VIRTIO_NET_F_HASH_REPORT, \
"VIRTIO_NET_F_HASH_REPORT: Hash reporting supported"),
FEATURE_ENTRY(VIRTIO_NET_F_RSS, \
"VIRTIO_NET_F_RSS: RSS RX steering supported"),
FEATURE_ENTRY(VIRTIO_NET_F_RSC_EXT, \
"VIRTIO_NET_F_RSC_EXT: Extended coalescing info supported"),
FEATURE_ENTRY(VIRTIO_NET_F_STANDBY, \
"VIRTIO_NET_F_STANDBY: Device acting as standby for primary "
"device with same MAC addr. supported"),
FEATURE_ENTRY(VIRTIO_NET_F_SPEED_DUPLEX, \
"VIRTIO_NET_F_SPEED_DUPLEX: Device set linkspeed and duplex"),
#ifndef VIRTIO_NET_NO_LEGACY
FEATURE_ENTRY(VIRTIO_NET_F_GSO, \
"VIRTIO_NET_F_GSO: Handling GSO-type packets supported"),
#endif /* !VIRTIO_NET_NO_LEGACY */
FEATURE_ENTRY(VHOST_NET_F_VIRTIO_NET_HDR, \
"VHOST_NET_F_VIRTIO_NET_HDR: Virtio-net headers for RX and TX "
"packets supported"),
FEATURE_ENTRY(VHOST_F_LOG_ALL, \
"VHOST_F_LOG_ALL: Logging write descriptors supported"),
FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
"VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
"negotiation supported"),
{ -1, "" }
};
#endif
/* virtio-scsi features mapping */
#ifdef CONFIG_VIRTIO_SCSI
static const qmp_virtio_feature_map_t virtio_scsi_feature_map[] = {
FEATURE_ENTRY(VIRTIO_SCSI_F_INOUT, \
"VIRTIO_SCSI_F_INOUT: Requests including read and writable data "
"buffers suppoted"),
FEATURE_ENTRY(VIRTIO_SCSI_F_HOTPLUG, \
"VIRTIO_SCSI_F_HOTPLUG: Reporting and handling hot-plug events "
"supported"),
FEATURE_ENTRY(VIRTIO_SCSI_F_CHANGE, \
"VIRTIO_SCSI_F_CHANGE: Reporting and handling LUN changes "
"supported"),
FEATURE_ENTRY(VIRTIO_SCSI_F_T10_PI, \
"VIRTIO_SCSI_F_T10_PI: T10 info included in request header"),
FEATURE_ENTRY(VHOST_F_LOG_ALL, \
"VHOST_F_LOG_ALL: Logging write descriptors supported"),
FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
"VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
"negotiation supported"),
{ -1, "" }
};
#endif
/* virtio/vhost-user-fs features mapping */
#ifdef CONFIG_VHOST_USER_FS
static const qmp_virtio_feature_map_t virtio_fs_feature_map[] = {
FEATURE_ENTRY(VHOST_F_LOG_ALL, \
"VHOST_F_LOG_ALL: Logging write descriptors supported"),
FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
"VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
"negotiation supported"),
{ -1, "" }
};
#endif
/* virtio/vhost-user-i2c features mapping */
#ifdef CONFIG_VIRTIO_I2C_ADAPTER
static const qmp_virtio_feature_map_t virtio_i2c_feature_map[] = {
FEATURE_ENTRY(VIRTIO_I2C_F_ZERO_LENGTH_REQUEST, \
"VIRTIO_I2C_F_ZERO_LEGNTH_REQUEST: Zero length requests supported"),
FEATURE_ENTRY(VHOST_F_LOG_ALL, \
"VHOST_F_LOG_ALL: Logging write descriptors supported"),
FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
"VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
"negotiation supported"),
{ -1, "" }
};
#endif
/* virtio/vhost-vsock features mapping */
#ifdef CONFIG_VHOST_VSOCK
static const qmp_virtio_feature_map_t virtio_vsock_feature_map[] = {
FEATURE_ENTRY(VIRTIO_VSOCK_F_SEQPACKET, \
"VIRTIO_VSOCK_F_SEQPACKET: SOCK_SEQPACKET supported"),
FEATURE_ENTRY(VHOST_F_LOG_ALL, \
"VHOST_F_LOG_ALL: Logging write descriptors supported"),
FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
"VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
"negotiation supported"),
{ -1, "" }
};
#endif
/* virtio-balloon features mapping */
#ifdef CONFIG_VIRTIO_BALLOON
static const qmp_virtio_feature_map_t virtio_balloon_feature_map[] = {
FEATURE_ENTRY(VIRTIO_BALLOON_F_MUST_TELL_HOST, \
"VIRTIO_BALLOON_F_MUST_TELL_HOST: Tell host before reclaiming "
"pages"),
FEATURE_ENTRY(VIRTIO_BALLOON_F_STATS_VQ, \
"VIRTIO_BALLOON_F_STATS_VQ: Guest memory stats VQ available"),
FEATURE_ENTRY(VIRTIO_BALLOON_F_DEFLATE_ON_OOM, \
"VIRTIO_BALLOON_F_DEFLATE_ON_OOM: Deflate balloon when guest OOM"),
FEATURE_ENTRY(VIRTIO_BALLOON_F_FREE_PAGE_HINT, \
"VIRTIO_BALLOON_F_FREE_PAGE_HINT: VQ reporting free pages enabled"),
FEATURE_ENTRY(VIRTIO_BALLOON_F_PAGE_POISON, \
"VIRTIO_BALLOON_F_PAGE_POISON: Guest page poisoning enabled"),
FEATURE_ENTRY(VIRTIO_BALLOON_F_REPORTING, \
"VIRTIO_BALLOON_F_REPORTING: Page reporting VQ enabled"),
{ -1, "" }
};
#endif
/* virtio-crypto features mapping */
#ifdef CONFIG_VIRTIO_CRYPTO
static const qmp_virtio_feature_map_t virtio_crypto_feature_map[] = {
FEATURE_ENTRY(VHOST_F_LOG_ALL, \
"VHOST_F_LOG_ALL: Logging write descriptors supported"),
{ -1, "" }
};
#endif
/* virtio-iommu features mapping */
#ifdef CONFIG_VIRTIO_IOMMU
static const qmp_virtio_feature_map_t virtio_iommu_feature_map[] = {
FEATURE_ENTRY(VIRTIO_IOMMU_F_INPUT_RANGE, \
"VIRTIO_IOMMU_F_INPUT_RANGE: Range of available virtual addrs. "
"available"),
FEATURE_ENTRY(VIRTIO_IOMMU_F_DOMAIN_RANGE, \
"VIRTIO_IOMMU_F_DOMAIN_RANGE: Number of supported domains "
"available"),
FEATURE_ENTRY(VIRTIO_IOMMU_F_MAP_UNMAP, \
"VIRTIO_IOMMU_F_MAP_UNMAP: Map and unmap requests available"),
FEATURE_ENTRY(VIRTIO_IOMMU_F_BYPASS, \
"VIRTIO_IOMMU_F_BYPASS: Endpoints not attached to domains are in "
"bypass mode"),
FEATURE_ENTRY(VIRTIO_IOMMU_F_PROBE, \
"VIRTIO_IOMMU_F_PROBE: Probe requests available"),
FEATURE_ENTRY(VIRTIO_IOMMU_F_MMIO, \
"VIRTIO_IOMMU_F_MMIO: VIRTIO_IOMMU_MAP_F_MMIO flag available"),
FEATURE_ENTRY(VIRTIO_IOMMU_F_BYPASS_CONFIG, \
"VIRTIO_IOMMU_F_BYPASS_CONFIG: Bypass field of IOMMU config "
"available"),
{ -1, "" }
};
#endif
/* virtio-mem features mapping */
#ifdef CONFIG_VIRTIO_MEM
static const qmp_virtio_feature_map_t virtio_mem_feature_map[] = {
#ifndef CONFIG_ACPI
FEATURE_ENTRY(VIRTIO_MEM_F_ACPI_PXM, \
"VIRTIO_MEM_F_ACPI_PXM: node_id is an ACPI PXM and is valid"),
#endif /* !CONFIG_ACPI */
FEATURE_ENTRY(VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE, \
"VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE: Unplugged memory cannot be "
"accessed"),
{ -1, "" }
};
#endif
/* virtio-rng features mapping */
#ifdef CONFIG_VIRTIO_RNG
static const qmp_virtio_feature_map_t virtio_rng_feature_map[] = {
FEATURE_ENTRY(VHOST_F_LOG_ALL, \
"VHOST_F_LOG_ALL: Logging write descriptors supported"),
FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
"VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features "
"negotiation supported"),
{ -1, "" }
};
#endif
/*
* The alignment to use between consumer and producer parts of vring.
* x86 pagesize again. This is the default, used by transports like PCI
@ -4296,203 +3862,6 @@ static VirtIODevice *virtio_device_find(const char *path)
return NULL;
}
#define CONVERT_FEATURES(type, map, is_status, bitmap) \
({ \
type *list = NULL; \
type *node; \
for (i = 0; map[i].virtio_bit != -1; i++) { \
if (is_status) { \
bit = map[i].virtio_bit; \
} \
else { \
bit = 1ULL << map[i].virtio_bit; \
} \
if ((bitmap & bit) == 0) { \
continue; \
} \
node = g_new0(type, 1); \
node->value = g_strdup(map[i].feature_desc); \
node->next = list; \
list = node; \
bitmap ^= bit; \
} \
list; \
})
static VirtioDeviceStatus *qmp_decode_status(uint8_t bitmap)
{
VirtioDeviceStatus *status;
uint8_t bit;
int i;
status = g_new0(VirtioDeviceStatus, 1);
status->statuses = CONVERT_FEATURES(strList, virtio_config_status_map,
1, bitmap);
status->has_unknown_statuses = bitmap != 0;
if (status->has_unknown_statuses) {
status->unknown_statuses = bitmap;
}
return status;
}
static VhostDeviceProtocols *qmp_decode_protocols(uint64_t bitmap)
{
VhostDeviceProtocols *vhu_protocols;
uint64_t bit;
int i;
vhu_protocols = g_new0(VhostDeviceProtocols, 1);
vhu_protocols->protocols =
CONVERT_FEATURES(strList,
vhost_user_protocol_map, 0, bitmap);
vhu_protocols->has_unknown_protocols = bitmap != 0;
if (vhu_protocols->has_unknown_protocols) {
vhu_protocols->unknown_protocols = bitmap;
}
return vhu_protocols;
}
static VirtioDeviceFeatures *qmp_decode_features(uint16_t device_id,
uint64_t bitmap)
{
VirtioDeviceFeatures *features;
uint64_t bit;
int i;
features = g_new0(VirtioDeviceFeatures, 1);
features->has_dev_features = true;
/* transport features */
features->transports = CONVERT_FEATURES(strList, virtio_transport_map, 0,
bitmap);
/* device features */
switch (device_id) {
#ifdef CONFIG_VIRTIO_SERIAL
case VIRTIO_ID_CONSOLE:
features->dev_features =
CONVERT_FEATURES(strList, virtio_serial_feature_map, 0, bitmap);
break;
#endif
#ifdef CONFIG_VIRTIO_BLK
case VIRTIO_ID_BLOCK:
features->dev_features =
CONVERT_FEATURES(strList, virtio_blk_feature_map, 0, bitmap);
break;
#endif
#ifdef CONFIG_VIRTIO_GPU
case VIRTIO_ID_GPU:
features->dev_features =
CONVERT_FEATURES(strList, virtio_gpu_feature_map, 0, bitmap);
break;
#endif
#ifdef CONFIG_VIRTIO_NET
case VIRTIO_ID_NET:
features->dev_features =
CONVERT_FEATURES(strList, virtio_net_feature_map, 0, bitmap);
break;
#endif
#ifdef CONFIG_VIRTIO_SCSI
case VIRTIO_ID_SCSI:
features->dev_features =
CONVERT_FEATURES(strList, virtio_scsi_feature_map, 0, bitmap);
break;
#endif
#ifdef CONFIG_VIRTIO_BALLOON
case VIRTIO_ID_BALLOON:
features->dev_features =
CONVERT_FEATURES(strList, virtio_balloon_feature_map, 0, bitmap);
break;
#endif
#ifdef CONFIG_VIRTIO_IOMMU
case VIRTIO_ID_IOMMU:
features->dev_features =
CONVERT_FEATURES(strList, virtio_iommu_feature_map, 0, bitmap);
break;
#endif
#ifdef CONFIG_VIRTIO_INPUT
case VIRTIO_ID_INPUT:
features->dev_features =
CONVERT_FEATURES(strList, virtio_input_feature_map, 0, bitmap);
break;
#endif
#ifdef CONFIG_VHOST_USER_FS
case VIRTIO_ID_FS:
features->dev_features =
CONVERT_FEATURES(strList, virtio_fs_feature_map, 0, bitmap);
break;
#endif
#ifdef CONFIG_VHOST_VSOCK
case VIRTIO_ID_VSOCK:
features->dev_features =
CONVERT_FEATURES(strList, virtio_vsock_feature_map, 0, bitmap);
break;
#endif
#ifdef CONFIG_VIRTIO_CRYPTO
case VIRTIO_ID_CRYPTO:
features->dev_features =
CONVERT_FEATURES(strList, virtio_crypto_feature_map, 0, bitmap);
break;
#endif
#ifdef CONFIG_VIRTIO_MEM
case VIRTIO_ID_MEM:
features->dev_features =
CONVERT_FEATURES(strList, virtio_mem_feature_map, 0, bitmap);
break;
#endif
#ifdef CONFIG_VIRTIO_I2C_ADAPTER
case VIRTIO_ID_I2C_ADAPTER:
features->dev_features =
CONVERT_FEATURES(strList, virtio_i2c_feature_map, 0, bitmap);
break;
#endif
#ifdef CONFIG_VIRTIO_RNG
case VIRTIO_ID_RNG:
features->dev_features =
CONVERT_FEATURES(strList, virtio_rng_feature_map, 0, bitmap);
break;
#endif
/* No features */
case VIRTIO_ID_9P:
case VIRTIO_ID_PMEM:
case VIRTIO_ID_IOMEM:
case VIRTIO_ID_RPMSG:
case VIRTIO_ID_CLOCK:
case VIRTIO_ID_MAC80211_WLAN:
case VIRTIO_ID_MAC80211_HWSIM:
case VIRTIO_ID_RPROC_SERIAL:
case VIRTIO_ID_MEMORY_BALLOON:
case VIRTIO_ID_CAIF:
case VIRTIO_ID_SIGNAL_DIST:
case VIRTIO_ID_PSTORE:
case VIRTIO_ID_SOUND:
case VIRTIO_ID_BT:
case VIRTIO_ID_RPMB:
case VIRTIO_ID_VIDEO_ENCODER:
case VIRTIO_ID_VIDEO_DECODER:
case VIRTIO_ID_SCMI:
case VIRTIO_ID_NITRO_SEC_MOD:
case VIRTIO_ID_WATCHDOG:
case VIRTIO_ID_CAN:
case VIRTIO_ID_DMABUF:
case VIRTIO_ID_PARAM_SERV:
case VIRTIO_ID_AUDIO_POLICY:
case VIRTIO_ID_GPIO:
break;
default:
g_assert_not_reached();
}
features->has_unknown_dev_features = bitmap != 0;
if (features->has_unknown_dev_features) {
features->unknown_dev_features = bitmap;
}
return features;
}
VirtioStatus *qmp_x_query_virtio_status(const char *path, Error **errp)
{
VirtIODevice *vdev;