Commit 4545c6a3 authored by Marc Zyngier's avatar Marc Zyngier

powerpc/msi: Fix deassociation of MSI descriptors

Since 2f2940d1 ("genirq/msi: Remove filter from
msi_free_descs_free_range()"), the core MSI code relies on the
msi_desc->irq field to have been cleared before the descriptor
can be freed, as it indicates that there is no association with
a device anymore.

The irq domain code provides this guarantee, and so does s390,
which is one of the two architectures not using irq domains for
MSIs.

Powerpc, however, is missing this particular requirements,
leading in a splat and leaked MSI descriptors.

Adding the now required irq reset to the handful of powerpc backends
that implement MSIs fixes that particular problem.
Reported-by: default avatarGuenter Roeck <linux@roeck-us.net>
Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/70dab88e-6119-0c12-7c6a-61bcbe239f66@roeck-us.net
parent e982ad82
...@@ -115,6 +115,7 @@ static void hsta_teardown_msi_irqs(struct pci_dev *dev) ...@@ -115,6 +115,7 @@ static void hsta_teardown_msi_irqs(struct pci_dev *dev)
msi_bitmap_free_hwirqs(&ppc4xx_hsta_msi.bmp, irq, 1); msi_bitmap_free_hwirqs(&ppc4xx_hsta_msi.bmp, irq, 1);
pr_debug("%s: Teardown IRQ %u (index %u)\n", __func__, pr_debug("%s: Teardown IRQ %u (index %u)\n", __func__,
entry->irq, irq); entry->irq, irq);
entry->irq = 0;
} }
} }
......
...@@ -289,6 +289,7 @@ static void axon_msi_teardown_msi_irqs(struct pci_dev *dev) ...@@ -289,6 +289,7 @@ static void axon_msi_teardown_msi_irqs(struct pci_dev *dev)
msi_for_each_desc(entry, &dev->dev, MSI_DESC_ASSOCIATED) { msi_for_each_desc(entry, &dev->dev, MSI_DESC_ASSOCIATED) {
irq_set_msi_desc(entry->irq, NULL); irq_set_msi_desc(entry->irq, NULL);
irq_dispose_mapping(entry->irq); irq_dispose_mapping(entry->irq);
entry->irq = 0;
} }
} }
......
...@@ -66,6 +66,7 @@ static void pasemi_msi_teardown_msi_irqs(struct pci_dev *pdev) ...@@ -66,6 +66,7 @@ static void pasemi_msi_teardown_msi_irqs(struct pci_dev *pdev)
hwirq = virq_to_hw(entry->irq); hwirq = virq_to_hw(entry->irq);
irq_set_msi_desc(entry->irq, NULL); irq_set_msi_desc(entry->irq, NULL);
irq_dispose_mapping(entry->irq); irq_dispose_mapping(entry->irq);
entry->irq = 0;
msi_bitmap_free_hwirqs(&msi_mpic->msi_bitmap, hwirq, ALLOC_CHUNK); msi_bitmap_free_hwirqs(&msi_mpic->msi_bitmap, hwirq, ALLOC_CHUNK);
} }
} }
......
...@@ -132,6 +132,7 @@ static void fsl_teardown_msi_irqs(struct pci_dev *pdev) ...@@ -132,6 +132,7 @@ static void fsl_teardown_msi_irqs(struct pci_dev *pdev)
msi_data = irq_get_chip_data(entry->irq); msi_data = irq_get_chip_data(entry->irq);
irq_set_msi_desc(entry->irq, NULL); irq_set_msi_desc(entry->irq, NULL);
irq_dispose_mapping(entry->irq); irq_dispose_mapping(entry->irq);
entry->irq = 0;
msi_bitmap_free_hwirqs(&msi_data->bitmap, hwirq, 1); msi_bitmap_free_hwirqs(&msi_data->bitmap, hwirq, 1);
} }
} }
......
...@@ -108,6 +108,7 @@ static void u3msi_teardown_msi_irqs(struct pci_dev *pdev) ...@@ -108,6 +108,7 @@ static void u3msi_teardown_msi_irqs(struct pci_dev *pdev)
hwirq = virq_to_hw(entry->irq); hwirq = virq_to_hw(entry->irq);
irq_set_msi_desc(entry->irq, NULL); irq_set_msi_desc(entry->irq, NULL);
irq_dispose_mapping(entry->irq); irq_dispose_mapping(entry->irq);
entry->irq = 0;
msi_bitmap_free_hwirqs(&msi_mpic->msi_bitmap, hwirq, 1); msi_bitmap_free_hwirqs(&msi_mpic->msi_bitmap, hwirq, 1);
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment