Blame qemu-msix-add-mask-unmask-notifiers.patch

Justin M. Forbes 272dfe
Support per-vector callbacks for msix mask/unmask.
Justin M. Forbes 272dfe
Will be used for vhost net.
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/msix.c |   36 +++++++++++++++++++++++++++++++++++-
Justin M. Forbes 272dfe
 hw/msix.h |    1 +
Justin M. Forbes 272dfe
 hw/pci.h  |    6 ++++++
Justin M. Forbes 272dfe
 3 files changed, 42 insertions(+), 1 deletions(-)
Justin M. Forbes 272dfe
Justin M. Forbes 272dfe
diff --git a/hw/msix.c b/hw/msix.c
Justin M. Forbes 272dfe
index d117bcf..3fcf3a1 100644
Justin M. Forbes 272dfe
--- a/hw/msix.c
Justin M. Forbes 272dfe
+++ b/hw/msix.c
Justin M. Forbes 272dfe
@@ -318,6 +318,13 @@ static void msix_mmio_writel(void *opaque, target_phys_addr_t addr,
Justin M. Forbes 272dfe
     if (kvm_enabled() && kvm_irqchip_in_kernel()) {
Justin M. Forbes 272dfe
         kvm_msix_update(dev, vector, was_masked, msix_is_masked(dev, vector));
Justin M. Forbes 272dfe
     }
Justin M. Forbes 272dfe
+    if (was_masked != msix_is_masked(dev, vector) &&
Justin M. Forbes 272dfe
+        dev->msix_mask_notifier && dev->msix_mask_notifier_opaque[vector]) {
Justin M. Forbes 272dfe
+        int r = dev->msix_mask_notifier(dev, vector,
Justin M. Forbes 272dfe
+					dev->msix_mask_notifier_opaque[vector],
Justin M. Forbes 272dfe
+					msix_is_masked(dev, vector));
Justin M. Forbes 272dfe
+        assert(r >= 0);
Justin M. Forbes 272dfe
+    }
Justin M. Forbes 272dfe
     msix_handle_mask_update(dev, vector);
Justin M. Forbes 272dfe
 }
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
@@ -356,10 +363,18 @@ void msix_mmio_map(PCIDevice *d, int region_num,
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
 static void msix_mask_all(struct PCIDevice *dev, unsigned nentries)
Justin M. Forbes 272dfe
 {
Justin M. Forbes 272dfe
-    int vector;
Justin M. Forbes 272dfe
+    int vector, r;
Justin M. Forbes 272dfe
     for (vector = 0; vector < nentries; ++vector) {
Justin M. Forbes 272dfe
         unsigned offset = vector * MSIX_ENTRY_SIZE + MSIX_VECTOR_CTRL;
Justin M. Forbes 272dfe
+        int was_masked = msix_is_masked(dev, vector);
Justin M. Forbes 272dfe
         dev->msix_table_page[offset] |= MSIX_VECTOR_MASK;
Justin M. Forbes 272dfe
+        if (was_masked != msix_is_masked(dev, vector) &&
Justin M. Forbes 272dfe
+            dev->msix_mask_notifier && dev->msix_mask_notifier_opaque[vector]) {
Justin M. Forbes 272dfe
+            r = dev->msix_mask_notifier(dev, vector,
Justin M. Forbes 272dfe
+                                        dev->msix_mask_notifier_opaque[vector],
Justin M. Forbes 272dfe
+                                        msix_is_masked(dev, vector));
Justin M. Forbes 272dfe
+            assert(r >= 0);
Justin M. Forbes 272dfe
+        }
Justin M. Forbes 272dfe
     }
Justin M. Forbes 272dfe
 }
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
@@ -382,6 +397,9 @@ int msix_init(struct PCIDevice *dev, unsigned short nentries,
Justin M. Forbes 272dfe
                                             sizeof *dev->msix_irq_entries);
Justin M. Forbes 272dfe
     }
Justin M. Forbes 272dfe
 #endif
Justin M. Forbes 272dfe
+    dev->msix_mask_notifier_opaque =
Justin M. Forbes 272dfe
+        qemu_mallocz(nentries * sizeof *dev->msix_mask_notifier_opaque);
Justin M. Forbes 272dfe
+    dev->msix_mask_notifier = NULL;
Justin M. Forbes 272dfe
     dev->msix_entry_used = qemu_mallocz(MSIX_MAX_ENTRIES *
Justin M. Forbes 272dfe
                                         sizeof *dev->msix_entry_used);
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
@@ -444,6 +462,8 @@ int msix_uninit(PCIDevice *dev)
Justin M. Forbes 272dfe
     dev->msix_entry_used = NULL;
