[PATCH v2 3/4] KVM: arm64: vgic: Tear down what vgic_init() created when it fails

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


On Mon, Aug 24, 2026 at 08:42:44AM +0800, Fuad Tabba wrote:
> Once kvm_vgic_dist_init() has succeeded, every later failure in
> vgic_init() returns with the SPI array still allocated. A failure after
> vgic_v4_init() has also succeeded, which today means only
> kvm_vgic_setup_default_irq_routing(), leaves the vPE array behind as
> well.
>
> A failed vgic_init() leaves kvm_arch_vcpu_precreate() admitting new
> vCPUs, so a retry of KVM_DEV_ARM_VGIC_CTRL_INIT reaches
> vgic_v4_init()'s early return with an array that no longer covers every
> vCPU, and vgic_v3_load()'s WARN_ON(vgic_v4_load()) fires on the first
> one it misses.
>
> Release both on the two paths that can reach them, so the ioctl is all
> or nothing and a retry starts from scratch. dist->nr_spis stays frozen,
> since the SPI count cannot change once vgic_init() has supplied it.
>
> Fixes: 180ae7b11823 ("KVM: arm/arm64: Enable irqchip routing")
> Fixes: 74fe55dc9ab7 ("KVM: arm/arm64: GICv4: Add init/teardown of the per-VM vPE irq domain")
> Reported-by: Sashiko <sashiko-bot at kernel.org>
> Closes: https://lore.kernel.org/all/20260807105558.73D701F000E9@smtp.kernel.org/
> Signed-off-by: Fuad Tabba <fuad.tabba at linux.dev>
> ---
>  arch/arm64/kvm/vgic/vgic-init.c | 11 +++++++++--
>  1 file changed, 9 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c
> index 4012df6002ea6..7493fded53acc 100644
> --- a/arch/arm64/kvm/vgic/vgic-init.c
> +++ b/arch/arm64/kvm/vgic/vgic-init.c
> @@ -462,7 +462,7 @@ int vgic_init(struct kvm *kvm)
>  		if (vgic_supports_direct_irqs(kvm)) {
>  			ret = vgic_v4_init(kvm);
>  			if (ret)

Hi Tabba,

> -				return ret;
> +				goto out_teardown;

The vigc_v4_init already called vgic_v4_teardown() in error path,
thus I think just free dist->spis is enough yet ?

>  		}
>  	} else {
>  		ret = vgic_v5_init(kvm);
> @@ -475,12 +475,19 @@ int vgic_init(struct kvm *kvm)
>
>  	ret = kvm_vgic_setup_default_irq_routing(kvm);
>  	if (ret)
> -		return ret;
> +		goto out_teardown;
>
>  	vgic_debug_init(kvm);
>  	dist->initialized = true;
>
>  	return 0;
> +
> +out_teardown:
> +	vgic_v4_teardown(kvm);
> +	kfree(dist->spis);
> +	dist->spis = NULL;
> +
> +	return ret;
>  }
>
>  static void kvm_vgic_dist_destroy(struct kvm *kvm)
> --
> 2.39.5
>



More information about the linux-arm-kernel mailing list