Blame qemu-virtio-pci-irqfd-support.patch

Justin M. Forbes 272dfe
Use irqfd when supported by kernel.
Justin M. Forbes 272dfe
This uses msix mask notifiers: when vector is masked, we poll it from
Justin M. Forbes 272dfe
userspace.  When it is unmasked, we poll it from kernel.
Justin M. Forbes 272dfe
Justin M. Forbes 272dfe
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Justin M. Forbes 272dfe
---
Justin M. Forbes 272dfe
 hw/virtio-pci.c |   31 +++++++++++++++++++++++++++++--
Justin M. Forbes 272dfe
 1 files changed, 29 insertions(+), 2 deletions(-)
Justin M. Forbes 272dfe
Justin M. Forbes 272dfe
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
Justin M. Forbes 272dfe
index c454093..e8e0d82 100644
Justin M. Forbes 272dfe
--- a/hw/virtio-pci.c
Justin M. Forbes 272dfe
+++ b/hw/virtio-pci.c
Justin M. Forbes 272dfe
@@ -404,6 +404,27 @@ static void virtio_pci_guest_notifier_read(void *opaque)
Justin M. Forbes 272dfe
     }
Justin M. Forbes 272dfe
 }
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
+static int virtio_pci_mask_notifier(PCIDevice *dev, unsigned vector,
Justin M. Forbes 272dfe
+                                    void *opaque, int masked)
Justin M. Forbes 272dfe
+{
Justin M. Forbes 272dfe
+    VirtQueue *vq = opaque;
Justin M. Forbes 272dfe
+    EventNotifier *notifier = virtio_queue_guest_notifier(vq);
Justin M. Forbes 272dfe
+    int r = kvm_set_irqfd(dev->msix_irq_entries[vector].gsi,
Justin M. Forbes 272dfe
+                          event_notifier_get_fd(notifier),
Justin M. Forbes 272dfe
+                          !masked);
Justin M. Forbes 272dfe
+    if (r < 0) {
Justin M. Forbes 272dfe
+        return (r == -ENOSYS) ? 0 : r;
Justin M. Forbes 272dfe
+    }
Justin M. Forbes 272dfe
+    if (masked) {
Justin M. Forbes 272dfe
+        qemu_set_fd_handler(event_notifier_get_fd(notifier),
Justin M. Forbes 272dfe
+                            virtio_pci_guest_notifier_read, NULL, vq);
Justin M. Forbes 272dfe
+    } else {
Justin M. Forbes 272dfe
+        qemu_set_fd_handler(event_notifier_get_fd(notifier),
Justin M. Forbes 272dfe
+                            NULL, NULL, vq);
Justin M. Forbes 272dfe
+    }
Justin M. Forbes 272dfe
+    return 0;
Justin M. Forbes 272dfe
+}
Justin M. Forbes 272dfe
+
Justin M. Forbes 272dfe
 static int virtio_pci_guest_notifier(void *opaque, int n, bool assign)
Justin M. Forbes 272dfe
 {
Justin M. Forbes 272dfe
     VirtIOPCIProxy *proxy = opaque;
Justin M. Forbes 272dfe
@@ -412,11 +433,15 @@ static int virtio_pci_guest_notifier(void *opaque, int n, bool assign)
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
     if (assign) {
Justin M. Forbes 272dfe
         int r = event_notifier_init(notifier, 0);
Justin M. Forbes 272dfe
-	if (r < 0)
Justin M. Forbes 272dfe
-		return r;
Justin M. Forbes 272dfe
+        if (r < 0)
Justin M. Forbes 272dfe
+            return r;
Justin M. Forbes 272dfe
         qemu_set_fd_handler(event_notifier_get_fd(notifier),
Justin M. Forbes 272dfe
                             virtio_pci_guest_notifier_read, NULL, vq);
Justin M. Forbes 272dfe
+        msix_set_mask_notifier(&proxy->pci_dev,
Justin M. Forbes 272dfe
+			       virtio_queue_vector(proxy->vdev, n), vq);
Justin M. Forbes 272dfe
     } else {
Justin M. Forbes 272dfe
+        msix_set_mask_notifier(&proxy->pci_dev,
Justin M. Forbes 272dfe
+			       virtio_queue_vector(proxy->vdev, n), NULL);
Justin M. Forbes 272dfe
         qemu_set_fd_handler(event_notifier_get_fd(notifier),
Justin M. Forbes 272dfe
                             NULL, NULL, vq);
Justin M. Forbes 272dfe
         event_notifier_cleanup(notifier);
Justin M. Forbes 272dfe
@@ -501,6 +526,8 @@ static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev,
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
     proxy->pci_dev.config_write = virtio_write_config;
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
+    proxy->pci_dev.msix_mask_notifier = virtio_pci_mask_notifier;
Justin M. Forbes 272dfe
+
Justin M. Forbes 272dfe
     size = VIRTIO_PCI_REGION_SIZE(&proxy->pci_dev) + vdev->config_len;
Justin M. Forbes 272dfe
     if (size & (size-1))
Justin M. Forbes 272dfe
         size = 1 << qemu_fls(size);
Justin M. Forbes 272dfe
-- 
Justin M. Forbes 272dfe
1.6.6.144.g5c3af