On Mon, 20 Jul 2026 at 06:39, Akihiko Odaki
<[email protected]> 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/[email protected]?part=1
> Assisted-by: Codex:gpt-5.6-sol
> Signed-off-by: Akihiko Odaki <[email protected]>

Reviewed-by: Fuad Tabba <[email protected]>

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
>
>

Reply via email to