[PATCH 11/17] vfio/pci: Perform MSI/MSI-X interrupt management via callbacks

From: Reinette Chatre
Date: Fri Feb 02 2024 - 00:00:32 EST


vfio_msi_set_vector_signal() is specific to MSI and MSI-X interrupt
management but its flow is the same as vfio_intx_set_signal() that
manages the INTx interrupts.

Replace the MSI and MSI-X specific calls with callbacks in preparation
for vfio_msi_set_vector_signal() to manage INTx interrupts also.

In preparation for support of INTx only the IRQ bypass code is
made optional.

Signed-off-by: Reinette Chatre <reinette.chatre@xxxxxxxxx>
---
Note to maintainers:
This change resembles "vfio/pci: Replace backend specific calls with
callbacks" that formed part of the IMS submission, but is not
specific to IMS.
https://lore.kernel.org/lkml/cover.1696609476.git.reinette.chatre@xxxxxxxxx

drivers/vfio/pci/vfio_pci_intrs.c | 44 +++++++++++++++++++++++++++----
1 file changed, 39 insertions(+), 5 deletions(-)

diff --git a/drivers/vfio/pci/vfio_pci_intrs.c b/drivers/vfio/pci/vfio_pci_intrs.c
index 6eef4e2d7c13..07dc388c4513 100644
--- a/drivers/vfio/pci/vfio_pci_intrs.c
+++ b/drivers/vfio/pci/vfio_pci_intrs.c
@@ -31,6 +31,21 @@ struct vfio_pci_irq_ctx {
struct irq_bypass_producer producer;
};

+struct vfio_pci_intr_ops {
+ int (*request_interrupt)(struct vfio_pci_core_device *vdev,
+ struct vfio_pci_irq_ctx *ctx,
+ unsigned int vector, unsigned int index);
+ void (*free_interrupt)(struct vfio_pci_core_device *vdev,
+ struct vfio_pci_irq_ctx *ctx,
+ unsigned int vector);
+ char *(*device_name)(struct vfio_pci_core_device *vdev,
+ unsigned int vector, unsigned int index);
+ void (*register_producer)(struct vfio_pci_core_device *vdev,
+ struct vfio_pci_irq_ctx *ctx,
+ unsigned int vector);
+ void (*unregister_producer)(struct vfio_pci_irq_ctx *ctx);
+};
+
static bool irq_is(struct vfio_pci_core_device *vdev, int type)
{
return vdev->irq_type == type;
@@ -525,6 +540,23 @@ static void vfio_msi_unregister_producer(struct vfio_pci_irq_ctx *ctx)
irq_bypass_unregister_producer(&ctx->producer);
}

+static struct vfio_pci_intr_ops intr_ops[] = {
+ [VFIO_PCI_MSI_IRQ_INDEX] = {
+ .request_interrupt = vfio_msi_request_interrupt,
+ .free_interrupt = vfio_msi_free_interrupt,
+ .device_name = vfio_msi_device_name,
+ .register_producer = vfio_msi_register_producer,
+ .unregister_producer = vfio_msi_unregister_producer,
+ },
+ [VFIO_PCI_MSIX_IRQ_INDEX] = {
+ .request_interrupt = vfio_msi_request_interrupt,
+ .free_interrupt = vfio_msi_free_interrupt,
+ .device_name = vfio_msi_device_name,
+ .register_producer = vfio_msi_register_producer,
+ .unregister_producer = vfio_msi_unregister_producer,
+ },
+};
+
static int vfio_msi_set_vector_signal(struct vfio_pci_core_device *vdev,
unsigned int vector, int fd,
unsigned int index)
@@ -536,8 +568,9 @@ static int vfio_msi_set_vector_signal(struct vfio_pci_core_device *vdev,
ctx = vfio_irq_ctx_get(vdev, vector);

if (ctx && ctx->trigger) {
- vfio_msi_unregister_producer(ctx);
- vfio_msi_free_interrupt(vdev, ctx, vector);
+ if (intr_ops[index].unregister_producer)
+ intr_ops[index].unregister_producer(ctx);
+ intr_ops[index].free_interrupt(vdev, ctx, vector);
kfree(ctx->name);
ctx->name = NULL;
eventfd_ctx_put(ctx->trigger);
@@ -554,7 +587,7 @@ static int vfio_msi_set_vector_signal(struct vfio_pci_core_device *vdev,
return -ENOMEM;
}

- ctx->name = vfio_msi_device_name(vdev, vector, index);
+ ctx->name = intr_ops[index].device_name(vdev, vector, index);
if (!ctx->name)
return -ENOMEM;

@@ -566,11 +599,12 @@ static int vfio_msi_set_vector_signal(struct vfio_pci_core_device *vdev,

ctx->trigger = trigger;

- ret = vfio_msi_request_interrupt(vdev, ctx, vector, index);
+ ret = intr_ops[index].request_interrupt(vdev, ctx, vector, index);
if (ret)
goto out_put_eventfd_ctx;

- vfio_msi_register_producer(vdev, ctx, vector);
+ if (intr_ops[index].register_producer)
+ intr_ops[index].register_producer(vdev, ctx, vector);

return 0;

--
2.34.1