summary refs log tree commit diff stats
path: root/hw/virtio-pci.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-pci.c
parentb1f416aa8d870fab71030abc9401cfc77b948e8e (diff)
downloadfocaccia-qemu-15b2bd1847239fe0b4a1041b69a631741d2e273a.tar.gz
focaccia-qemu-15b2bd1847239fe0b4a1041b69a631741d2e273a.zip
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-pci.c')
-rw-r--r--hw/virtio-pci.c37
1 files changed, 10 insertions, 27 deletions
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index 36770fd8f7..a66c946f48 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -496,25 +496,15 @@ static unsigned virtio_pci_get_features(void *opaque)
     return proxy->host_features;
 }
 
-static void virtio_pci_guest_notifier_read(void *opaque)
-{
-    VirtQueue *vq = opaque;
-    EventNotifier *n = virtio_queue_get_guest_notifier(vq);
-    if (event_notifier_test_and_clear(n)) {
-        virtio_irq(vq);
-    }
-}
-
 static int kvm_virtio_pci_vq_vector_use(VirtIOPCIProxy *proxy,
                                         unsigned int queue_no,
                                         unsigned int vector,
                                         MSIMessage msg)
 {
     VirtQueue *vq = virtio_get_queue(proxy->vdev, queue_no);
+    EventNotifier *n = virtio_queue_get_guest_notifier(vq);
     VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
-    int fd, ret;
-
-    fd = event_notifier_get_fd(virtio_queue_get_guest_notifier(vq));
+    int ret;
 
     if (irqfd->users == 0) {
         ret = kvm_irqchip_add_msi_route(kvm_state, msg);
@@ -525,7 +515,7 @@ static int kvm_virtio_pci_vq_vector_use(VirtIOPCIProxy *proxy,
     }
     irqfd->users++;
 
-    ret = kvm_irqchip_add_irqfd(kvm_state, fd, irqfd->virq);
+    ret = kvm_irqchip_add_irq_notifier(kvm_state, n, irqfd->virq);
     if (ret < 0) {
         if (--irqfd->users == 0) {
             kvm_irqchip_release_virq(kvm_state, irqfd->virq);
@@ -533,8 +523,7 @@ static int kvm_virtio_pci_vq_vector_use(VirtIOPCIProxy *proxy,
         return ret;
     }
 
-    qemu_set_fd_handler(fd, NULL, NULL, NULL);
-
+    virtio_queue_set_guest_notifier_fd_handler(vq, true, true);
     return 0;
 }
 
@@ -543,19 +532,18 @@ static void kvm_virtio_pci_vq_vector_release(VirtIOPCIProxy *proxy,
                                              unsigned int vector)
 {
     VirtQueue *vq = virtio_get_queue(proxy->vdev, queue_no);
+    EventNotifier *n = virtio_queue_get_guest_notifier(vq);
     VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
-    int fd, ret;
-
-    fd = event_notifier_get_fd(virtio_queue_get_guest_notifier(vq));
+    int ret;
 
-    ret = kvm_irqchip_remove_irqfd(kvm_state, fd, irqfd->virq);
+    ret = kvm_irqchip_remove_irq_notifier(kvm_state, n, irqfd->virq);
     assert(ret == 0);
 
     if (--irqfd->users == 0) {
         kvm_irqchip_release_virq(kvm_state, irqfd->virq);
     }
 
-    qemu_set_fd_handler(fd, virtio_pci_guest_notifier_read, NULL, vq);
+    virtio_queue_set_guest_notifier_fd_handler(vq, true, false);
 }
 
 static int kvm_virtio_pci_vector_use(PCIDevice *dev, unsigned vector,
@@ -617,14 +605,9 @@ static int virtio_pci_set_guest_notifier(void *opaque, int n, bool assign)
         if (r < 0) {
             return r;
         }
-        qemu_set_fd_handler(event_notifier_get_fd(notifier),
-                            virtio_pci_guest_notifier_read, NULL, vq);
+        virtio_queue_set_guest_notifier_fd_handler(vq, true, false);
     } else {
-        qemu_set_fd_handler(event_notifier_get_fd(notifier),
-                            NULL, NULL, NULL);
-        /* Test and clear notifier before closing it,
-         * in case poll callback didn't have time to run. */
-        virtio_pci_guest_notifier_read(vq);
+        virtio_queue_set_guest_notifier_fd_handler(vq, false, false);
         event_notifier_cleanup(notifier);
     }