thebeanogamer / rpms / qemu-kvm

Forked from rpms/qemu-kvm 5 months ago
Clone
29b115
From 433106c286a1961737300ebaece6f10b2747e7d8 Mon Sep 17 00:00:00 2001
29b115
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
29b115
Date: Thu, 21 Jul 2022 15:38:55 +0200
29b115
Subject: [PATCH 20/32] vhost: Add svq avail_handler callback
29b115
MIME-Version: 1.0
29b115
Content-Type: text/plain; charset=UTF-8
29b115
Content-Transfer-Encoding: 8bit
29b115
29b115
RH-Author: Eugenio Pérez <eperezma@redhat.com>
29b115
RH-MergeRequest: 108: Net Control Virtqueue shadow Support
29b115
RH-Commit: [20/27] d228eb89d204f8be623bc870503bbf0078dfc9ae (eperezmartin/qemu-kvm)
29b115
RH-Bugzilla: 1939363
29b115
RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
29b115
RH-Acked-by: Cindy Lu <lulu@redhat.com>
29b115
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
29b115
29b115
Bugzilla: https://bugzilla.redhat.com/1939363
29b115
29b115
Upstream Status: git://git.qemu.org/qemu.git
29b115
29b115
commit e966c0b781aebabd2c0f5eef91678f08ce1d068c
29b115
Author: Eugenio Pérez <eperezma@redhat.com>
29b115
Date:   Wed Jul 20 08:59:39 2022 +0200
29b115
29b115
    vhost: Add svq avail_handler callback
29b115
29b115
    This allows external handlers to be aware of new buffers that the guest
29b115
    places in the virtqueue.
29b115
29b115
    When this callback is defined the ownership of the guest's virtqueue
29b115
    element is transferred to the callback. This means that if the user
29b115
    wants to forward the descriptor it needs to manually inject it. The
29b115
    callback is also free to process the command by itself and use the
29b115
    element with svq_push.
29b115
29b115
    Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
29b115
    Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
29b115
    Signed-off-by: Jason Wang <jasowang@redhat.com>
29b115
29b115
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
29b115
---
29b115
 hw/virtio/vhost-shadow-virtqueue.c | 14 ++++++++++++--
29b115
 hw/virtio/vhost-shadow-virtqueue.h | 31 +++++++++++++++++++++++++++++-
29b115
 hw/virtio/vhost-vdpa.c             |  3 ++-
29b115
 3 files changed, 44 insertions(+), 4 deletions(-)
29b115
29b115
diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c
29b115
index 95d0d7a7ee..e53aac45f6 100644
29b115
--- a/hw/virtio/vhost-shadow-virtqueue.c
29b115
+++ b/hw/virtio/vhost-shadow-virtqueue.c
29b115
@@ -306,7 +306,11 @@ static void vhost_handle_guest_kick(VhostShadowVirtqueue *svq)
29b115
                 break;
29b115
             }
29b115
 
