Register dummy interrupt handlers for DMA datagrams in preparation for
DMA datagram receive operations.

Reviewed-by: Vishnu Dasa <vd...@vmware.com>
Signed-off-by: Jorgen Hansen <jhan...@vmware.com>
---
 drivers/misc/vmw_vmci/vmci_guest.c | 42 +++++++++++++++++++++++++++---
 include/linux/vmw_vmci_defs.h      | 14 ++++++++--
 2 files changed, 51 insertions(+), 5 deletions(-)

diff --git a/drivers/misc/vmw_vmci/vmci_guest.c 
b/drivers/misc/vmw_vmci/vmci_guest.c
index ced187e7ac08..acef19c562b3 100644
--- a/drivers/misc/vmw_vmci/vmci_guest.c
+++ b/drivers/misc/vmw_vmci/vmci_guest.c
@@ -414,6 +414,9 @@ static irqreturn_t vmci_interrupt(int irq, void *_dev)
                        icr &= ~VMCI_ICR_NOTIFICATION;
                }
 
+               if (icr & VMCI_ICR_DMA_DATAGRAM)
+                       icr &= ~VMCI_ICR_DMA_DATAGRAM;
+
                if (icr != 0)
                        dev_warn(dev->dev,
                                 "Ignoring unknown interrupt cause (%d)\n",
@@ -438,6 +441,16 @@ static irqreturn_t vmci_interrupt_bm(int irq, void *_dev)
        return IRQ_HANDLED;
 }
 
+/*
+ * Interrupt handler for MSI-X interrupt vector VMCI_INTR_DMA_DATAGRAM,
+ * which is for the completion of a DMA datagram send or receive operation.
+ * Will only get called if we are using MSI-X with exclusive vectors.
+ */
+static irqreturn_t vmci_interrupt_dma_datagram(int irq, void *_dev)
+{
+       return IRQ_HANDLED;
+}
+
 /*
  * Most of the initialization at module load time is done here.
  */
@@ -447,6 +460,7 @@ static int vmci_guest_probe_device(struct pci_dev *pdev,
        struct vmci_guest_device *vmci_dev;
        void __iomem *iobase = NULL;
        void __iomem *mmio_base = NULL;
+       unsigned int num_irq_vectors;
        unsigned int capabilities;
        unsigned int caps_in_use;
        unsigned long cmd;
@@ -627,8 +641,12 @@ static int vmci_guest_probe_device(struct pci_dev *pdev,
         * Enable interrupts.  Try MSI-X first, then MSI, and then fallback on
         * legacy interrupts.
         */
-       error = pci_alloc_irq_vectors(pdev, VMCI_MAX_INTRS, VMCI_MAX_INTRS,
-                       PCI_IRQ_MSIX);
+       if (vmci_dev->mmio_base != NULL)
+               num_irq_vectors = VMCI_MAX_INTRS;
+       else
+               num_irq_vectors = VMCI_MAX_INTRS_NOTIFICATION;
+       error = pci_alloc_irq_vectors(pdev, num_irq_vectors, num_irq_vectors,
+                                     PCI_IRQ_MSIX);
        if (error < 0) {
                error = pci_alloc_irq_vectors(pdev, 1, 1,
                                PCI_IRQ_MSIX | PCI_IRQ_MSI | PCI_IRQ_LEGACY);
@@ -666,6 +684,17 @@ static int vmci_guest_probe_device(struct pci_dev *pdev,
                                pci_irq_vector(pdev, 1), error);
                        goto err_free_irq;
                }
+               if (caps_in_use & VMCI_CAPS_DMA_DATAGRAM) {
+                       error = request_irq(pci_irq_vector(pdev, 2),
+                                           vmci_interrupt_dma_datagram,
+                                           0, KBUILD_MODNAME, vmci_dev);
+                       if (error) {
+                               dev_err(&pdev->dev,
+                                       "Failed to allocate irq %u: %d\n",
+                                       pci_irq_vector(pdev, 2), error);
+                               goto err_free_bm_irq;
+                       }
+               }
        }
 
        dev_dbg(&pdev->dev, "Registered device\n");
@@ -676,6 +705,8 @@ static int vmci_guest_probe_device(struct pci_dev *pdev,
        cmd = VMCI_IMR_DATAGRAM;
        if (caps_in_use & VMCI_CAPS_NOTIFICATIONS)
                cmd |= VMCI_IMR_NOTIFICATION;
+       if (caps_in_use & VMCI_CAPS_DMA_DATAGRAM)
+               cmd |= VMCI_IMR_DMA_DATAGRAM;
        vmci_write_reg(vmci_dev, cmd, VMCI_IMR_ADDR);
 
        /* Enable interrupts. */
@@ -686,6 +717,8 @@ static int vmci_guest_probe_device(struct pci_dev *pdev,
        vmci_call_vsock_callback(false);
        return 0;
 
+err_free_bm_irq:
+       free_irq(pci_irq_vector(pdev, 1), vmci_dev);
 err_free_irq:
        free_irq(pci_irq_vector(pdev, 0), vmci_dev);
        tasklet_kill(&vmci_dev->datagram_tasklet);
@@ -751,8 +784,11 @@ static void vmci_guest_remove_device(struct pci_dev *pdev)
         * MSI-X, we might have multiple vectors, each with their own
         * IRQ, which we must free too.
         */
-       if (vmci_dev->exclusive_vectors)
+       if (vmci_dev->exclusive_vectors) {
                free_irq(pci_irq_vector(pdev, 1), vmci_dev);
+               if (vmci_dev->mmio_base != NULL)
+                       free_irq(pci_irq_vector(pdev, 2), vmci_dev);
+       }
        free_irq(pci_irq_vector(pdev, 0), vmci_dev);
        pci_free_irq_vectors(pdev);
 
diff --git a/include/linux/vmw_vmci_defs.h b/include/linux/vmw_vmci_defs.h
index 4167779469fd..2b70c024dacb 100644
--- a/include/linux/vmw_vmci_defs.h
+++ b/include/linux/vmw_vmci_defs.h
@@ -45,13 +45,22 @@
 /* Interrupt Cause register bits. */
 #define VMCI_ICR_DATAGRAM      BIT(0)
 #define VMCI_ICR_NOTIFICATION  BIT(1)
+#define VMCI_ICR_DMA_DATAGRAM  BIT(2)
 
 /* Interrupt Mask register bits. */
 #define VMCI_IMR_DATAGRAM      BIT(0)
 #define VMCI_IMR_NOTIFICATION  BIT(1)
+#define VMCI_IMR_DMA_DATAGRAM  BIT(2)
 
-/* Maximum MSI/MSI-X interrupt vectors in the device. */
-#define VMCI_MAX_INTRS 2
+/*
+ * Maximum MSI/MSI-X interrupt vectors in the device.
+ * If VMCI_CAPS_DMA_DATAGRAM is supported by the device,
+ * VMCI_MAX_INTRS_DMA_DATAGRAM vectors are available,
+ * otherwise only VMCI_MAX_INTRS_NOTIFICATION.
+ */
+#define VMCI_MAX_INTRS_NOTIFICATION 2
+#define VMCI_MAX_INTRS_DMA_DATAGRAM 3
+#define VMCI_MAX_INTRS              VMCI_MAX_INTRS_DMA_DATAGRAM
 
 /*
  * Supported interrupt vectors.  There is one for each ICR value above,
@@ -60,6 +69,7 @@
 enum {
        VMCI_INTR_DATAGRAM = 0,
        VMCI_INTR_NOTIFICATION = 1,
+       VMCI_INTR_DMA_DATAGRAM = 2,
 };
 
 /*
-- 
2.25.1

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

Reply via email to