@@ -46,6 +46,10 @@ struct vfio_pci_intr_ops {
void (*unregister_producer)(struct vfio_pci_irq_ctx *ctx);
};
+static int vfio_irq_set_vector_signal(struct vfio_pci_core_device *vdev,
+ unsigned int vector, int fd,
+ unsigned int index);
+
static bool irq_is(struct vfio_pci_core_device *vdev, int type)
{
return vdev->irq_type == type;
@@ -321,51 +325,6 @@ static char *vfio_intx_device_name(struct vfio_pci_core_device *vdev,
return kasprintf(GFP_KERNEL_ACCOUNT, "vfio-intx(%s)", pci_name(pdev));
}
-static int vfio_intx_set_signal(struct vfio_pci_core_device *vdev,
- unsigned int vector, int fd,
- unsigned int index)
-{
- struct vfio_pci_irq_ctx *ctx;
- struct eventfd_ctx *trigger;
- int ret;
-
- ctx = vfio_irq_ctx_get(vdev, 0);
- if (WARN_ON_ONCE(!ctx))
- return -EINVAL;
-
- if (ctx->trigger) {
- vfio_intx_free_interrupt(vdev, ctx, vector);
- kfree(ctx->name);
- eventfd_ctx_put(ctx->trigger);
- ctx->trigger = NULL;
- }
-
- if (fd < 0) /* Disable only */
- return 0;
-
- ctx->name = vfio_intx_device_name(vdev, vector, index);
- if (!ctx->name)
- return -ENOMEM;
-
- trigger = eventfd_ctx_fdget(fd);
- if (IS_ERR(trigger)) {
- kfree(ctx->name);
- return PTR_ERR(trigger);
- }
-
- ctx->trigger = trigger;
-
- ret = vfio_intx_request_interrupt(vdev, ctx, vector, index);
- if (ret) {
- ctx->trigger = NULL;
- kfree(ctx->name);
- eventfd_ctx_put(trigger);
- return ret;
- }
-
- return 0;
-}
-
static void vfio_intx_disable(struct vfio_pci_core_device *vdev)
{
struct vfio_pci_irq_ctx *ctx;
@@ -376,7 +335,7 @@ static void vfio_intx_disable(struct vfio_pci_core_device *vdev)
vfio_virqfd_disable(&ctx->unmask);
vfio_virqfd_disable(&ctx->mask);
}
- vfio_intx_set_signal(vdev, 0, -1, VFIO_PCI_INTX_IRQ_INDEX);
+ vfio_irq_set_vector_signal(vdev, 0, -1, VFIO_PCI_INTX_IRQ_INDEX);
vdev->irq_type = VFIO_PCI_NUM_IRQS;
vfio_irq_ctx_free(vdev, ctx, 0);
}
@@ -541,6 +500,11 @@ static void vfio_msi_unregister_producer(struct vfio_pci_irq_ctx *ctx)
}
static struct vfio_pci_intr_ops intr_ops[] = {
+ [VFIO_PCI_INTX_IRQ_INDEX] = {
+ .request_interrupt = vfio_intx_request_interrupt,
+ .free_interrupt = vfio_intx_free_interrupt,
+ .device_name = vfio_intx_device_name,
+ },
[VFIO_PCI_MSI_IRQ_INDEX] = {
.request_interrupt = vfio_msi_request_interrupt,
.free_interrupt = vfio_msi_free_interrupt,
@@ -735,17 +699,17 @@ static int vfio_pci_set_intx_trigger(struct vfio_pci_core_device *vdev,
return -EINVAL;
if (flags & VFIO_IRQ_SET_DATA_EVENTFD) {
- int32_t fd = *(int32_t *)data;
+ int32_t *fds = data;
int ret;
if (is_intx(vdev))
- return vfio_intx_set_signal(vdev, start, fd, index);
+ return vfio_irq_set_block(vdev, start, count, fds, index);
ret = vfio_intx_enable(vdev);
if (ret)
return ret;
- ret = vfio_intx_set_signal(vdev, start, fd, index);
+ ret = vfio_irq_set_block(vdev, start, count, fds, index);
if (ret)
vfio_intx_disable(vdev);
The interrupt management flow of vfio_intx_set_signal() is available from the now generic vfio_irq_set_signal(). Initialize the INTx specific management ops so that vfio_irq_set_signal() can be used to manage INTx interrupts and point all existing INTx specific interrupt management calls to vfio_irq_set_signal(). Use vfio_irq_set_block() within vfio_pci_set_intx_trigger() to highlight its similarities with vfio_pci_set_msi_trigger() for the next stage of uniting the interrupt management code. vfio_pci_set_intx_trigger() ensures that start == 0 and count == 1 before vfio_irq_set_block() is called so the loop within it is essentially a direct call to vfio_irq_set_vector_signal(). Signed-off-by: Reinette Chatre <reinette.chatre@intel.com> --- drivers/vfio/pci/vfio_pci_intrs.c | 62 +++++++------------------------ 1 file changed, 13 insertions(+), 49 deletions(-)