aboutsummaryrefslogtreecommitdiff
path: root/hw/virtio.c
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2012-07-05 17:16:30 +0200
committerAvi Kivity <avi@redhat.com>2012-07-12 14:08:11 +0300
commit15b2bd1847239fe0b4a1041b69a631741d2e273a (patch)
tree36b395a7ea3642442e9f45ec4280013ca56ae033 /hw/virtio.c
parentb1f416aa8d870fab71030abc9401cfc77b948e8e (diff)
virtio: move common irqfd handling out of virtio-pci
All transports can use the same event handler for the irqfd, though the exact mechanics of the assignment will be specific. Note that there are three states: handled by the kernel, handled in userspace, disabled. This also lets virtio use event_notifier_set_handler. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'hw/virtio.c')
-rw-r--r--hw/virtio.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/hw/virtio.c b/hw/virtio.c
index 197edf00f4..d146f86f13 100644
--- a/hw/virtio.c
+++ b/hw/virtio.c
@@ -984,6 +984,30 @@ VirtQueue *virtio_get_queue(VirtIODevice *vdev, int n)
return vdev->vq + n;
}
+static void virtio_queue_guest_notifier_read(EventNotifier *n)
+{
+ VirtQueue *vq = container_of(n, VirtQueue, guest_notifier);
+ if (event_notifier_test_and_clear(n)) {
+ virtio_irq(vq);
+ }
+}
+
+void virtio_queue_set_guest_notifier_fd_handler(VirtQueue *vq, bool assign,
+ bool with_irqfd)
+{
+ if (assign && !with_irqfd) {
+ event_notifier_set_handler(&vq->guest_notifier,
+ virtio_queue_guest_notifier_read);
+ } else {
+ event_notifier_set_handler(&vq->guest_notifier, NULL);
+ }
+ if (!assign) {
+ /* Test and clear notifier before closing it,
+ * in case poll callback didn't have time to run. */
+ virtio_queue_guest_notifier_read(&vq->guest_notifier);
+ }
+}
+
EventNotifier *virtio_queue_get_guest_notifier(VirtQueue *vq)
{
return &vq->guest_notifier;