This will make qemu aware of the device used buffers, allowing it to write the guest memory with its contents if needed.
Signed-off-by: Eugenio Pérez <epere...@redhat.com> --- hw/virtio/vhost-shadow-virtqueue.c | 15 +++++++++++++++ hw/virtio/vhost-vdpa.c | 11 +++++++++++ 2 files changed, 26 insertions(+) diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c index 9c2cf07fd9..9619c8082c 100644 --- a/hw/virtio/vhost-shadow-virtqueue.c +++ b/hw/virtio/vhost-shadow-virtqueue.c @@ -58,6 +58,19 @@ static void vhost_handle_guest_kick(EventNotifier *n) event_notifier_set(&svq->hdev_kick); } +/* Forward vhost notifications */ +static void vhost_svq_handle_call(EventNotifier *n) +{ + VhostShadowVirtqueue *svq = container_of(n, VhostShadowVirtqueue, + hdev_call); + + if (unlikely(!event_notifier_test_and_clear(n))) { + return; + } + + event_notifier_set(&svq->svq_call); +} + /** * Obtain the SVQ call notifier, where vhost device notifies SVQ that there * exists pending used buffers. @@ -150,6 +163,7 @@ VhostShadowVirtqueue *vhost_svq_new(void) /* Placeholder descriptor, it should be deleted at set_kick_fd */ event_notifier_init_fd(&svq->svq_kick, INVALID_SVQ_KICK_FD); + event_notifier_set_handler(&svq->hdev_call, vhost_svq_handle_call); return g_steal_pointer(&svq); err_init_hdev_call: @@ -165,6 +179,7 @@ err_init_hdev_kick: void vhost_svq_free(VhostShadowVirtqueue *vq) { event_notifier_cleanup(&vq->hdev_kick); + event_notifier_set_handler(&vq->hdev_call, NULL); event_notifier_cleanup(&vq->hdev_call); g_free(vq); } diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c index 029f98feee..bdb45c8808 100644 --- a/hw/virtio/vhost-vdpa.c +++ b/hw/virtio/vhost-vdpa.c @@ -716,6 +716,9 @@ static int vhost_vdpa_set_vring_call(struct vhost_dev *dev, * @dev The vhost device model * @svq The shadow virtqueue * @idx The index of the virtqueue in the vhost device + * + * Note that this function does not rewind kick file descriptor if cannot set + * call one. */ static bool vhost_vdpa_svq_setup(struct vhost_dev *dev, VhostShadowVirtqueue *svq, @@ -732,6 +735,14 @@ static bool vhost_vdpa_svq_setup(struct vhost_dev *dev, r = vhost_vdpa_set_vring_dev_kick(dev, &file); if (unlikely(r != 0)) { error_report("Can't set device kick fd (%d)", -r); + return false; + } + + event_notifier = vhost_svq_get_svq_call_notifier(svq); + file.fd = event_notifier_get_fd(event_notifier); + r = vhost_vdpa_set_vring_dev_call(dev, &file); + if (unlikely(r != 0)) { + error_report("Can't set device call fd (%d)", -r); } return r == 0; -- 2.27.0