]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
VMCI: dma dg: register dummy IRQ handlers for DMA datagrams
authorJorgen Hansen <jhansen@vmware.com>
Tue, 14 Jun 2022 19:06:10 +0000 (13:06 -0600)
committerStefan Bader <stefan.bader@canonical.com>
Wed, 22 Jun 2022 12:41:23 +0000 (14:41 +0200)
BugLink: https://bugs.launchpad.net/bugs/1978145
Register dummy interrupt handlers for DMA datagrams in preparation for
DMA datagram receive operations.

Reviewed-by: Vishnu Dasa <vdasa@vmware.com>
Signed-off-by: Jorgen Hansen <jhansen@vmware.com>
Link: https://lore.kernel.org/r/20220207102725.2742-6-jhansen@vmware.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
(cherry picked from commit cc68f2177fcbfe2dbe5e9514789b96ba5995ec1e)
Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
Acked-by: Khaled Elmously <khalid.elmously@canonical.com>
Acked-by: Cengiz Can <cengiz.can@canonical.com>
Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
drivers/misc/vmw_vmci/vmci_guest.c
include/linux/vmw_vmci_defs.h

index ced187e7ac08bc503906b22703c66df0920d8409..acef19c562b32260b9c50fc4222a7b4b11f70704 100644 (file)
@@ -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);
 
index 4167779469fd1916b29bd0eb49bc1f54f90d0c3a..2b70c024dacb99c2ad20656e68ff0e0c9739d58d 100644 (file)
 /* 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,
 };
 
 /*