mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-03 07:43:54 -06:00
vhost: Add Shadow VirtQueue kick forwarding capabilities
At this mode no buffer forwarding will be performed in SVQ mode: Qemu will just forward the guest's kicks to the device. Host memory notifiers regions are left out for simplicity, and they will not be addressed in this series. 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>
This commit is contained in:
parent
10857ec0ad
commit
dff4426fa6
4 changed files with 215 additions and 2 deletions
|
@ -11,6 +11,59 @@
|
|||
#include "hw/virtio/vhost-shadow-virtqueue.h"
|
||||
|
||||
#include "qemu/error-report.h"
|
||||
#include "qemu/main-loop.h"
|
||||
#include "linux-headers/linux/vhost.h"
|
||||
|
||||
/**
|
||||
* Forward guest notifications.
|
||||
*
|
||||
* @n: guest kick event notifier, the one that guest set to notify svq.
|
||||
*/
|
||||
static void vhost_handle_guest_kick(EventNotifier *n)
|
||||
{
|
||||
VhostShadowVirtqueue *svq = container_of(n, VhostShadowVirtqueue, svq_kick);
|
||||
event_notifier_test_and_clear(n);
|
||||
event_notifier_set(&svq->hdev_kick);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a new file descriptor for the guest to kick the SVQ and notify for avail
|
||||
*
|
||||
* @svq: The svq
|
||||
* @svq_kick_fd: The svq kick fd
|
||||
*
|
||||
* Note that the SVQ will never close the old file descriptor.
|
||||
*/
|
||||
void vhost_svq_set_svq_kick_fd(VhostShadowVirtqueue *svq, int svq_kick_fd)
|
||||
{
|
||||
EventNotifier *svq_kick = &svq->svq_kick;
|
||||
bool poll_stop = VHOST_FILE_UNBIND != event_notifier_get_fd(svq_kick);
|
||||
bool poll_start = svq_kick_fd != VHOST_FILE_UNBIND;
|
||||
|
||||
if (poll_stop) {
|
||||
event_notifier_set_handler(svq_kick, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* event_notifier_set_handler already checks for guest's notifications if
|
||||
* they arrive at the new file descriptor in the switch, so there is no
|
||||
* need to explicitly check for them.
|
||||
*/
|
||||
if (poll_start) {
|
||||
event_notifier_init_fd(svq_kick, svq_kick_fd);
|
||||
event_notifier_set(svq_kick);
|
||||
event_notifier_set_handler(svq_kick, vhost_handle_guest_kick);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the shadow virtqueue operation.
|
||||
* @svq: Shadow Virtqueue
|
||||
*/
|
||||
void vhost_svq_stop(VhostShadowVirtqueue *svq)
|
||||
{
|
||||
event_notifier_set_handler(&svq->svq_kick, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates vhost shadow virtqueue, and instructs the vhost device to use the
|
||||
|
@ -39,6 +92,7 @@ VhostShadowVirtqueue *vhost_svq_new(void)
|
|||
goto err_init_hdev_call;
|
||||
}
|
||||
|
||||
event_notifier_init_fd(&svq->svq_kick, VHOST_FILE_UNBIND);
|
||||
return g_steal_pointer(&svq);
|
||||
|
||||
err_init_hdev_call:
|
||||
|
@ -56,6 +110,7 @@ err_init_hdev_kick:
|
|||
void vhost_svq_free(gpointer pvq)
|
||||
{
|
||||
VhostShadowVirtqueue *vq = pvq;
|
||||
vhost_svq_stop(vq);
|
||||
event_notifier_cleanup(&vq->hdev_kick);
|
||||
event_notifier_cleanup(&vq->hdev_call);
|
||||
g_free(vq);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue