aboutsummaryrefslogtreecommitdiff
path: root/include/hw/virtio
diff options
context:
space:
mode:
Diffstat (limited to 'include/hw/virtio')
-rw-r--r--include/hw/virtio/vhost-backend.h8
-rw-r--r--include/hw/virtio/vhost-scsi-common.h2
-rw-r--r--include/hw/virtio/vhost-user-base.h2
-rw-r--r--include/hw/virtio/vhost-user-blk.h2
-rw-r--r--include/hw/virtio/vhost-vdpa.h22
-rw-r--r--include/hw/virtio/vhost-vsock-common.h2
-rw-r--r--include/hw/virtio/vhost.h86
-rw-r--r--include/hw/virtio/virtio-features.h126
-rw-r--r--include/hw/virtio/virtio-gpu.h3
-rw-r--r--include/hw/virtio/virtio-mem.h2
-rw-r--r--include/hw/virtio/virtio-net.h8
-rw-r--r--include/hw/virtio/virtio-pci.h15
-rw-r--r--include/hw/virtio/virtio-pmem.h2
-rw-r--r--include/hw/virtio/virtio.h26
14 files changed, 267 insertions, 39 deletions
diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
index 70c2e8f..ff94fa1 100644
--- a/include/hw/virtio/vhost-backend.h
+++ b/include/hw/virtio/vhost-backend.h
@@ -11,7 +11,7 @@
#ifndef VHOST_BACKEND_H
#define VHOST_BACKEND_H
-#include "exec/memory.h"
+#include "system/memory.h"
typedef enum VhostBackendType {
VHOST_BACKEND_TYPE_NONE = 0,
@@ -95,6 +95,10 @@ typedef int (*vhost_new_worker_op)(struct vhost_dev *dev,
struct vhost_worker_state *worker);
typedef int (*vhost_free_worker_op)(struct vhost_dev *dev,
struct vhost_worker_state *worker);
+typedef int (*vhost_set_features_ex_op)(struct vhost_dev *dev,
+ const uint64_t *features);
+typedef int (*vhost_get_features_ex_op)(struct vhost_dev *dev,
+ uint64_t *features);
typedef int (*vhost_set_features_op)(struct vhost_dev *dev,
uint64_t features);
typedef int (*vhost_get_features_op)(struct vhost_dev *dev,
@@ -186,6 +190,8 @@ typedef struct VhostOps {
vhost_free_worker_op vhost_free_worker;
vhost_get_vring_worker_op vhost_get_vring_worker;
vhost_attach_vring_worker_op vhost_attach_vring_worker;
+ vhost_set_features_ex_op vhost_set_features_ex;
+ vhost_get_features_ex_op vhost_get_features_ex;
vhost_set_features_op vhost_set_features;
vhost_get_features_op vhost_get_features;
vhost_set_backend_cap_op vhost_set_backend_cap;
diff --git a/include/hw/virtio/vhost-scsi-common.h b/include/hw/virtio/vhost-scsi-common.h
index c5d2c09..d54d9c9 100644
--- a/include/hw/virtio/vhost-scsi-common.h
+++ b/include/hw/virtio/vhost-scsi-common.h
@@ -40,7 +40,7 @@ struct VHostSCSICommon {
};
int vhost_scsi_common_start(VHostSCSICommon *vsc, Error **errp);
-void vhost_scsi_common_stop(VHostSCSICommon *vsc);
+int vhost_scsi_common_stop(VHostSCSICommon *vsc);
char *vhost_scsi_common_get_fw_dev_path(FWPathProvider *p, BusState *bus,
DeviceState *dev);
void vhost_scsi_common_set_config(VirtIODevice *vdev, const uint8_t *config);
diff --git a/include/hw/virtio/vhost-user-base.h b/include/hw/virtio/vhost-user-base.h
index 51d0968..387e434 100644
--- a/include/hw/virtio/vhost-user-base.h
+++ b/include/hw/virtio/vhost-user-base.h
@@ -44,6 +44,6 @@ struct VHostUserBaseClass {
};
-#define TYPE_VHOST_USER_DEVICE "vhost-user-device"
+#define TYPE_VHOST_USER_TEST_DEVICE "vhost-user-test-device"
#endif /* QEMU_VHOST_USER_BASE_H */
diff --git a/include/hw/virtio/vhost-user-blk.h b/include/hw/virtio/vhost-user-blk.h
index ea085ee..a10f785 100644
--- a/include/hw/virtio/vhost-user-blk.h
+++ b/include/hw/virtio/vhost-user-blk.h
@@ -50,6 +50,8 @@ struct VHostUserBlk {
bool connected;
/* vhost_user_blk_start/vhost_user_blk_stop */
bool started_vu;
+
+ bool skip_get_vring_base_on_force_shutdown;
};
#endif
diff --git a/include/hw/virtio/vhost-vdpa.h b/include/hw/virtio/vhost-vdpa.h
index 0a9575b..449bf5c 100644
--- a/include/hw/virtio/vhost-vdpa.h
+++ b/include/hw/virtio/vhost-vdpa.h
@@ -43,7 +43,21 @@ typedef struct vhost_vdpa_shared {
struct vhost_vdpa_iova_range iova_range;
QLIST_HEAD(, vdpa_iommu) iommu_list;
- /* IOVA mapping used by the Shadow Virtqueue */
+ /*
+ * IOVA mapping used by the Shadow Virtqueue
+ *
+ * It is shared among all ASID for simplicity, whether CVQ shares ASID with
+ * guest or not:
+ * - Memory listener need access to guest's memory addresses allocated in
+ * the IOVA tree.
+ * - There should be plenty of IOVA address space for both ASID not to
+ * worry about collisions between them. Guest's translations are still
+ * validated with virtio virtqueue_pop so there is no risk for the guest
+ * to access memory that it shouldn't.
+ *
+ * To allocate a iova tree per ASID is doable but it complicates the code
+ * and it is not worth it for the moment.
+ */
VhostIOVATree *iova_tree;
/* Copy of backend features */
@@ -51,6 +65,12 @@ typedef struct vhost_vdpa_shared {
bool iotlb_batch_begin_sent;
+ /*
+ * The memory listener has been registered, so DMA maps have been sent to
+ * the device.
+ */
+ bool listener_registered;
+
/* Vdpa must send shadow addresses as IOTLB key for data queues, not GPA */
bool shadow_data;
diff --git a/include/hw/virtio/vhost-vsock-common.h b/include/hw/virtio/vhost-vsock-common.h
index 75a74e8..01bf606 100644
--- a/include/hw/virtio/vhost-vsock-common.h
+++ b/include/hw/virtio/vhost-vsock-common.h
@@ -42,7 +42,7 @@ struct VHostVSockCommon {
};
int vhost_vsock_common_start(VirtIODevice *vdev);
-void vhost_vsock_common_stop(VirtIODevice *vdev);
+int vhost_vsock_common_stop(VirtIODevice *vdev);
int vhost_vsock_common_pre_save(void *opaque);
int vhost_vsock_common_post_load(void *opaque, int version_id);
void vhost_vsock_common_realize(VirtIODevice *vdev);
diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
index a9469d5..08bbb4d 100644
--- a/include/hw/virtio/vhost.h
+++ b/include/hw/virtio/vhost.h
@@ -1,9 +1,10 @@
#ifndef VHOST_H
#define VHOST_H
+#include "net/vhost_net.h"
#include "hw/virtio/vhost-backend.h"
#include "hw/virtio/virtio.h"
-#include "exec/memory.h"
+#include "system/memory.h"
#define VHOST_F_DEVICE_IOTLB 63
#define VHOST_USER_F_PROTOCOL_FEATURES 30
@@ -106,9 +107,9 @@ struct vhost_dev {
* future use should be discouraged and the variable retired as
* its easy to confuse with the VirtIO backend_features.
*/
- uint64_t features;
- uint64_t acked_features;
- uint64_t backend_features;
+ VIRTIO_DECLARE_FEATURES(features);
+ VIRTIO_DECLARE_FEATURES(acked_features);
+ VIRTIO_DECLARE_FEATURES(backend_features);
/**
* @protocol_features: is the vhost-user only feature set by
@@ -143,6 +144,10 @@ struct vhost_net {
struct vhost_dev dev;
struct vhost_virtqueue vqs[2];
int backend;
+ const int *feature_bits;
+ int max_tx_queue_size;
+ SaveAcketFeatures *save_acked_features;
+ bool is_vhost_user;
NetClientState *nc;
};
@@ -232,8 +237,25 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings);
* Stop the vhost device. After the device is stopped the notifiers
* can be disabled (@vhost_dev_disable_notifiers) and the device can
* be torn down (@vhost_dev_cleanup).
+ *
+ * Return: 0 on success, != 0 on error when stopping dev.
+ */
+int vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings);
+
+/**
+ * vhost_dev_force_stop() - force stop the vhost device
+ * @hdev: common vhost_dev structure
+ * @vdev: the VirtIODevice structure
+ * @vrings: true to have vrings disabled in this call
+ *
+ * Force stop the vhost device. After the device is stopped the notifiers
+ * can be disabled (@vhost_dev_disable_notifiers) and the device can
+ * be torn down (@vhost_dev_cleanup). Unlike @vhost_dev_stop, this doesn't
+ * attempt to flush in-flight backend requests by skipping GET_VRING_BASE
+ * entirely.
*/
-void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings);
+int vhost_dev_force_stop(struct vhost_dev *hdev, VirtIODevice *vdev,
+ bool vrings);
/**
* DOC: vhost device configuration handling
@@ -299,6 +321,20 @@ void vhost_virtqueue_mask(struct vhost_dev *hdev, VirtIODevice *vdev, int n,
bool mask);
/**
+ * vhost_get_features_ex() - sanitize the extended features set
+ * @hdev: common vhost_dev structure
+ * @feature_bits: pointer to terminated table of feature bits
+ * @features: original features set, filtered out on return
+ *
+ * This is the extended variant of vhost_get_features(), supporting the
+ * the extended features set. Filter it with the intersection of what is
+ * supported by the vhost backend (hdev->features) and the supported
+ * feature_bits.
+ */
+void vhost_get_features_ex(struct vhost_dev *hdev,
+ const int *feature_bits,
+ uint64_t *features);
+/**
* vhost_get_features() - return a sanitised set of feature bits
* @hdev: common vhost_dev structure
* @feature_bits: pointer to terminated table of feature bits
@@ -308,8 +344,28 @@ void vhost_virtqueue_mask(struct vhost_dev *hdev, VirtIODevice *vdev, int n,
* is supported by the vhost backend (hdev->features), the supported
* feature_bits and the requested feature set.
*/
-uint64_t vhost_get_features(struct vhost_dev *hdev, const int *feature_bits,
- uint64_t features);
+static inline uint64_t vhost_get_features(struct vhost_dev *hdev,
+ const int *feature_bits,
+ uint64_t features)
+{
+ uint64_t features_ex[VIRTIO_FEATURES_NU64S];
+
+ virtio_features_from_u64(features_ex, features);
+ vhost_get_features_ex(hdev, feature_bits, features_ex);
+ return features_ex[0];
+}
+
+/**
+ * vhost_ack_features_ex() - set vhost full set of acked_features
+ * @hdev: common vhost_dev structure
+ * @feature_bits: pointer to terminated table of feature bits
+ * @features: requested feature set
+ *
+ * This sets the internal hdev->acked_features to the intersection of
+ * the backends advertised features and the supported feature_bits.
+ */
+void vhost_ack_features_ex(struct vhost_dev *hdev, const int *feature_bits,
+ const uint64_t *features);
/**
* vhost_ack_features() - set vhost acked_features
@@ -320,8 +376,16 @@ uint64_t vhost_get_features(struct vhost_dev *hdev, const int *feature_bits,
* This sets the internal hdev->acked_features to the intersection of
* the backends advertised features and the supported feature_bits.
*/
-void vhost_ack_features(struct vhost_dev *hdev, const int *feature_bits,
- uint64_t features);
+static inline void vhost_ack_features(struct vhost_dev *hdev,
+ const int *feature_bits,
+ uint64_t features)
+{
+ uint64_t features_ex[VIRTIO_FEATURES_NU64S];
+
+ virtio_features_from_u64(features_ex, features);
+ vhost_ack_features_ex(hdev, feature_bits, features_ex);
+}
+
unsigned int vhost_get_max_memslots(void);
unsigned int vhost_get_free_memslots(void);
@@ -333,8 +397,8 @@ int vhost_device_iotlb_miss(struct vhost_dev *dev, uint64_t iova, int write);
int vhost_virtqueue_start(struct vhost_dev *dev, struct VirtIODevice *vdev,
struct vhost_virtqueue *vq, unsigned idx);
-void vhost_virtqueue_stop(struct vhost_dev *dev, struct VirtIODevice *vdev,
- struct vhost_virtqueue *vq, unsigned idx);
+int vhost_virtqueue_stop(struct vhost_dev *dev, struct VirtIODevice *vdev,
+ struct vhost_virtqueue *vq, unsigned idx);
void vhost_dev_reset_inflight(struct vhost_inflight *inflight);
void vhost_dev_free_inflight(struct vhost_inflight *inflight);
diff --git a/include/hw/virtio/virtio-features.h b/include/hw/virtio/virtio-features.h
new file mode 100644
index 0000000..e29b7fe
--- /dev/null
+++ b/include/hw/virtio/virtio-features.h
@@ -0,0 +1,126 @@
+/*
+ * Virtio features helpers
+ *
+ * Copyright 2025 Red Hat, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef QEMU_VIRTIO_FEATURES_H
+#define QEMU_VIRTIO_FEATURES_H
+
+#include "qemu/bitops.h"
+
+#define VIRTIO_FEATURES_FMT "%016"PRIx64"%016"PRIx64
+#define VIRTIO_FEATURES_PR(f) (f)[1], (f)[0]
+
+#define VIRTIO_FEATURES_MAX 128
+#define VIRTIO_FEATURES_BIT(b) BIT_ULL((b) % 64)
+#define VIRTIO_FEATURES_U64(b) ((b) / 64)
+#define VIRTIO_FEATURES_NU32S (VIRTIO_FEATURES_MAX / 32)
+#define VIRTIO_FEATURES_NU64S (VIRTIO_FEATURES_MAX / 64)
+
+#define VIRTIO_DECLARE_FEATURES(name) \
+ union { \
+ uint64_t name; \
+ uint64_t name##_ex[VIRTIO_FEATURES_NU64S]; \
+ }
+
+#define VIRTIO_DEFINE_PROP_FEATURE(_name, _state, _field, _bit, _defval) \
+ DEFINE_PROP_BIT64(_name, _state, _field[VIRTIO_FEATURES_U64(_bit)], \
+ (_bit) % 64, _defval)
+
+static inline void virtio_features_clear(uint64_t *features)
+{
+ memset(features, 0, sizeof(features[0]) * VIRTIO_FEATURES_NU64S);
+}
+
+static inline void virtio_features_from_u64(uint64_t *features, uint64_t from)
+{
+ virtio_features_clear(features);
+ features[0] = from;
+}
+
+static inline bool virtio_has_feature_ex(const uint64_t *features,
+ unsigned int fbit)
+{
+ assert(fbit < VIRTIO_FEATURES_MAX);
+ return features[VIRTIO_FEATURES_U64(fbit)] & VIRTIO_FEATURES_BIT(fbit);
+}
+
+static inline void virtio_add_feature_ex(uint64_t *features,
+ unsigned int fbit)
+{
+ assert(fbit < VIRTIO_FEATURES_MAX);
+ features[VIRTIO_FEATURES_U64(fbit)] |= VIRTIO_FEATURES_BIT(fbit);
+}
+
+static inline void virtio_clear_feature_ex(uint64_t *features,
+ unsigned int fbit)
+{
+ assert(fbit < VIRTIO_FEATURES_MAX);
+ features[VIRTIO_FEATURES_U64(fbit)] &= ~VIRTIO_FEATURES_BIT(fbit);
+}
+
+static inline bool virtio_features_equal(const uint64_t *f1,
+ const uint64_t *f2)
+{
+ return !memcmp(f1, f2, sizeof(uint64_t) * VIRTIO_FEATURES_NU64S);
+}
+
+static inline bool virtio_features_use_ex(const uint64_t *features)
+{
+ int i;
+
+ for (i = 1; i < VIRTIO_FEATURES_NU64S; ++i) {
+ if (features[i]) {
+ return true;
+ }
+ }
+ return false;
+}
+
+static inline bool virtio_features_empty(const uint64_t *features)
+{
+ return !virtio_features_use_ex(features) && !features[0];
+}
+
+static inline void virtio_features_copy(uint64_t *to, const uint64_t *from)
+{
+ memcpy(to, from, sizeof(to[0]) * VIRTIO_FEATURES_NU64S);
+}
+
+static inline bool virtio_features_andnot(uint64_t *to, const uint64_t *f1,
+ const uint64_t *f2)
+{
+ uint64_t diff = 0;
+ int i;
+
+ for (i = 0; i < VIRTIO_FEATURES_NU64S; i++) {
+ to[i] = f1[i] & ~f2[i];
+ diff |= to[i];
+ }
+ return diff;
+}
+
+static inline void virtio_features_and(uint64_t *to, const uint64_t *f1,
+ const uint64_t *f2)
+{
+ int i;
+
+ for (i = 0; i < VIRTIO_FEATURES_NU64S; i++) {
+ to[i] = f1[i] & f2[i];
+ }
+}
+
+static inline void virtio_features_or(uint64_t *to, const uint64_t *f1,
+ const uint64_t *f2)
+{
+ int i;
+
+ for (i = 0; i < VIRTIO_FEATURES_NU64S; i++) {
+ to[i] = f1[i] | f2[i];
+ }
+}
+
+#endif
diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index a42957c..9f16f89 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -20,6 +20,7 @@
#include "hw/virtio/virtio.h"
#include "qemu/log.h"
#include "system/vhost-user-backend.h"
+#include "qapi/qapi-types-virtio.h"
#include "standard-headers/linux/virtio_gpu.h"
#include "standard-headers/linux/virtio_ids.h"
@@ -128,6 +129,7 @@ struct virtio_gpu_base_conf {
uint32_t xres;
uint32_t yres;
uint64_t hostmem;
+ VirtIOGPUOutputList *outputs;
};
struct virtio_gpu_ctrl_command {
@@ -167,6 +169,7 @@ struct VirtIOGPUBaseClass {
#define VIRTIO_GPU_BASE_PROPERTIES(_state, _conf) \
DEFINE_PROP_UINT32("max_outputs", _state, _conf.max_outputs, 1), \
+ DEFINE_PROP_VIRTIO_GPU_OUTPUT_LIST("outputs", _state, _conf.outputs), \
DEFINE_PROP_BIT("edid", _state, _conf.flags, \
VIRTIO_GPU_FLAG_EDID_ENABLED, true), \
DEFINE_PROP_UINT32("xres", _state, _conf.xres, 1280), \
diff --git a/include/hw/virtio/virtio-mem.h b/include/hw/virtio/virtio-mem.h
index bc4f787..e0ab31b 100644
--- a/include/hw/virtio/virtio-mem.h
+++ b/include/hw/virtio/virtio-mem.h
@@ -134,7 +134,7 @@ struct VirtioMemSystemReset {
struct VirtIOMEMClass {
/* private */
- VirtIODevice parent;
+ VirtioDeviceClass parent_class;
/* public */
void (*fill_device_info)(const VirtIOMEM *vmen, VirtioMEMDeviceInfo *vi);
diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h
index b9ea9e8..5b8ab7b 100644
--- a/include/hw/virtio/virtio-net.h
+++ b/include/hw/virtio/virtio-net.h
@@ -144,7 +144,11 @@ typedef struct VirtioNetRssData {
bool enabled_software_rss;
bool redirect;
bool populate_hash;
- uint32_t hash_types;
+ bool peer_hash_available;
+ uint32_t runtime_hash_types;
+ uint32_t supported_hash_types;
+ uint32_t peer_hash_types;
+ OnOffAutoBit64 specified_hash_types;
uint8_t key[VIRTIO_NET_RSS_MAX_KEY_SIZE];
uint16_t indirections_len;
uint16_t *indirections_table;
@@ -178,7 +182,7 @@ struct VirtIONet {
uint32_t has_vnet_hdr;
size_t host_hdr_len;
size_t guest_hdr_len;
- uint64_t host_features;
+ VIRTIO_DECLARE_FEATURES(host_features);
uint32_t rsc_timeout;
uint8_t rsc4_enabled;
uint8_t rsc6_enabled;
diff --git a/include/hw/virtio/virtio-pci.h b/include/hw/virtio/virtio-pci.h
index 971c5fa..6397529 100644
--- a/include/hw/virtio/virtio-pci.h
+++ b/include/hw/virtio/virtio-pci.h
@@ -32,9 +32,7 @@ DECLARE_OBJ_CHECKERS(VirtioPCIBusState, VirtioPCIBusClass,
enum {
VIRTIO_PCI_FLAG_BUS_MASTER_BUG_MIGRATION_BIT,
VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT,
- VIRTIO_PCI_FLAG_MIGRATE_EXTRA_BIT,
VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY_BIT,
- VIRTIO_PCI_FLAG_DISABLE_PCIE_BIT,
VIRTIO_PCI_FLAG_PAGE_PER_VQ_BIT,
VIRTIO_PCI_FLAG_ATS_BIT,
VIRTIO_PCI_FLAG_INIT_DEVERR_BIT,
@@ -54,12 +52,6 @@ enum {
* vcpu thread using ioeventfd for some devices. */
#define VIRTIO_PCI_FLAG_USE_IOEVENTFD (1 << VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT)
-/* virtio version flags */
-#define VIRTIO_PCI_FLAG_DISABLE_PCIE (1 << VIRTIO_PCI_FLAG_DISABLE_PCIE_BIT)
-
-/* migrate extra state */
-#define VIRTIO_PCI_FLAG_MIGRATE_EXTRA (1 << VIRTIO_PCI_FLAG_MIGRATE_EXTRA_BIT)
-
/* have pio notification for modern device ? */
#define VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY \
(1 << VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY_BIT)
@@ -155,6 +147,7 @@ struct VirtIOPCIProxy {
uint32_t modern_io_bar_idx;
uint32_t modern_mem_bar_idx;
int config_cap;
+ uint16_t last_pcie_cap_offset;
uint32_t flags;
bool disable_modern;
bool ignore_backend_features;
@@ -165,7 +158,7 @@ struct VirtIOPCIProxy {
uint32_t nvectors;
uint32_t dfselect;
uint32_t gfselect;
- uint32_t guest_features[2];
+ uint32_t guest_features[VIRTIO_FEATURES_NU32S];
VirtIOPCIQueue vqs[VIRTIO_QUEUE_MAX];
VirtIOIRQFD *vector_irqfd;
@@ -255,8 +248,8 @@ typedef struct VirtioPCIDeviceTypeInfo {
size_t class_size;
void (*instance_init)(Object *obj);
void (*instance_finalize)(Object *obj);
- void (*class_init)(ObjectClass *klass, void *data);
- InterfaceInfo *interfaces;
+ void (*class_init)(ObjectClass *klass, const void *data);
+ const InterfaceInfo *interfaces;
} VirtioPCIDeviceTypeInfo;
/* Register virtio-pci type(s). @t must be static. */
diff --git a/include/hw/virtio/virtio-pmem.h b/include/hw/virtio/virtio-pmem.h
index fc4fd1f..9cce600 100644
--- a/include/hw/virtio/virtio-pmem.h
+++ b/include/hw/virtio/virtio-pmem.h
@@ -36,7 +36,7 @@ struct VirtIOPMEM {
struct VirtIOPMEMClass {
/* private */
- VirtIODevice parent;
+ VirtioDeviceClass parent_class;
/* public */
void (*fill_device_info)(const VirtIOPMEM *pmem, VirtioPMEMDeviceInfo *vi);
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index 6386910..d97529c 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -14,8 +14,9 @@
#ifndef QEMU_VIRTIO_H
#define QEMU_VIRTIO_H
-#include "exec/memory.h"
+#include "system/memory.h"
#include "hw/qdev-core.h"
+#include "hw/virtio/virtio-features.h"
#include "net/net.h"
#include "migration/vmstate.h"
#include "qemu/event_notifier.h"
@@ -121,9 +122,9 @@ struct VirtIODevice
* backend (e.g. vhost) and could potentially be a subset of the
* total feature set offered by QEMU.
*/
- uint64_t host_features;
- uint64_t guest_features;
- uint64_t backend_features;
+ VIRTIO_DECLARE_FEATURES(host_features);
+ VIRTIO_DECLARE_FEATURES(guest_features);
+ VIRTIO_DECLARE_FEATURES(backend_features);
size_t config_len;
void *config;
@@ -177,6 +178,9 @@ struct VirtioDeviceClass {
/* This is what a VirtioDevice must implement */
DeviceRealize realize;
DeviceUnrealize unrealize;
+ void (*get_features_ex)(VirtIODevice *vdev, uint64_t *requested_features,
+ Error **errp);
+ void (*set_features_ex)(VirtIODevice *vdev, const uint64_t *val);
uint64_t (*get_features)(VirtIODevice *vdev,
uint64_t requested_features,
Error **errp);
@@ -186,7 +190,7 @@ struct VirtioDeviceClass {
void (*get_config)(VirtIODevice *vdev, uint8_t *config);
void (*set_config)(VirtIODevice *vdev, const uint8_t *config);
void (*reset)(VirtIODevice *vdev);
- void (*set_status)(VirtIODevice *vdev, uint8_t val);
+ int (*set_status)(VirtIODevice *vdev, uint8_t val);
/* Device must validate queue_index. */
void (*queue_reset)(VirtIODevice *vdev, uint32_t queue_index);
/* Device must validate queue_index. */
@@ -210,8 +214,14 @@ struct VirtioDeviceClass {
void (*guest_notifier_mask)(VirtIODevice *vdev, int n, bool mask);
int (*start_ioeventfd)(VirtIODevice *vdev);
void (*stop_ioeventfd)(VirtIODevice *vdev);
- /* Called before loading queues. Useful to add queues before loading. */
- int (*pre_load_queues)(VirtIODevice *vdev);
+ /*
+ * Called before loading queues.
+ * If the number of queues change at runtime, use @n to know the
+ * number and add or remove queues accordingly.
+ * Note that this function is called in the middle of loading vmsd;
+ * no assumption should be made on states being loaded from vmsd.
+ */
+ int (*pre_load_queues)(VirtIODevice *vdev, uint32_t n);
/* Saving and loading of a device; trying to deprecate save/load
* use vmsd for new devices.
*/
@@ -284,7 +294,6 @@ int virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes,
unsigned int *out_bytes, unsigned max_in_bytes,
unsigned max_out_bytes);
-void virtio_notify_irqfd(VirtIODevice *vdev, VirtQueue *vq);
void virtio_notify(VirtIODevice *vdev, VirtQueue *vq);
int virtio_save(VirtIODevice *vdev, QEMUFile *f);
@@ -366,6 +375,7 @@ void virtio_queue_reset(VirtIODevice *vdev, uint32_t queue_index);
void virtio_queue_enable(VirtIODevice *vdev, uint32_t queue_index);
void virtio_update_irq(VirtIODevice *vdev);
int virtio_set_features(VirtIODevice *vdev, uint64_t val);
+int virtio_set_features_ex(VirtIODevice *vdev, const uint64_t *val);
/* Base devices. */
typedef struct VirtIOBlkConf VirtIOBlkConf;