[tip: irq/drivers] irqchip/gic-v3-its: Prevent leak in its_vpe_irq_domain_alloc()

tip-bot2 for Kemeng Shi posted 1 patch 3 days, 16 hours ago
drivers/irqchip/irq-gic-v3-its.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
[tip: irq/drivers] irqchip/gic-v3-its: Prevent leak in its_vpe_irq_domain_alloc()
Posted by tip-bot2 for Kemeng Shi 3 days, 16 hours ago
The following commit has been merged into the irq/drivers branch of tip:

Commit-ID:     325ff3e78c64cd619d52b99f7c8b09a3f31e1495
Gitweb:        https://git.kernel.org/tip/325ff3e78c64cd619d52b99f7c8b09a3f31e1495
Author:        Kemeng Shi <shikemeng@huaweicloud.com>
AuthorDate:    Tue, 21 Jul 2026 14:32:40 +08:00
Committer:     Thomas Gleixner <tglx@kernel.org>
CommitterDate: Tue, 21 Jul 2026 10:03:48 +02:00

irqchip/gic-v3-its: Prevent leak in its_vpe_irq_domain_alloc()

When its_irq_gic_domain_alloc() fails, the following
its_vpe_irq_domain_free() fails to invoke its_vep_teardown() for the
corresponding interrupt, which leaks the resource.

Invoke its_vpe_teardown() in the error handling path to avoid the leak.

[ tglx: Massaged change log ]

Fixes: 7d75bbb4bc1ad ("irqchip/gic-v3-its: Add VPE irq domain allocation/teardown")
Signed-off-by: Kemeng Shi <shikemeng@huaweicloud.com>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Acked-by: Marc Zyngier <maz@kernel.org>
Link: https://patch.msgid.link/20260721063241.52549-2-shikemeng@huaweicloud.com
---
 drivers/irqchip/irq-gic-v3-its.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 78c34e6..07e3a08 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -4594,6 +4594,13 @@ static int its_vpe_init(struct its_vpe *vpe)
 
 static void its_vpe_teardown(struct its_vpe *vpe)
 {
+	/*
+	 * If vpt_page is NULL, then its_vpe_init() has failed, and
+	 * there is nothing to do as no resource has been allocated.
+	 */
+	if (vpe->vpt_page == NULL)
+		return;
+
 	its_vpe_db_proxy_unmap(vpe);
 	its_vpe_id_free(vpe->vpe_id);
 	its_free_pending_table(vpe->vpt_page);
@@ -4674,8 +4681,10 @@ static int its_vpe_irq_domain_alloc(struct irq_domain *domain, unsigned int virq
 		irqd_set_resend_when_in_progress(irq_get_irq_data(virq + i));
 	}
 
-	if (err)
+	if (err) {
+		its_vpe_teardown(vm->vpes[i]);
 		its_vpe_irq_domain_free(domain, virq, i);
+	}
 
 	return err;
 }