diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2012-07-05 17:16:30 +0200 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2012-07-12 14:08:11 +0300 |
commit | 15b2bd1847239fe0b4a1041b69a631741d2e273a (patch) | |
tree | 36b395a7ea3642442e9f45ec4280013ca56ae033 /hw/virtio.c | |
parent | b1f416aa8d870fab71030abc9401cfc77b948e8e (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.c | 24 |
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; |