Skip to content

Commit ffd0b25

Browse files
Qian Caimpe
authored andcommitted
Revert "powerpc/pci: unmap legacy INTx interrupts when a PHB is removed"
This reverts commit 3a3181e which causes memory corruptions on POWER9 powernv. eg: pci_bus 0035:08: busn_res: [bus 08-0c] is released ============================================================================= BUG kmalloc-16 (Tainted: G W O ): Object already free ----------------------------------------------------------------------------- Disabling lock debugging due to kernel taint INFO: Allocated in pcibios_scan_phb+0x104/0x3e0 age=1960714 cpu=4 pid=1 __slab_alloc+0xa4/0xf0 __kmalloc+0x294/0x330 pcibios_scan_phb+0x104/0x3e0 pcibios_init+0x84/0x124 do_one_initcall+0xac/0x528 kernel_init_freeable+0x35c/0x3fc kernel_init+0x24/0x148 ret_from_kernel_thread+0x5c/0x80 INFO: Freed in pcibios_remove_bus+0x70/0x90 age=0 cpu=16 pid=1717146 kfree+0x49c/0x510 pcibios_remove_bus+0x70/0x90 pci_remove_bus+0xe4/0x110 pci_remove_bus_device+0x74/0x170 pci_remove_bus_device+0x4c/0x170 pci_stop_and_remove_bus_device_locked+0x34/0x50 remove_store+0xc0/0xe0 dev_attr_store+0x30/0x50 sysfs_kf_write+0x68/0xb0 kernfs_fop_write+0x114/0x260 vfs_write+0xe4/0x260 ksys_write+0x74/0x130 system_call_exception+0xf8/0x1d0 system_call_common+0xe8/0x218 INFO: Slab 0x0000000099caaf22 objects=178 used=174 fp=0x00000000006a64b0 flags=0x7fff8000000201 INFO: Object 0x00000000f360132d @offset=30192 fp=0x0000000000000000 Signed-off-by: Qian Cai <[email protected]> Acked-by: Oliver O'Halloran <[email protected]> Signed-off-by: Michael Ellerman <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 996f9e0 commit ffd0b25

File tree

2 files changed

+0
-120
lines changed

2 files changed

+0
-120
lines changed