29b115
-            r = vhost_svq_add_element(svq, elem);
29b115
+            if (svq->ops) {
29b115
+                r = svq->ops->avail_handler(svq, elem, svq->ops_opaque);
29b115
+            } else {
29b115
+                r = vhost_svq_add_element(svq, elem);
29b115
+            }
29b115
             if (unlikely(r != 0)) {
29b115
                 if (r == -ENOSPC) {
29b115
                     /*
29b115
@@ -685,12 +689,16 @@ void vhost_svq_stop(VhostShadowVirtqueue *svq)
29b115
  * shadow methods and file descriptors.
29b115
  *
29b115
  * @iova_tree: Tree to perform descriptors translations
29b115
+ * @ops: SVQ owner callbacks
29b115
+ * @ops_opaque: ops opaque pointer
29b115
  *
29b115
  * Returns the new virtqueue or NULL.
29b115
  *
29b115
  * In case of error, reason is reported through error_report.
29b115
  */
29b115
-VhostShadowVirtqueue *vhost_svq_new(VhostIOVATree *iova_tree)
29b115
+VhostShadowVirtqueue *vhost_svq_new(VhostIOVATree *iova_tree,
29b115
+                                    const VhostShadowVirtqueueOps *ops,
29b115
+                                    void *ops_opaque)
29b115
 {
29b115
     g_autofree VhostShadowVirtqueue *svq = g_new0(VhostShadowVirtqueue, 1);
29b115
     int r;
29b115
@@ -712,6 +720,8 @@ VhostShadowVirtqueue *vhost_svq_new(VhostIOVATree *iova_tree)
29b115
     event_notifier_init_fd(&svq->svq_kick, VHOST_FILE_UNBIND);
29b115
     event_notifier_set_handler(&svq->hdev_call, vhost_svq_handle_call);
29b115
     svq->iova_tree = iova_tree;
29b115
+    svq->ops = ops;
29b115
+    svq->ops_opaque = ops_opaque;
29b115
     return g_steal_pointer(&svq);
29b115
 
29b115
 err_init_hdev_call:
29b115
diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-shadow-virtqueue.h
29b115
index cf442f7dea..d04c34a589 100644
29b115
--- a/hw/virtio/vhost-shadow-virtqueue.h
29b115
+++ b/hw/virtio/vhost-shadow-virtqueue.h
29b115
@@ -25,6 +25,27 @@ typedef struct SVQDescState {
29b115
     unsigned int ndescs;
29b115
 } SVQDescState;
29b115
 
29b115
+typedef struct VhostShadowVirtqueue VhostShadowVirtqueue;
29b115
+
29b115
+/**
29b115
+ * Callback to handle an avail buffer.
29b115
+ *
29b115
+ * @svq:  Shadow virtqueue
29b115
+ * @elem:  Element placed in the queue by the guest
29b115
+ * @vq_callback_opaque:  Opaque
29b115
+ *
29b115
+ * Returns 0 if the vq is running as expected.
29b115
+ *
29b115
+ * Note that ownership of elem is transferred to the callback.
29b115
+ */
29b115
+typedef int (*VirtQueueAvailCallback)(VhostShadowVirtqueue *svq,
29b115
+                                      VirtQueueElement *elem,
29b115
+                                      void *vq_callback_opaque);
29b115
+
29b115
+typedef struct VhostShadowVirtqueueOps {
29b115
+    VirtQueueAvailCallback avail_handler;
29b115
+} VhostShadowVirtqueueOps;
29b115
+
29b115
 /* Shadow virtqueue to relay notifications */
29b115
 typedef struct VhostShadowVirtqueue {
29b115
     /* Shadow vring */
29b115
@@ -69,6 +90,12 @@ typedef struct VhostShadowVirtqueue {
29b115
      */
29b115
     uint16_t *desc_next;
29b115
 
29b115
+    /* Caller callbacks */
29b115
+    const VhostShadowVirtqueueOps *ops;
29b115
+
29b115
+    /* Caller callbacks opaque */
29b115
+    void *ops_opaque;
29b115
+
29b115
     /* Next head to expose to the device */
29b115
     uint16_t shadow_avail_idx;
29b115
 
29b115
@@ -102,7 +129,9 @@ void vhost_svq_start(VhostShadowVirtqueue *svq, VirtIODevice *vdev,
29b115
                      VirtQueue *vq);
29b115
 void vhost_svq_stop(VhostShadowVirtqueue *svq);
29b115
 
29b115
-VhostShadowVirtqueue *vhost_svq_new(VhostIOVATree *iova_tree);
29b115
+VhostShadowVirtqueue *vhost_svq_new(VhostIOVATree *iova_tree,
29b115
+                                    const VhostShadowVirtqueueOps *ops,
29b115
+                                    void *ops_opaque);
29b115
 
29b115
 void vhost_svq_free(gpointer vq);
29b115
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(VhostShadowVirtqueue, vhost_svq_free);
29b115
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
29b115
index 33dcaa135e..28df57b12e 100644
29b115
--- a/hw/virtio/vhost-vdpa.c
29b115
+++ b/hw/virtio/vhost-vdpa.c
29b115
@@ -416,8 +416,9 @@ static int vhost_vdpa_init_svq(struct vhost_dev *hdev, struct vhost_vdpa *v,
29b115
 
29b115
     shadow_vqs = g_ptr_array_new_full(hdev->nvqs, vhost_svq_free);
29b115
     for (unsigned n = 0; n < hdev->nvqs; ++n) {
29b115
-        g_autoptr(VhostShadowVirtqueue) svq = vhost_svq_new(v->iova_tree);
29b115
+        g_autoptr(VhostShadowVirtqueue) svq;
29b115
 
29b115
+        svq = vhost_svq_new(v->iova_tree, NULL, NULL);
29b115
         if (unlikely(!svq)) {
29b115
             error_setg(errp, "Cannot create svq %u", n);
29b115
             return -1;
29b115
-- 
29b115
2.31.1
29b115