diff options
author | Anthony Liguori <aliguori@us.ibm.com> | 2012-07-18 14:44:43 -0500 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2012-07-18 14:44:43 -0500 |
commit | 09f06a6c603ce64284287d32f6ffadaaa5064850 (patch) | |
tree | 176bbc325a87eb4961ec8605e75d326746e7c9bb /hw/virtio.c | |
parent | 513e6bde4fa551c293e7d346e27b618b57a4087a (diff) | |
parent | 15b2bd1847239fe0b4a1041b69a631741d2e273a (diff) |
Merge remote-tracking branch 'qemu-kvm/uq/master' into staging
* qemu-kvm/uq/master:
virtio: move common irqfd handling out of virtio-pci
virtio: move common ioeventfd handling out of virtio-pci
event_notifier: add event_notifier_set_handler
memory: pass EventNotifier, not eventfd
ivshmem: wrap ivshmem_del_eventfd loops with transaction
ivshmem: use EventNotifier and memory API
event_notifier: add event_notifier_init_fd
event_notifier: remove event_notifier_test
event_notifier: add event_notifier_set
apic: Defer interrupt updates to VCPU thread
apic: Reevaluate pending interrupts on LVT_LINT0 changes
apic: Resolve potential endless loop around apic_update_irq
kvm: expose tsc deadline timer feature to guest
kvm_pv_eoi: add flag support
kvm: Don't abort on kvm_irqchip_add_msi_route()
Diffstat (limited to 'hw/virtio.c')
-rw-r--r-- | hw/virtio.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/hw/virtio.c b/hw/virtio.c index 168abe4864..d146f86f13 100644 --- a/hw/virtio.c +++ b/hw/virtio.c @@ -984,10 +984,56 @@ 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; } + +static void virtio_queue_host_notifier_read(EventNotifier *n) +{ + VirtQueue *vq = container_of(n, VirtQueue, host_notifier); + if (event_notifier_test_and_clear(n)) { + virtio_queue_notify_vq(vq); + } +} + +void virtio_queue_set_host_notifier_fd_handler(VirtQueue *vq, bool assign) +{ + if (assign) { + event_notifier_set_handler(&vq->host_notifier, + virtio_queue_host_notifier_read); + } else { + event_notifier_set_handler(&vq->host_notifier, NULL); + /* Test and clear notifier before after disabling event, + * in case poll callback didn't have time to run. */ + virtio_queue_host_notifier_read(&vq->host_notifier); + } +} + EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq) { return &vq->host_notifier; |