|
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
|