[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20201014182811.12027-1-cai@lca.pw>
Date: Wed, 14 Oct 2020 14:28:11 -0400
From: Qian Cai <cai@....pw>
To: Michael Ellerman <mpe@...erman.id.au>
Cc: Cédric Le Goater <clg@...d.org>,
Stephen Rothwell <sfr@...b.auug.org.au>,
Alexey Kardashevskiy <aik@...abs.ru>,
Oliver O'Halloran <oohall@...il.com>,
linux-kernel@...r.kernel.org, linux-next@...r.kernel.org,
linuxppc-dev@...ts.ozlabs.org
Subject: [PATCH -next] Revert "powerpc/pci: unmap legacy INTx interrupts when a PHB is removed"
This reverts commit 3a3181e16fbde752007759f8759d25e0ff1fc425 which
causes memory corruptions on POWER9 NV.
Signed-off-by: Qian Cai <cai@....pw>
---
arch/powerpc/include/asm/pci-bridge.h | 6 --
arch/powerpc/kernel/pci-common.c | 114 --------------------------
2 files changed, 120 deletions(-)
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
index d21e070352dc..d2a2a14e56f9 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -48,9 +48,6 @@ struct pci_controller_ops {
/*
* Structure of a PCI controller (host bridge)
- *
- * @irq_count: number of interrupt mappings
- * @irq_map: interrupt mappings
*/
struct pci_controller {
struct pci_bus *bus;
@@ -130,9 +127,6 @@ struct pci_controller {
void *private_data;
struct npu *npu;
-
- unsigned int irq_count;
- unsigned int *irq_map;
};
/* These are used for config access before all the PCI probing
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index deb831f0ae13..be108616a721 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -353,115 +353,6 @@ struct pci_controller *pci_find_controller_for_domain(int domain_nr)
return NULL;
}
-/*
- * Assumption is made on the interrupt parent. All interrupt-map
- * entries are considered to have the same parent.
- */
-static int pcibios_irq_map_count(struct pci_controller *phb)
-{
- const __be32 *imap;
- int imaplen;
- struct device_node *parent;
- u32 intsize, addrsize, parintsize, paraddrsize;
-
- if (of_property_read_u32(phb->dn, "#interrupt-cells", &intsize))
- return 0;
- if (of_property_read_u32(phb->dn, "#address-cells", &addrsize))
- return 0;
-
- imap = of_get_property(phb->dn, "interrupt-map", &imaplen);
- if (!imap) {
- pr_debug("%pOF : no interrupt-map\n", phb->dn);
- return 0;
- }
- imaplen /= sizeof(u32);
- pr_debug("%pOF : imaplen=%d\n", phb->dn, imaplen);
-
- if (imaplen < (addrsize + intsize + 1))
- return 0;
-
- imap += intsize + addrsize;
- parent = of_find_node_by_phandle(be32_to_cpup(imap));
- if (!parent) {
- pr_debug("%pOF : no imap parent found !\n", phb->dn);
- return 0;
- }
-
- if (of_property_read_u32(parent, "#interrupt-cells", &parintsize)) {
- pr_debug("%pOF : parent lacks #interrupt-cells!\n", phb->dn);
- return 0;
- }
-
- if (of_property_read_u32(parent, "#address-cells", ¶ddrsize))
- paraddrsize = 0;
-
- return imaplen / (addrsize + intsize + 1 + paraddrsize + parintsize);
-}
-
-static void pcibios_irq_map_init(struct pci_controller *phb)
-{
- phb->irq_count = pcibios_irq_map_count(phb);
- if (phb->irq_count < PCI_NUM_INTX)
- phb->irq_count = PCI_NUM_INTX;
-
- pr_debug("%pOF : interrupt map #%d\n", phb->dn, phb->irq_count);
-
- phb->irq_map = kcalloc(phb->irq_count, sizeof(unsigned int),
- GFP_KERNEL);
-}
-
-static void pci_irq_map_register(struct pci_dev *pdev, unsigned int virq)
-{
- struct pci_controller *phb = pci_bus_to_host(pdev->bus);
- int i;
-
- if (!phb->irq_map)
- return;
-
- for (i = 0; i < phb->irq_count; i++) {
- /*
- * Look for an empty or an equivalent slot, as INTx
- * interrupts can be shared between adapters.
- */
- if (phb->irq_map[i] == virq || !phb->irq_map[i]) {
- phb->irq_map[i] = virq;
- break;
- }
- }
-
- if (i == phb->irq_count)
- pr_err("PCI:%s all platform interrupts mapped\n",
- pci_name(pdev));
-}
-
-/*
- * Clearing the mapped interrupts will also clear the underlying
- * mappings of the ESB pages of the interrupts when under XIVE. It is
- * a requirement of PowerVM to clear all memory mappings before
- * removing a PHB.
- */
-static void pci_irq_map_dispose(struct pci_bus *bus)
-{
- struct pci_controller *phb = pci_bus_to_host(bus);
- int i;
-
- if (!phb->irq_map)
- return;
-
- pr_debug("PCI: Clearing interrupt mappings for PHB %04x:%02x...\n",
- pci_domain_nr(bus), bus->number);
- for (i = 0; i < phb->irq_count; i++)
- irq_dispose_mapping(phb->irq_map[i]);
-
- kfree(phb->irq_map);
-}
-
-void pcibios_remove_bus(struct pci_bus *bus)
-{
- pci_irq_map_dispose(bus);
-}
-EXPORT_SYMBOL_GPL(pcibios_remove_bus);
-
/*
* Reads the interrupt pin to determine if interrupt is use by card.
* If the interrupt is used, then gets the interrupt line from the
@@ -510,8 +401,6 @@ static int pci_read_irq_line(struct pci_dev *pci_dev)
pci_dev->irq = virq;
- /* Record all interrut mappings for later removal of a PHB */
- pci_irq_map_register(pci_dev, virq);
return 0;
}
@@ -1665,9 +1554,6 @@ void pcibios_scan_phb(struct pci_controller *hose)
pr_debug("PCI: Scanning PHB %pOF\n", node);
- /* Allocate interrupt mappings array */
- pcibios_irq_map_init(hose);
-
/* Get some IO space for the new PHB */
pcibios_setup_phb_io_space(hose);
--
2.28.0
Powered by blists - more mailing lists