On 2026/08/18 14:12, Connor Kite wrote:
Adds a callback to shadow virtqueues in order to enable
non-default processing of used vring elements from the device.

Signed-off-by: Connor Kite <[email protected]>
---
  hw/virtio/vhost-shadow-virtqueue.c |  9 +++++++++
  hw/virtio/vhost-shadow-virtqueue.h | 16 ++++++++++++++++
  2 files changed, 25 insertions(+)

diff --git a/hw/virtio/vhost-shadow-virtqueue.c 
b/hw/virtio/vhost-shadow-virtqueue.c
index c8831d52be..496e7e58a3 100644
--- a/hw/virtio/vhost-shadow-virtqueue.c
+++ b/hw/virtio/vhost-shadow-virtqueue.c
@@ -675,6 +675,15 @@ static void vhost_svq_flush(VhostShadowVirtqueue *svq,
                  break;
              }
+ if (svq->ops && svq->ops->used_callback) {
+                int r = svq->ops->used_callback(svq, elem, svq->ops_opaque);
+
+                if (r < 0) {
+                    /* VQ or handler is broken. Do not set guest notifier */

This comment is extraneous. It is obvious that event_notifier_set() below is not called, and it is same with the existing error path below.

What matters here is the difference with the existing error path. Why doesn't it call virtqueue_fill() nor virtqueue_flush()? They need to be addressed here.

Regards,
Akihiko Odaki

+                    return;
+                }
+            }
+
              if (unlikely(i >= svq->vring.num)) {
                  qemu_log_mask(LOG_GUEST_ERROR,
                           "More than %u used buffers obtained in a %u size 
SVQ",
diff --git a/hw/virtio/vhost-shadow-virtqueue.h 
b/hw/virtio/vhost-shadow-virtqueue.h
index ec16a1e838..fd68319fb7 100644
--- a/hw/virtio/vhost-shadow-virtqueue.h
+++ b/hw/virtio/vhost-shadow-virtqueue.h
@@ -56,8 +56,24 @@ typedef int (*VirtQueueAvailCallback)(VhostShadowVirtqueue 
*svq,
                                        VirtQueueElement *elem,
                                        void *vq_callback_opaque);
+/**
+ * Callback to handle a used buffer
+ *
+ * @svq: Shadow virtqueue
+ * @elem: Element placed in the queue by the device
+ * @vq_callback_opaque: Used to pass arguments to callback
+ *
+ * Returns 0 if the vq is running as expected. Returns a negative errno on
+ * failure.  The callback should not add used elements to the vq shadowed
+ * by the svq as that is done separately after the callback returns.
+ */
+typedef int (*VirtQueueUsedCallback)(VhostShadowVirtqueue *svq,
+                                      VirtQueueElement *elem,
+                                      void *vq_callback_opaque);
+
  typedef struct VhostShadowVirtqueueOps {
      VirtQueueAvailCallback avail_handler;
+    VirtQueueUsedCallback used_callback;
  } VhostShadowVirtqueueOps;
/* Shadow virtqueue to relay notifications */



Reply via email to