在 2021/10/1 下午3:05, Eugenio Pérez 写道:
Those are needed for SVQ: Host ones are needed to check if SVQ knows
how to talk with the device and for feature negotiation, and guest ones
to know if SVQ can talk with it.
Signed-off-by: Eugenio Pérez <epere...@redhat.com>
---
include/hw/virtio/vhost-vdpa.h | 2 ++
hw/virtio/vhost-vdpa.c | 31 ++++++++++++++++++++++++++++---
2 files changed, 30 insertions(+), 3 deletions(-)
diff --git a/include/hw/virtio/vhost-vdpa.h b/include/hw/virtio/vhost-vdpa.h
index fddac248b3..9044ae694b 100644
--- a/include/hw/virtio/vhost-vdpa.h
+++ b/include/hw/virtio/vhost-vdpa.h
@@ -26,6 +26,8 @@ typedef struct vhost_vdpa {
int device_fd;
uint32_t msg_type;
MemoryListener listener;
+ uint64_t host_features;
+ uint64_t guest_features;
Any reason that we can't use the features stored in VirtioDevice?
Thanks
bool shadow_vqs_enabled;
GPtrArray *shadow_vqs;
struct vhost_dev *dev;
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index 6c5f4c98b8..a057e8277d 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -439,10 +439,19 @@ static int vhost_vdpa_set_mem_table(struct vhost_dev *dev,
return 0;
}
-static int vhost_vdpa_set_features(struct vhost_dev *dev,
- uint64_t features)
+/**
+ * Internal set_features() that follows vhost/VirtIO protocol for that
+ */
+static int vhost_vdpa_backend_set_features(struct vhost_dev *dev,
+ uint64_t features)
{
+ struct vhost_vdpa *v = dev->opaque;
+
int ret;
+ if (v->host_features & BIT_ULL(VIRTIO_F_QUEUE_STATE)) {
+ features |= BIT_ULL(VIRTIO_F_QUEUE_STATE);
+ }
+
trace_vhost_vdpa_set_features(dev, features);
ret = vhost_vdpa_call(dev, VHOST_SET_FEATURES, &features);
uint8_t status = 0;
@@ -455,6 +464,17 @@ static int vhost_vdpa_set_features(struct vhost_dev *dev,
return !(status & VIRTIO_CONFIG_S_FEATURES_OK);
}
+/**
+ * Exposed vhost set features
+ */
+static int vhost_vdpa_set_features(struct vhost_dev *dev,
+ uint64_t features)
+{
+ struct vhost_vdpa *v = dev->opaque;
+ v->guest_features = features;
+ return vhost_vdpa_backend_set_features(dev, features);
+}
+
static int vhost_vdpa_set_backend_cap(struct vhost_dev *dev)
{
uint64_t features;
@@ -673,12 +693,17 @@ static int vhost_vdpa_set_vring_call(struct vhost_dev
*dev,
}
static int vhost_vdpa_get_features(struct vhost_dev *dev,
- uint64_t *features)
+ uint64_t *features)
{
int ret;
ret = vhost_vdpa_call(dev, VHOST_GET_FEATURES, features);
trace_vhost_vdpa_get_features(dev, *features);
+
+ if (ret == 0) {
+ struct vhost_vdpa *v = dev->opaque;
+ v->host_features = *features;
+ }
return ret;
}