Blame qemu-virtio-pci-fill-in-notifier-support.patch

Justin M. Forbes 272dfe
Support host/guest notifiers in virtio-pci.
Justin M. Forbes 272dfe
The last one only with kvm, that's okay
Justin M. Forbes 272dfe
because vhost relies on kvm anyway.
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 |   62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
Justin M. Forbes 272dfe
 1 files changed, 62 insertions(+), 0 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 05898c8..c454093 100644
Justin M. Forbes 272dfe
--- a/hw/virtio-pci.c
Justin M. Forbes 272dfe
+++ b/hw/virtio-pci.c
Justin M. Forbes 272dfe
@@ -23,6 +23,7 @@
Justin M. Forbes 272dfe
 #include "msix.h"
Justin M. Forbes 272dfe
 #include "net.h"
Justin M. Forbes 272dfe
 #include "loader.h"
Justin M. Forbes 272dfe
+#include "kvm.h"
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
 /* from Linux's linux/virtio_pci.h */
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
@@ -394,6 +395,65 @@ static unsigned virtio_pci_get_features(void *opaque)
Justin M. Forbes 272dfe
     return proxy->host_features;
Justin M. Forbes 272dfe
 }
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
+static void virtio_pci_guest_notifier_read(void *opaque)
Justin M. Forbes 272dfe
+{
Justin M. Forbes 272dfe
+    VirtQueue *vq = opaque;
Justin M. Forbes 272dfe
+    EventNotifier *n = virtio_queue_guest_notifier(vq);
Justin M. Forbes 272dfe
+    if (event_notifier_test_and_clear(n)) {
Justin M. Forbes 272dfe
+        virtio_irq(vq);
Justin M. Forbes 272dfe
+    }
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
+    VirtQueue *vq = virtio_queue(proxy->vdev, n);
Justin M. Forbes 272dfe
+    EventNotifier *notifier = virtio_queue_guest_notifier(vq);
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
+        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
+        event_notifier_cleanup(notifier);
Justin M. Forbes 272dfe
+    }
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_host_notifier(void *opaque, int n, bool assign)
Justin M. Forbes 272dfe
+{
Justin M. Forbes 272dfe
+    VirtIOPCIProxy *proxy = opaque;
Justin M. Forbes 272dfe
+    VirtQueue *vq = virtio_queue(proxy->vdev, n);
Justin M. Forbes 272dfe
+    EventNotifier *notifier = virtio_queue_host_notifier(vq);
Justin M. Forbes 272dfe
+    int r;
Justin M. Forbes 272dfe
+    if (assign) {
Justin M. Forbes 272dfe
+	r = event_notifier_init(notifier, 1);
Justin M. Forbes 272dfe
+	if (r < 0) {
Justin M. Forbes 272dfe
+		return r;
Justin M. Forbes 272dfe
+        }
Justin M. Forbes 272dfe
+        r = kvm_set_ioeventfd(proxy->addr + VIRTIO_PCI_QUEUE_NOTIFY,
Justin M. Forbes 272dfe
+                              n, event_notifier_get_fd(notifier),
Justin M. Forbes 272dfe
+                              assign);
Justin M. Forbes 272dfe
+        if (r < 0) {
Justin M. Forbes 272dfe
+            event_notifier_cleanup(notifier);
Justin M. Forbes 272dfe
+        }
Justin M. Forbes 272dfe
+    } else {
Justin M. Forbes 272dfe
+        r = kvm_set_ioeventfd(proxy->addr + VIRTIO_PCI_QUEUE_NOTIFY,
Justin M. Forbes 272dfe
+                              n, event_notifier_get_fd(notifier),
Justin M. Forbes 272dfe
+                              assign);
Justin M. Forbes 272dfe
+	if (r < 0) {
Justin M. Forbes 272dfe
+		return r;
Justin M. Forbes 272dfe
+        }
Justin M. Forbes 272dfe
+        event_notifier_cleanup(notifier);
Justin M. Forbes 272dfe
+    }
Justin M. Forbes 272dfe
+    return r;
Justin M. Forbes 272dfe
+}
Justin M. Forbes 272dfe
+
Justin M. Forbes 272dfe
 static const VirtIOBindings virtio_pci_bindings = {
Justin M. Forbes 272dfe
     .notify = virtio_pci_notify,
Justin M. Forbes 272dfe
     .save_config = virtio_pci_save_config,
Justin M. Forbes 272dfe
@@ -401,6 +461,8 @@ static const VirtIOBindings virtio_pci_bindings = {
Justin M. Forbes 272dfe
     .save_queue = virtio_pci_save_queue,
Justin M. Forbes 272dfe
     .load_queue = virtio_pci_load_queue,
Justin M. Forbes 272dfe
     .get_features = virtio_pci_get_features,
Justin M. Forbes 272dfe
+    .host_notifier = virtio_pci_host_notifier,
Justin M. Forbes 272dfe
+    .guest_notifier = virtio_pci_guest_notifier,
Justin M. Forbes 272dfe
 };
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
 static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev,
Justin M. Forbes 272dfe
-- 
Justin M. Forbes 272dfe
1.6.6.144.g5c3af