From mboxrd@z Thu Jan 1 00:00:00 1970 From: suravee.suthikulpanit@amd.com (suravee.suthikulpanit at amd.com) Date: Thu, 20 Nov 2014 19:02:25 -0600 Subject: [PATCH] irqdomain: Fix NULL pointer dererence in irq_domain_free_irqs_parent Message-ID: <1416531745-24661-1-git-send-email-suravee.suthikulpanit@amd.com> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org From: Suravee Suthikulpanit This patch checks if the parent domain is NULL before recursively freeing irqs in the parent domains. In this case, GICv2m is freeing irqs in parent (GIC), which calls irq_domain_free_irqs_top. This fixes the crash below: Unble to handle kernel NULL pointer dereference at virtual address 00000018 pgd = fffffe03c78c0000 [00000018] *pgd=00000083c8700003, *pud=00000083c8700003, *pmd=00000083c8700003, *pte=0000000000000000 Internal error: Oops: 96000007 [#1] SMP Modules linked in: mlx4_core(-) rtc_efi efivarfs [last unloaded: mlx4_en] CPU: 5 PID: 985 Comm: modprobe Not tainted 3.18.0-rc4-marc-v2m+ #223 task: fffffe03c20c0000 ti: fffffe03c1fb8000 task.ti: fffffe03c1fb8000 PC is at irq_domain_free_irqs_recursive+0x10/0x84 LR is at irq_domain_free_irqs_common+0x8c/0xa0 pc : [] lr : [] pstate: 60000145 sp : fffffe03c1fbb9a0 x29: fffffe03c1fbb9a0 x28: fffffe03c1fb8000 x27: fffffe000092f000 x26: fffffe03c10eba00 ... Call trace: [] irq_domain_free_irqs_recursive+0x10/0x84 [] irq_domain_free_irqs_common+0x88/0xa0 [] irq_domain_free_irqs_top+0x6c/0x84 [] irq_domain_free_irqs_recursive+0x24/0x84 [] irq_domain_free_irqs_parent+0x14/0x20 [] gicv2m_irq_domain_free+0x48/0x88 [] irq_domain_free_irqs_recursive+0x24/0x84 [] irq_domain_free_irqs_common+0x88/0xa0 [] irq_domain_free_irqs_top+0x6c/0x84 [] msi_domain_free+0x74/0x8c [] irq_domain_free_irqs_recursive+0x24/0x84 [] irq_domain_free_irqs+0x110/0x184 [] msi_domain_free_irqs+0x28/0x4c [] free_msi_irqs+0x90/0x1d8 [] pci_disable_msix+0x40/0x50 Signed-off-by: Suravee Suthikulpanit --- kernel/irq/irqdomain.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index 029acf1..4390eb8 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -1166,6 +1166,9 @@ int irq_domain_alloc_irqs_parent(struct irq_domain *domain, void irq_domain_free_irqs_parent(struct irq_domain *domain, unsigned int irq_base, unsigned int nr_irqs) { + if (!domain->parent) + return; + /* irq_domain_free_irqs_recursive() will call parent's free */ if (!irq_domain_is_auto_recursive(domain)) irq_domain_free_irqs_recursive(domain->parent, irq_base, -- 1.9.3