Re: [PATCH v9 01/16] KVM: arm64: Serialize repeated vCPU initialization
From: Fuad Tabba
Date: Wed Jul 29 2026 - 11:21:36 EST
On Mon, 20 Jul 2026 at 06:39, Akihiko Odaki
<odaki@xxxxxxxxxxxxxxxxxxxxxx> wrote:
>
> The initial KVM_ARM_VCPU_INIT path holds config_lock while resetting the
> vCPU, but repeated initialization of an existing vCPU does not. As a
> result, reset_mdcr() can race with VM-wide PMU configuration and
> overwrite MDCR_EL2 with a stale counter count.
>
> Take config_lock around the repeated-init checks and reset. The vCPU
> ioctl already holds vcpu->mutex, matching the established lock ordering.
>
> Fixes: c8823e51b534 ("KVM: arm64: Fix MDCR_EL2.HPMN reset value")
> Closes: https://sashiko.dev/#/patchset/20260710-hybrid-v8-0-621409f3a592@xxxxxxxxxxxxxxxxxxxxxx?part=1
> Assisted-by: Codex:gpt-5.6-sol
> Signed-off-by: Akihiko Odaki <odaki@xxxxxxxxxxxxxxxxxxxxxx>
Reviewed-by: Fuad Tabba <fuad.tabba@xxxxxxxxx>
Cheers,
/fuad
> ---
> arch/arm64/kvm/arm.c | 15 +++++++--------
> 1 file changed, 7 insertions(+), 8 deletions(-)
>
> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> index 50adfff75be8..a06ea39f57b1 100644
> --- a/arch/arm64/kvm/arm.c
> +++ b/arch/arm64/kvm/arm.c
> @@ -1652,29 +1652,26 @@ static int __kvm_vcpu_set_target(struct kvm_vcpu *vcpu,
> {
> unsigned long features = init->features[0];
> struct kvm *kvm = vcpu->kvm;
> - int ret = -EINVAL;
> + int ret;
>
> - mutex_lock(&kvm->arch.config_lock);
> + lockdep_assert_held(&kvm->arch.config_lock);
>
> if (test_bit(KVM_ARCH_FLAG_VCPU_FEATURES_CONFIGURED, &kvm->arch.flags) &&
> kvm_vcpu_init_changed(vcpu, init))
> - goto out_unlock;
> + return -EINVAL;
>
> bitmap_copy(kvm->arch.vcpu_features, &features, KVM_VCPU_MAX_FEATURES);
>
> ret = kvm_setup_vcpu(vcpu);
> if (ret)
> - goto out_unlock;
> + return ret;
>
> /* Now we know what it is, we can reset it. */
> kvm_reset_vcpu(vcpu);
>
> set_bit(KVM_ARCH_FLAG_VCPU_FEATURES_CONFIGURED, &kvm->arch.flags);
> vcpu_set_flag(vcpu, VCPU_INITIALIZED);
> - ret = 0;
> -out_unlock:
> - mutex_unlock(&kvm->arch.config_lock);
> - return ret;
> + return 0;
> }
>
> static int kvm_vcpu_set_target(struct kvm_vcpu *vcpu,
> @@ -1690,6 +1687,8 @@ static int kvm_vcpu_set_target(struct kvm_vcpu *vcpu,
> if (ret)
> return ret;
>
> + guard(mutex)(&vcpu->kvm->arch.config_lock);
> +
> if (!kvm_vcpu_initialized(vcpu))
> return __kvm_vcpu_set_target(vcpu, init);
>
>
> --
> 2.55.0
>
>