134 lines
4.3 KiB
Diff
134 lines
4.3 KiB
Diff
|
|
From 2f41ff8e23ed358890fb66b6f524627a9747cc14 Mon Sep 17 00:00:00 2001
|
||
|
|
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
|
||
|
|
Date: Mon, 14 Mar 2022 18:34:44 +0100
|
||
|
|
Subject: [PATCH] vhost: Add vhost_svq_valid_features to shadow vq
|
||
|
|
MIME-Version: 1.0
|
||
|
|
Content-Type: text/plain; charset=UTF-8
|
||
|
|
Content-Transfer-Encoding: 8bit
|
||
|
|
|
||
|
|
This allows SVQ to negotiate features with the guest and the device. For
|
||
|
|
the device, SVQ is a driver. While this function bypasses all
|
||
|
|
non-transport features, it needs to disable the features that SVQ does
|
||
|
|
not support when forwarding buffers. This includes packed vq layout,
|
||
|
|
indirect descriptors or event idx.
|
||
|
|
|
||
|
|
Future changes can add support to offer more features to the guest,
|
||
|
|
since the use of VirtQueue gives this for free. This is left out at the
|
||
|
|
moment for simplicity.
|
||
|
|
|
||
|
|
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
|
||
|
|
Acked-by: Michael S. Tsirkin <mst@redhat.com>
|
||
|
|
Signed-off-by: Jason Wang <jasowang@redhat.com>
|
||
|
|
Signed-off-by: fangyi <eric.fangyi@huawei.com>
|
||
|
|
---
|
||
|
|
hw/virtio/vhost-shadow-virtqueue.c | 44 ++++++++++++++++++++++++++++++
|
||
|
|
hw/virtio/vhost-shadow-virtqueue.h | 2 ++
|
||
|
|
hw/virtio/vhost-vdpa.c | 15 ++++++++++
|
||
|
|
3 files changed, 61 insertions(+)
|
||
|
|
|
||
|
|
diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c
|
||
|
|
index 55cb5414ef..519328445c 100644
|
||
|
|
--- a/hw/virtio/vhost-shadow-virtqueue.c
|
||
|
|
+++ b/hw/virtio/vhost-shadow-virtqueue.c
|
||
|
|
@@ -11,9 +11,53 @@
|
||
|
|
#include "hw/virtio/vhost-shadow-virtqueue.h"
|
||
|
|
|
||
|
|
#include "qemu/error-report.h"
|
||
|
|
+#include "qapi/error.h"
|
||
|
|
#include "qemu/main-loop.h"
|
||
|
|
#include "linux-headers/linux/vhost.h"
|
||
|
|
|
||
|
|
+/**
|
||
|
|
+ * Validate the transport device features that both guests can use with the SVQ
|
||
|
|
+ * and SVQs can use with the device.
|
||
|
|
+ *
|
||
|
|
+ * @dev_features: The features
|
||
|
|
+ * @errp: Error pointer
|
||
|
|
+ */
|
||
|
|
+bool vhost_svq_valid_features(uint64_t features, Error **errp)
|
||
|
|
+{
|
||
|
|
+ bool ok = true;
|
||
|
|
+ uint64_t svq_features = features;
|
||
|
|
+
|
||
|
|
+ for (uint64_t b = VIRTIO_TRANSPORT_F_START; b <= VIRTIO_TRANSPORT_F_END;
|
||
|
|
+ ++b) {
|
||
|
|
+ switch (b) {
|
||
|
|
+ case VIRTIO_F_ANY_LAYOUT:
|
||
|
|
+ continue;
|
||
|
|
+
|
||
|
|
+ case VIRTIO_F_ACCESS_PLATFORM:
|
||
|
|
+ /* SVQ trust in the host's IOMMU to translate addresses */
|
||
|
|
+ case VIRTIO_F_VERSION_1:
|
||
|
|
+ /* SVQ trust that the guest vring is little endian */
|
||
|
|
+ if (!(svq_features & BIT_ULL(b))) {
|
||
|
|
+ svq_features |= BIT_ULL(b);
|
||
|
|
+ ok = false;
|
||
|
|
+ }
|
||
|
|
+ continue;
|
||
|
|
+
|
||
|
|
+ default:
|
||
|
|
+ if (svq_features & BIT_ULL(b)) {
|
||
|
|
+ svq_features &= ~BIT_ULL(b);
|
||
|
|
+ ok = false;
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ if (!ok) {
|
||
|
|
+ error_setg(errp, "SVQ Invalid device feature flags, offer: 0x%"PRIx64
|
||
|
|
+ ", ok: 0x%"PRIx64, features, svq_features);
|
||
|
|
+ }
|
||
|
|
+ return ok;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
/**
|
||
|
|
* Forward guest notifications.
|
||
|
|
*
|
||
|
|
diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-shadow-virtqueue.h
|
||
|
|
index cbc5213579..9e12f77201 100644
|
||
|
|
--- a/hw/virtio/vhost-shadow-virtqueue.h
|
||
|
|
+++ b/hw/virtio/vhost-shadow-virtqueue.h
|
||
|
|
@@ -33,6 +33,8 @@ typedef struct VhostShadowVirtqueue {
|
||
|
|
EventNotifier svq_call;
|
||
|
|
} VhostShadowVirtqueue;
|
||
|
|
|
||
|
|
+bool vhost_svq_valid_features(uint64_t features, Error **errp);
|
||
|
|
+
|
||
|
|
void vhost_svq_set_svq_kick_fd(VhostShadowVirtqueue *svq, int svq_kick_fd);
|
||
|
|
void vhost_svq_set_svq_call_fd(VhostShadowVirtqueue *svq, int call_fd);
|
||
|
|
|
||
|
|
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
|
||
|
|
index 29c720308f..8ee63933a8 100644
|
||
|
|
--- a/hw/virtio/vhost-vdpa.c
|
||
|
|
+++ b/hw/virtio/vhost-vdpa.c
|
||
|
|
@@ -350,11 +350,26 @@ static int vhost_vdpa_init_svq(struct vhost_dev *hdev, struct vhost_vdpa *v,
|
||
|
|
Error **errp)
|
||
|
|
{
|
||
|
|
g_autoptr(GPtrArray) shadow_vqs = NULL;
|
||
|
|
+ uint64_t dev_features, svq_features;
|
||
|
|
+ int r;
|
||
|
|
+ bool ok;
|
||
|
|
|
||
|
|
if (!v->shadow_vqs_enabled) {
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
+ r = hdev->vhost_ops->vhost_get_features(hdev, &dev_features);
|
||
|
|
+ if (r != 0) {
|
||
|
|
+ error_setg_errno(errp, -r, "Can't get vdpa device features");
|
||
|
|
+ return r;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ svq_features = dev_features;
|
||
|
|
+ ok = vhost_svq_valid_features(svq_features, errp);
|
||
|
|
+ if (unlikely(!ok)) {
|
||
|
|
+ return -1;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
shadow_vqs = g_ptr_array_new_full(hdev->nvqs, vhost_svq_free);
|
||
|
|
for (unsigned n = 0; n < hdev->nvqs; ++n) {
|
||
|
|
g_autoptr(VhostShadowVirtqueue) svq = vhost_svq_new();
|
||
|
|
--
|
||
|
|
2.27.0
|
||
|
|
|