Unmapping the MSIX base mapping in the loops which allocate/free MSI
desciptors is daft and in the way of allowing runtime expansion of MSI-X
descriptors.

Store the mapping in struct pci_dev and free it after freeing the MSI-X
descriptors.

Signed-off-by: Thomas Gleixner <t...@linutronix.de>
---
 drivers/pci/msi/msi.c |   18 ++++++++----------
 include/linux/pci.h   |    1 +
 2 files changed, 9 insertions(+), 10 deletions(-)

--- a/drivers/pci/msi/msi.c
+++ b/drivers/pci/msi/msi.c
@@ -241,14 +241,14 @@ static void free_msi_irqs(struct pci_dev
        pci_msi_teardown_msi_irqs(dev);
 
        list_for_each_entry_safe(entry, tmp, msi_list, list) {
-               if (entry->pci.msi_attrib.is_msix) {
-                       if (list_is_last(&entry->list, msi_list))
-                               iounmap(entry->pci.mask_base);
-               }
-
                list_del(&entry->list);
                free_msi_entry(entry);
        }
+
+       if (dev->msix_base) {
+               iounmap(dev->msix_base);
+               dev->msix_base = NULL;
+       }
 }
 
 static void pci_intx_for_msi(struct pci_dev *dev, int enable)
@@ -501,10 +501,6 @@ static int msix_setup_entries(struct pci
        for (i = 0, curmsk = masks; i < nvec; i++) {
                entry = alloc_msi_entry(&dev->dev, 1, curmsk);
                if (!entry) {
-                       if (!i)
-                               iounmap(base);
-                       else
-                               free_msi_irqs(dev);
                        /* No enough memory. Don't try again */
                        ret = -ENOMEM;
                        goto out;
@@ -602,12 +598,14 @@ static int msix_capability_init(struct p
                goto out_disable;
        }
 
+       dev->msix_base = base;
+
        /* Ensure that all table entries are masked. */
        msix_mask_all(base, tsize);
 
        ret = msix_setup_entries(dev, base, entries, nvec, affd);
        if (ret)
-               goto out_disable;
+               goto out_free;
 
        ret = pci_msi_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSIX);
        if (ret)
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -473,6 +473,7 @@ struct pci_dev {
        u8              ptm_granularity;
 #endif
 #ifdef CONFIG_PCI_MSI
+       void __iomem    *msix_base;
        const struct attribute_group **msi_irq_groups;
 #endif
        struct pci_vpd  vpd;

Reply via email to