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

