Linux MIPS Architecture development
 help / color / mirror / Atom feed
From: Haofeng Li <920484857@qq.com>
To: tglx@kernel.org
Cc: linux-kernel@vger.kernel.org, Haofeng Li <13266079573@163.com>,
	Haofeng Li <lihaofeng@kylinos.cn>,
	Florian Fainelli <florian.fainelli@broadcom.com>,
	Broadcom internal kernel review list
	<bcm-kernel-feedback-list@broadcom.com>,
	Kevin Cernekee <cernekee@gmail.com>,
	linux-mips@vger.kernel.org, linux-arm-kernel@lists.infradead.org
Subject: [PATCH 05/16] irqchip/bcm7038-l1: clean up init failure paths
Date: Tue, 14 Jul 2026 21:24:41 +0800	[thread overview]
Message-ID: <tencent_4839362F248901E45E50D9AEF6823DFA4007@qq.com> (raw)
In-Reply-To: <20260714132453.3302672-1-920484857@qq.com>

From: Haofeng Li <lihaofeng@kylinos.cn>

bcm7038_l1_init_one() stores the allocated CPU object in
intc->cpus[idx] before mapping its registers and parent interrupt.
Failures after that allocation leak the CPU object and possibly its
MMIO mapping.

A later IRQ domain allocation failure also frees intc while leaving
parent mappings and chained handlers installed for CPUs initialized
successfully. Those handlers retain intc as their data and can access
freed memory.

Free the current CPU object on local failures. Remember every parent
IRQ so the common error path can disable wake when it was enabled,
remove the chained handler, dispose the mapping, unmap the registers,
and free the CPU object before freeing intc.

Fixes: 5f7f0317ed28 ("IRQCHIP: Add new driver for BCM7038-style level 1 interrupt controllers")

Signed-off-by: Haofeng Li <lihaofeng@kylinos.cn>
---
 drivers/irqchip/irq-bcm7038-l1.c | 24 ++++++++++++++++++++----
 1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/drivers/irqchip/irq-bcm7038-l1.c b/drivers/irqchip/irq-bcm7038-l1.c
index 54a8557ef557..b42c4f4df6bf 100644
--- a/drivers/irqchip/irq-bcm7038-l1.c
+++ b/drivers/irqchip/irq-bcm7038-l1.c
@@ -49,6 +49,8 @@ struct bcm7038_l1_chip {
 
 struct bcm7038_l1_cpu {
 	void __iomem		*map_base;
+	unsigned int		parent_irq;
+	bool			wake_enabled;
 	u32			mask_cache[];
 };
 
@@ -247,8 +249,11 @@ static int bcm7038_l1_init_one(struct device_node *dn, unsigned int idx,
 		return -ENOMEM;
 
 	cpu->map_base = ioremap(res.start, sz);
-	if (!cpu->map_base)
+	if (!cpu->map_base) {
+		kfree(cpu);
+		intc->cpus[idx] = NULL;
 		return -ENOMEM;
+	}
 
 	for (i = 0; i < n_words; i++) {
 		l1_writel(~intc->irq_fwd_mask[i],
@@ -261,12 +266,17 @@ static int bcm7038_l1_init_one(struct device_node *dn, unsigned int idx,
 	parent_irq = irq_of_parse_and_map(dn, idx);
 	if (!parent_irq) {
 		pr_err("failed to map parent interrupt %d\n", parent_irq);
+		iounmap(cpu->map_base);
+		kfree(cpu);
+		intc->cpus[idx] = NULL;
 		return -EINVAL;
 	}
 
-	if (of_property_read_bool(dn, "brcm,irq-can-wake"))
-		enable_irq_wake(parent_irq);
+	if (of_property_read_bool(dn, "brcm,irq-can-wake") &&
+	    !enable_irq_wake(parent_irq))
+		cpu->wake_enabled = true;
 
+	cpu->parent_irq = parent_irq;
 	irq_set_chained_handler_and_data(parent_irq, bcm7038_l1_irq_handle,
 					 intc);
 
@@ -408,7 +418,7 @@ static int bcm7038_l1_probe(struct platform_device *pdev, struct device_node *pa
 			if (idx)
 				break;
 			pr_err("failed to remap intc L1 registers\n");
-			goto out_free;
+			goto out_unmap;
 		}
 	}
 
@@ -440,6 +450,12 @@ static int bcm7038_l1_probe(struct platform_device *pdev, struct device_node *pa
 		struct bcm7038_l1_cpu *cpu = intc->cpus[idx];
 
 		if (cpu) {
+			if (cpu->parent_irq) {
+				if (cpu->wake_enabled)
+					disable_irq_wake(cpu->parent_irq);
+				irq_set_chained_handler_and_data(cpu->parent_irq, NULL, NULL);
+				irq_dispose_mapping(cpu->parent_irq);
+			}
 			if (cpu->map_base)
 				iounmap(cpu->map_base);
 			kfree(cpu);
-- 
2.25.1


       reply	other threads:[~2026-07-14 13:26 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20260714122351.3274006-1-lihaofeng@kylinos.cn>
     [not found] ` <20260714132453.3302672-1-920484857@qq.com>
2026-07-14 13:24   ` Haofeng Li [this message]
2026-07-28 17:36     ` [PATCH 05/16] irqchip/bcm7038-l1: clean up init failure paths Florian Fainelli
2026-07-14 13:24   ` [PATCH 06/16] irqchip/loongson-liointc: unmap per-core iomaps on error Haofeng Li
2026-08-02 16:31     ` Radu Rendec
2026-07-14 13:24   ` [PATCH 07/16] irqchip/mips-gic: clean up IRQ domain creation failure Haofeng Li
2026-08-02 19:19     ` Radu Rendec
2026-07-14 13:24   ` [PATCH 08/16] irqchip/mips-gic: clean up if IPI domain registration fails Haofeng Li
2026-08-02 19:26     ` Radu Rendec
2026-07-14 13:24   ` [PATCH 09/16] irqchip/econet: clean up VEIC initialization Haofeng Li
2026-07-23  1:09     ` Caleb James DeLisle
2026-07-14 13:24   ` [PATCH 11/16] irqchip/loongson-eiointc: preserve live state on cascade failure Haofeng Li
2026-07-14 13:24   ` [PATCH 16/16] irqchip/bcm7120-l2: fix parent IRQ count error handling Haofeng Li
2026-07-28 15:57     ` Florian Fainelli

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=tencent_4839362F248901E45E50D9AEF6823DFA4007@qq.com \
    --to=920484857@qq.com \
    --cc=13266079573@163.com \
    --cc=bcm-kernel-feedback-list@broadcom.com \
    --cc=cernekee@gmail.com \
    --cc=florian.fainelli@broadcom.com \
    --cc=lihaofeng@kylinos.cn \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mips@vger.kernel.org \
    --cc=tglx@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox