summaryrefslogtreecommitdiffstats
path: root/arch/alpha/kernel/sys_eiger.c
diff options
context:
space:
mode:
authorLorenzo Pieralisi <lorenzo.pieralisi@arm.com>2017-10-26 16:54:15 +0200
committerBjorn Helgaas <bhelgaas@google.com>2017-10-26 18:53:38 +0200
commit814eae5982cc55988f642f7f1d10eaf340845c00 (patch)
tree1afd46129232626ca89ef28db5b1cfbf57187432 /arch/alpha/kernel/sys_eiger.c
parentPCI: aardvark: Move to struct pci_host_bridge IRQ mapping functions (diff)
downloadlinux-814eae5982cc55988f642f7f1d10eaf340845c00.tar.xz
linux-814eae5982cc55988f642f7f1d10eaf340845c00.zip
alpha/PCI: Move pci_map_irq()/pci_swizzle() out of initdata
The introduction of {map/swizzle}_irq() hooks in the struct pci_host_bridge allowed to replace the pci_fixup_irqs() PCI IRQ allocation in alpha arch PCI code with per-bridge map/swizzle functions with commit 0e4c2eeb758a ("alpha/PCI: Replace pci_fixup_irqs() call with host bridge IRQ mapping hooks"). As a side effect of converting PCI IRQ allocation to the struct pci_host_bridge {map/swizzle}_irq() hooks mechanism, the actual PCI IRQ allocation function (ie pci_assign_irq()) is carried out per-device in pci_device_probe() that is called when a PCI device driver is about to be probed. This means that, for drivers compiled as loadable modules, the actual PCI device IRQ allocation can now happen after the system has booted so the struct pci_host_bridge {map/swizzle}_irq() hooks pci_assign_irq() relies on must stay valid after the system has booted so that PCI core can carry out PCI IRQ allocation correctly. Most of the alpha board structures pci_map_irq() and pci_swizzle() hooks (that are used to initialize their struct pci_host_bridge equivalent through the alpha_mv global variable - that represents the struct alpha_machine_vector of the running kernel) are marked as __init/__initdata; this causes freed memory dereferences when PCI IRQ allocation is carried out after the kernel has booted (ie when loading PCI drivers as loadable module) because when the kernel tries to bind the PCI device to its (module) driver, the function pci_assign_irq() is called, that in turn retrieves the struct pci_host_bridge {map/swizzle}_irq() hooks to carry out PCI IRQ allocation; if those hooks are marked as __init code/__initdata they point at freed/invalid memory. Fix the issue by removing the __init/__initdata markers from all subarch struct alpha_machine_vector.pci_map_irq()/pci_swizzle() functions (and data). Fixes: 0e4c2eeb758a ("alpha/PCI: Replace pci_fixup_irqs() call with host bridge IRQ mapping hooks") Link: http://lkml.kernel.org/r/alpine.LRH.2.21.1710251043170.7098@math.ut.ee Reported-by: Meelis Roos <mroos@linux.ee> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Cc: Richard Henderson <rth@twiddle.net> Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru> Cc: Meelis Roos <mroos@linux.ee> Cc: Matt Turner <mattst88@gmail.com>
Diffstat (limited to 'arch/alpha/kernel/sys_eiger.c')
-rw-r--r--arch/alpha/kernel/sys_eiger.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/arch/alpha/kernel/sys_eiger.c b/arch/alpha/kernel/sys_eiger.c
index 15f42083bdb3..2731738b5872 100644
--- a/arch/alpha/kernel/sys_eiger.c
+++ b/arch/alpha/kernel/sys_eiger.c
@@ -141,7 +141,7 @@ eiger_init_irq(void)
}
}
-static int __init
+static int
eiger_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
u8 irq_orig;
@@ -158,7 +158,7 @@ eiger_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
return irq_orig - 0x80;
}
-static u8 __init
+static u8
eiger_swizzle(struct pci_dev *dev, u8 *pinp)
{
struct pci_controller *hose = dev->sysdata;