summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWenwen Wang <wang6495@umn.edu>2019-04-17 09:18:50 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-06-15 11:54:07 +0200
commitaeb743dbe9360aa8b37b725550df1b3811b21fa6 (patch)
tree38dcd54072a809641d71a5d0de28a3200e5e72b0
parent47e6a354e24881c89e936393459ae39a98c4c9de (diff)
downloadlinux-stable-aeb743dbe9360aa8b37b725550df1b3811b21fa6.tar.gz
linux-stable-aeb743dbe9360aa8b37b725550df1b3811b21fa6.tar.bz2
linux-stable-aeb743dbe9360aa8b37b725550df1b3811b21fa6.zip
x86/PCI: Fix PCI IRQ routing table memory leak
[ Upstream commit ea094d53580f40c2124cef3d072b73b2425e7bfd ] In pcibios_irq_init(), the PCI IRQ routing table 'pirq_table' is first found through pirq_find_routing_table(). If the table is not found and CONFIG_PCI_BIOS is defined, the table is then allocated in pcibios_get_irq_routing_table() using kmalloc(). Later, if the I/O APIC is used, this table is actually not used. In that case, the allocated table is not freed, which is a memory leak. Free the allocated table if it is not used. Signed-off-by: Wenwen Wang <wang6495@umn.edu> [bhelgaas: added Ingo's reviewed-by, since the only change since v1 was to use the irq_routing_table local variable name he suggested] Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Ingo Molnar <mingo@kernel.org> Acked-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--arch/x86/pci/irq.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c
index 52e55108404e..d3a73f9335e1 100644
--- a/arch/x86/pci/irq.c
+++ b/arch/x86/pci/irq.c
@@ -1119,6 +1119,8 @@ static const struct dmi_system_id pciirq_dmi_table[] __initconst = {
void __init pcibios_irq_init(void)
{
+ struct irq_routing_table *rtable = NULL;
+
DBG(KERN_DEBUG "PCI: IRQ init\n");
if (raw_pci_ops == NULL)
@@ -1129,8 +1131,10 @@ void __init pcibios_irq_init(void)
pirq_table = pirq_find_routing_table();
#ifdef CONFIG_PCI_BIOS
- if (!pirq_table && (pci_probe & PCI_BIOS_IRQ_SCAN))
+ if (!pirq_table && (pci_probe & PCI_BIOS_IRQ_SCAN)) {
pirq_table = pcibios_get_irq_routing_table();
+ rtable = pirq_table;
+ }
#endif
if (pirq_table) {
pirq_peer_trick();
@@ -1145,8 +1149,10 @@ void __init pcibios_irq_init(void)
* If we're using the I/O APIC, avoid using the PCI IRQ
* routing table
*/
- if (io_apic_assign_pci_irqs)
+ if (io_apic_assign_pci_irqs) {
+ kfree(rtable);
pirq_table = NULL;
+ }
}
x86_init.pci.fixup_irqs();