[PATCH 2/3] irqchip/gic-v4: Unwind what its_alloc_vcpu_irqs() allocated on failure
From: Fuad Tabba
Date: Thu Aug 20 2026 - 08:51:40 EST
A failure in the its_alloc_vcpu_sgis() loop leaves behind both the SGI
domains created for the vPEs below the failing index and the vPE irqs
allocated before the loop, since irq_domain_remove() frees neither. Each
leaked vPE takes its ITS state with it, a vpe_id and an LPI pending
table.
Free both from a second label before the existing unwind. With the
freed pointers now cleared, its_free_sgi_irqs() can skip a vPE with no
SGI domain rather than warn on it, so the error path can reuse it.
Fixes: 6d31b6ff985d ("irqchip/gic-v4.1: Add VSGI allocation/teardown")
Signed-off-by: Fuad Tabba <fuad.tabba@xxxxxxxxx>
---
drivers/irqchip/irq-gic-v4.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/irqchip/irq-gic-v4.c b/drivers/irqchip/irq-gic-v4.c
index 754839e409f88..f707a3cb281aa 100644
--- a/drivers/irqchip/irq-gic-v4.c
+++ b/drivers/irqchip/irq-gic-v4.c
@@ -159,6 +159,8 @@ static int its_alloc_vcpu_sgis(struct its_vpe *vpe, int idx)
return -ENOMEM;
}
+static void its_free_sgi_irqs(struct its_vm *vm);
+
int its_alloc_vcpu_irqs(struct its_vm *vm)
{
int vpe_base_irq, i;
@@ -189,11 +191,14 @@ int its_alloc_vcpu_irqs(struct its_vm *vm)
vm->vpes[i]->irq = vpe_base_irq + i;
ret = its_alloc_vcpu_sgis(vm->vpes[i], i);
if (ret)
- goto err;
+ goto err_free_irqs;
}
return 0;
+err_free_irqs:
+ its_free_sgi_irqs(vm);
+ irq_domain_free_irqs(vpe_base_irq, vm->nr_vpes);
err:
if (vm->domain) {
irq_domain_remove(vm->domain);
@@ -215,8 +220,13 @@ static void its_free_sgi_irqs(struct its_vm *vm)
return;
for (i = 0; i < vm->nr_vpes; i++) {
- unsigned int irq = irq_find_mapping(vm->vpes[i]->sgi_domain, 0);
+ unsigned int irq;
+ /* irq_find_mapping() falls back to the default domain on NULL. */
+ if (!vm->vpes[i]->sgi_domain)
+ continue;
+
+ irq = irq_find_mapping(vm->vpes[i]->sgi_domain, 0);
if (WARN_ON(!irq))
continue;
--
2.39.5