arch/powerpc/include/asm/pci-bridge.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,6 @@ struct pci_controller_ops {
4848

4949
/*
5050
* Structure of a PCI controller (host bridge)
51-
*
52-
* @irq_count: number of interrupt mappings
53-
* @irq_map: interrupt mappings
5451
*/
5552
struct pci_controller {
5653
struct pci_bus *bus;
@@ -130,9 +127,6 @@ struct pci_controller {
130127

131128
void *private_data;
132129
struct npu *npu;
133-
134-
unsigned int irq_count;
135-
unsigned int *irq_map;
136130
};
137131

138132
/* These are used for config access before all the PCI probing

arch/powerpc/kernel/pci-common.c

Lines changed: 0 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -353,115 +353,6 @@ struct pci_controller *pci_find_controller_for_domain(int domain_nr)
353353
return NULL;
354354
}
355355

356-
/*
357-
* Assumption is made on the interrupt parent. All interrupt-map
358-
* entries are considered to have the same parent.
359-
*/
360-
static int pcibios_irq_map_count(struct pci_controller *phb)
361-
{
362-
const __be32 *imap;
363-
int imaplen;
364-
struct device_node *parent;
365-
u32 intsize, addrsize, parintsize, paraddrsize;
366-
367-
if (of_property_read_u32(phb->dn, "#interrupt-cells", &intsize))
368-
return 0;
369-
if (of_property_read_u32(phb->dn, "#address-cells", &addrsize))
370-
return 0;
371-
372-
imap = of_get_property(phb->dn, "interrupt-map", &imaplen);
373-
if (!imap) {
374-
pr_debug("%pOF : no interrupt-map\n", phb->dn);
375-
return 0;
376-
}
377-
imaplen /= sizeof(u32);
378-
pr_debug("%pOF : imaplen=%d\n", phb->dn, imaplen);
379-
380-
if (imaplen < (addrsize + intsize + 1))
381-
return 0;
382-
383-
imap += intsize + addrsize;
384-
parent = of_find_node_by_phandle(be32_to_cpup(imap));
385-
if (!parent) {
386-
pr_debug("%pOF : no imap parent found !\n", phb->dn);
387-
return 0;
388-
}
389-
390-
if (of_property_read_u32(parent, "#interrupt-cells", &parintsize)) {
391-
pr_debug("%pOF : parent lacks #interrupt-cells!\n", phb->dn);
392-
return 0;
393-
}
394-
395-
if (of_property_read_u32(parent, "#address-cells", &paraddrsize))
396-
paraddrsize = 0;
397-
398-
return imaplen / (addrsize + intsize + 1 + paraddrsize + parintsize);
399-
}
400-
401-
static void pcibios_irq_map_init(struct pci_controller *phb)
402-
{
403-
phb->irq_count = pcibios_irq_map_count(phb);
404-
if (phb->irq_count < PCI_NUM_INTX)
405-
phb->irq_count = PCI_NUM_INTX;
406-
407-
pr_debug("%pOF : interrupt map #%d\n", phb->dn, phb->irq_count);
408-
409-
phb->irq_map = kcalloc(phb->irq_count, sizeof(unsigned int),
410-
GFP_KERNEL);
411-
}
412-
413-
static void pci_irq_map_register(struct pci_dev *pdev, unsigned int virq)
414-
{
415-
struct pci_controller *phb = pci_bus_to_host(pdev->bus);
416-
int i;
417-
418-
if (!phb->irq_map)
419-
return;
420-
421-
for (i = 0; i < phb->irq_count; i++) {
422-
/*
423-
* Look for an empty or an equivalent slot, as INTx
424-
* interrupts can be shared between adapters.
425-
*/
426-
if (phb->irq_map[i] == virq || !phb->irq_map[i]) {
427-
phb->irq_map[i] = virq;
428-
break;
429-
}
430-
}
431-
432-
if (i == phb->irq_count)
433-
pr_err("PCI:%s all platform interrupts mapped\n",
434-
pci_name(pdev));
435-
}
436-
437-
/*
438-
* Clearing the mapped interrupts will also clear the underlying
439-
* mappings of the ESB pages of the interrupts when under XIVE. It is
440-
* a requirement of PowerVM to clear all memory mappings before
441-
* removing a PHB.
442-
*/
443-
static void pci_irq_map_dispose(struct pci_bus *bus)
444-
{
445-
struct pci_controller *phb = pci_bus_to_host(bus);
446-
int i;
447-
448-
if (!phb->irq_map)
449-
return;
450-
451-
pr_debug("PCI: Clearing interrupt mappings for PHB %04x:%02x...\n",
452-
pci_domain_nr(bus), bus->number);
453-
for (i = 0; i < phb->irq_count; i++)
454-
irq_dispose_mapping(phb->irq_map[i]);
455-
456-
kfree(phb->irq_map);
457-
}
458-
459-
void pcibios_remove_bus(struct pci_bus *bus)
460-
{
461-
pci_irq_map_dispose(bus);
462-
}
463-
EXPORT_SYMBOL_GPL(pcibios_remove_bus);
464-
465356
/*
466357
* Reads the interrupt pin to determine if interrupt is use by card.
467358
* 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)
510401

511402
pci_dev->irq = virq;
512403

513-
/* Record all interrut mappings for later removal of a PHB */
514-
pci_irq_map_register(pci_dev, virq);
515404
return 0;
516405
}
517406

@@ -1665,9 +1554,6 @@ void pcibios_scan_phb(struct pci_controller *hose)
16651554

16661555
pr_debug("PCI: Scanning PHB %pOF\n", node);
16671556

1668-
/* Allocate interrupt mappings array */
1669-
pcibios_irq_map_init(hose);
1670-
16711557
/* Get some IO space for the new PHB */
16721558
pcibios_setup_phb_io_space(hose);
16731559

0 commit comments

Comments
 (0)