[PATCH] KVM: arm64: vgic: Serialise CTRL_INIT against vCPU creation
Fuad Tabba
fuad.tabba at linux.dev
Sun Sep 6 09:45:37 PDT 2026
Hi Sascha,
On Fri, 4 Sept 2026 at 18:45, Sascha Bischoff <Sascha.Bischoff at arm.com> wrote:
>
> vgic_init() compares created_vcpus with online_vcpus to detect a vCPU
> being created. However, CTRL_INIT only holds config_lock, while
> admission of new vCPUs and updates to created_vcpus are protected by
> kvm->lock.
>
> A concurrent KVM_CREATE_VCPU can therefore increment created_vcpus
> after vgic_init() checks the counters, then block on config_lock before
> publishing the new vCPU. For a GICv4 VM, vgic_v4_init() consequently
> sizes its vPE array using a stale online_vcpus value, leaving no vPE
> entry for the new vCPU once its creation completes. The upcoming GICv5
> IRS support would hit the same issue when sizing its doorbell domain.
>
> Hold kvm->lock around CTRL_INIT. The existing counter check detects a
> vCPU creation already in progress, while the lock prevents a new one
> from starting until initialisation has completed.
This also brings CTRL_INIT in line with the other vgic device flows
that serialise against vCPU creation: kvm_vgic_create(), the GICv2
register uaccess path, and SAVE_PENDING_TABLES just below it all hold
kvm->lock across the config_lock section.
> Fixes: f00327731131 ("KVM: arm64: Use config_lock to protect vgic state")
> Reported-by: Sashiko <sashiko-bot at kernel.org>
> Link: https://lore.kernel.org/r/20260807124506.ED85C1F000E9@smtp.kernel.org
> Signed-off-by: Sascha Bischoff <sascha.bischoff at arm.com>
Given that f00327731131 carried a stable tag, worth a Cc: stable?
Reviewed-by: Fuad Tabba <fuad.tabba at linux.dev>
Tested-by: Fuad Tabba <fuad.tabba at linux.dev>
Cheers,
/fuad
> ---
> arch/arm64/kvm/vgic/vgic-kvm-device.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/arch/arm64/kvm/vgic/vgic-kvm-device.c b/arch/arm64/kvm/vgic/vgic-kvm-device.c
> index 90be99443df3b..219881915bf41 100644
> --- a/arch/arm64/kvm/vgic/vgic-kvm-device.c
> +++ b/arch/arm64/kvm/vgic/vgic-kvm-device.c
> @@ -255,9 +255,11 @@ static int vgic_set_common_attr(struct kvm_device *dev,
> case KVM_DEV_ARM_VGIC_GRP_CTRL: {
> switch (attr->attr) {
> case KVM_DEV_ARM_VGIC_CTRL_INIT:
> + mutex_lock(&dev->kvm->lock);
> mutex_lock(&dev->kvm->arch.config_lock);
> r = vgic_init(dev->kvm);
> mutex_unlock(&dev->kvm->arch.config_lock);
> + mutex_unlock(&dev->kvm->lock);
> return r;
> case KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES:
> /*
> --
> 2.34.1
More information about the linux-arm-kernel
mailing list