Justin M. Forbes 272dfe
     qemu_free(dev->msix_irq_entries);
Justin M. Forbes 272dfe
     dev->msix_irq_entries = NULL;
Justin M. Forbes 272dfe
+    qemu_free(dev->msix_mask_notifier_opaque);
Justin M. Forbes 272dfe
+    dev->msix_mask_notifier_opaque = NULL;
Justin M. Forbes 272dfe
     dev->cap_present &= ~QEMU_PCI_CAP_MSIX;
Justin M. Forbes 272dfe
     return 0;
Justin M. Forbes 272dfe
 }
Justin M. Forbes 272dfe
@@ -587,3 +607,17 @@ void msix_unuse_all_vectors(PCIDevice *dev)
Justin M. Forbes 272dfe
         return;
Justin M. Forbes 272dfe
     msix_free_irq_entries(dev);
Justin M. Forbes 272dfe
 }
Justin M. Forbes 272dfe
+
Justin M. Forbes 272dfe
+int msix_set_mask_notifier(PCIDevice *dev, unsigned vector, void *opaque)
Justin M. Forbes 272dfe
+{
Justin M. Forbes 272dfe
+    int r = 0;
Justin M. Forbes 272dfe
+    if (vector >= dev->msix_entries_nr || !dev->msix_entry_used[vector])
Justin M. Forbes 272dfe
+        return 0;
Justin M. Forbes 272dfe
+
Justin M. Forbes 272dfe
+    if (dev->msix_mask_notifier)
Justin M. Forbes 272dfe
+        r = dev->msix_mask_notifier(dev, vector, opaque,
Justin M. Forbes 272dfe
+                                    msix_is_masked(dev, vector));
Justin M. Forbes 272dfe
+    if (r >= 0)
Justin M. Forbes 272dfe
+        dev->msix_mask_notifier_opaque[vector] = opaque;
Justin M. Forbes 272dfe
+    return r;
Justin M. Forbes 272dfe
+}
Justin M. Forbes 272dfe
diff --git a/hw/msix.h b/hw/msix.h
Justin M. Forbes 272dfe
index a9f7993..f167231 100644
Justin M. Forbes 272dfe
--- a/hw/msix.h
Justin M. Forbes 272dfe
+++ b/hw/msix.h
Justin M. Forbes 272dfe
@@ -33,4 +33,5 @@ void msix_reset(PCIDevice *dev);
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
 extern int msix_supported;
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
+int msix_set_mask_notifier(PCIDevice *dev, unsigned vector, void *opaque);
Justin M. Forbes 272dfe
 #endif
Justin M. Forbes 272dfe
diff --git a/hw/pci.h b/hw/pci.h
Justin M. Forbes 272dfe
index a225a6a..bf722ca 100644
Justin M. Forbes 272dfe
--- a/hw/pci.h
Justin M. Forbes 272dfe
+++ b/hw/pci.h
Justin M. Forbes 272dfe
@@ -217,6 +217,9 @@ enum {
Justin M. Forbes 272dfe
 #define PCI_CAPABILITY_CONFIG_MSI_LENGTH 0x10
Justin M. Forbes 272dfe
 #define PCI_CAPABILITY_CONFIG_MSIX_LENGTH 0x10
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
+typedef int (*msix_mask_notifier_func)(PCIDevice *, unsigned vector,
Justin M. Forbes 272dfe
+				       void *opaque, int masked);
Justin M. Forbes 272dfe
+
Justin M. Forbes 272dfe
 struct PCIDevice {
Justin M. Forbes 272dfe
     DeviceState qdev;
Justin M. Forbes 272dfe
     /* PCI config space */
Justin M. Forbes 272dfe
@@ -282,6 +285,9 @@ struct PCIDevice {
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
     struct kvm_irq_routing_entry *msix_irq_entries;
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
+    void **msix_mask_notifier_opaque;
Justin M. Forbes 272dfe
+    msix_mask_notifier_func msix_mask_notifier;
Justin M. Forbes 272dfe
+
Justin M. Forbes 272dfe
     /* Device capability configuration space */
Justin M. Forbes 272dfe
     struct {
Justin M. Forbes 272dfe
         int supported;
Justin M. Forbes 272dfe
-- 
Justin M. Forbes 272dfe
1.6.6.144.g5c3af