[PATCH v2 2/4] irqchip/gic-v4: Unwind what its_alloc_vcpu_irqs() allocated on failure

Yao Yuan yaoyuan at linux.alibaba.com
Tue Aug 25 02:10:22 PDT 2026


On Mon, Aug 24, 2026 at 08:42:43AM +0800, Fuad Tabba wrote:
> 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 and be reused there. The check has to precede the lookup:
> irq_find_mapping(NULL, 0) falls back to irq_default_domain, and the
> live irq it returns would then be freed.

Reviewed-by: Yuan Yao <yaoyuan at linux.alibaba.com>

>
> Fixes: 6d31b6ff985d ("irqchip/gic-v4.1: Add VSGI allocation/teardown")
> Signed-off-by: Fuad Tabba <fuad.tabba at linux.dev>
> ---
>  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
>



More information about the linux-arm-kernel mailing list