On Thu, Jul 23, 2026 at 03:30:12PM -0700, Connor Kite wrote:
> Adds shadow virtqueues that will eventually be used to transfer data
> between device and host via bounce buffers when isolation mode is
> active.  The svqs are initalized, and eventfd assignments are
> intercepted so that notifications come to svqs first before
> the guest or backend receive them.
> 
> Signed-off-by: Connor Kite <[email protected]>
> ---
>  hw/virtio/vhost-user.c | 54 
> ++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 54 insertions(+)
> 
> diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
> index acabfb7f1c..75858289a2 100644
> --- a/hw/virtio/vhost-user.c
> +++ b/hw/virtio/vhost-user.c
> @@ -18,6 +18,7 @@
>  #include "hw/virtio/vhost-backend.h"
>  #include "hw/virtio/virtio.h"
>  #include "hw/virtio/virtio-net.h"
> +#include "hw/virtio/vhost-shadow-virtqueue.h"
>  #include "hw/virtio/vhost-iova-tree.h"
>  #include "chardev/char-fe.h"
>  #include "io/channel-socket.h"
> @@ -365,7 +366,9 @@ struct vhost_user {
>  
>      /* Isolated memory data*/
>      struct IsolationRegion iso_memory;
> +    GPtrArray *shadow_vqs;
>      VhostIOVATree *iso_iova_tree;
> +    bool svqs_allocated;
>  };
>  
>  struct scrub_regions {
> @@ -1693,6 +1696,24 @@ static int vhost_set_vring_file(struct vhost_dev *dev,
>  static int vhost_user_set_vring_kick(struct vhost_dev *dev,
>                                       struct vhost_vring_file *file)
>  {
> +    struct vhost_user *u = dev->opaque;
> +    int svq_idx = file->index - dev->vq_index;
> +    if (u->user->memory_isolation) {
> +        VhostShadowVirtqueue *svq = g_ptr_array_index(u->shadow_vqs,
> +                                                      svq_idx);
> +        vhost_svq_set_svq_kick_fd(svq, file->fd);
> +
> +        if (svq->hdev_kick.initialized == false) {
> +            int r = event_notifier_init(&svq->hdev_kick, 0);

Where is event_notifier_cleanup() called?

> +            if (r) {
> +                error_report("Failed to create kick event notifier");
> +                return r;
> +            }
> +        }
> +
> +        file->fd = event_notifier_get_fd(&svq->hdev_kick);

Modifying the function argument is probably not expected but
vhost_virtqueue_start() doesn't use it after this call, so there is no
immediate problem. It would be safer to have a local struct
vhost_vring_file that can be modified without affecting the caller's
copy.

> +    }
> +
>      int ret = vhost_set_vring_file(dev, VHOST_USER_SET_VRING_KICK, file);
>      if (ret < 0) {
>          return ret;
> @@ -1721,6 +1742,24 @@ static int vhost_user_set_vring_kick(struct vhost_dev 
> *dev,
>  static int vhost_user_set_vring_call(struct vhost_dev *dev,
>                                       struct vhost_vring_file *file)
>  {
> +    struct vhost_user *u = dev->opaque;
> +    int svq_idx = file->index - dev->vq_index;
> +    if (u->user->memory_isolation) {
> +        VhostShadowVirtqueue *svq = g_ptr_array_index(u->shadow_vqs,
> +                                                      svq_idx);
> +        vhost_svq_set_svq_call_fd(svq, file->fd);
> +
> +        if (svq->hdev_call.initialized == false) {
> +            int r = event_notifier_init(&svq->hdev_call, 0);

Where is event_notifier_cleanup() called?

> +            if (r) {
> +                error_report("Failed to create call event notifier");
> +                return r;
> +            }
> +        }
> +
> +        file->fd = event_notifier_get_fd(&svq->hdev_call);

Same as above.

> +    }
> +
>      return vhost_set_vring_file(dev, VHOST_USER_SET_VRING_CALL, file);
>  }
>  
> @@ -2715,6 +2754,17 @@ static int 
> vhost_user_postcopy_notifier(NotifierWithReturn *notifier,
>      return 0;
>  }
>  
> +static void vhost_user_init_svq(struct vhost_dev *dev, struct vhost_user *u)
> +{
> +    /*Modified from vhost-vdpa*/
> +    u->shadow_vqs = g_ptr_array_new_full(dev->nvqs, vhost_svq_free);
> +    for (int i = 0; i < dev->nvqs; i++) {
> +        VhostShadowVirtqueue *svq;
> +        svq = vhost_svq_new(NULL, NULL);
> +        g_ptr_array_add(u->shadow_vqs, svq);
> +    }
> +}
> +
>  static int vhost_user_backend_init(struct vhost_dev *dev, void *opaque,
>                                     Error **errp)
>  {
> @@ -2859,6 +2909,10 @@ static int vhost_user_backend_init(struct vhost_dev 
> *dev, void *opaque,
>      u->postcopy_notifier.notify = vhost_user_postcopy_notifier;
>      postcopy_add_notifier(&u->postcopy_notifier);
>  
> +    if (vus->memory_isolation) {
> +        vhost_user_init_svq(dev, u);
> +    }
> +
>      return 0;
>  }
>  
> 
> -- 
> 2.43.0
> 

Attachment: signature.asc
Description: PGP signature

Reply via email to