All subfunctions in kvm_s390_set_mem_control() need to take the kvm->lock, so factor it out of the switch. Also add the missing locking around dat_reset_cmma(). Fixes: e38c884df921 ("KVM: s390: Switch to new gmap") Signed-off-by: Claudio Imbrenda --- arch/s390/kvm/kvm-s390.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index ffb20a64d328..93141a68e0dd 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -962,6 +962,8 @@ static int kvm_s390_set_mem_control(struct kvm *kvm, struct kvm_device_attr *att { int ret; + guard(mutex)(&kvm->lock); + switch (attr->attr) { case KVM_S390_VM_MEM_ENABLE_CMMA: ret = -ENXIO; @@ -969,7 +971,6 @@ static int kvm_s390_set_mem_control(struct kvm *kvm, struct kvm_device_attr *att break; VM_EVENT(kvm, 3, "%s", "ENABLE: CMMA support"); - mutex_lock(&kvm->lock); if (kvm->created_vcpus) ret = -EBUSY; else { @@ -978,7 +979,6 @@ static int kvm_s390_set_mem_control(struct kvm *kvm, struct kvm_device_attr *att kvm->arch.use_pfmfi = 0; ret = 0; } - mutex_unlock(&kvm->lock); break; case KVM_S390_VM_MEM_CLR_CMMA: { gfn_t start_gfn = 0; @@ -992,7 +992,8 @@ static int kvm_s390_set_mem_control(struct kvm *kvm, struct kvm_device_attr *att VM_EVENT(kvm, 3, "%s", "RESET: CMMA states"); do { - start_gfn = dat_reset_cmma(kvm->arch.gmap->asce, start_gfn); + scoped_guard(read_lock, &kvm->mmu_lock) + start_gfn = dat_reset_cmma(kvm->arch.gmap->asce, start_gfn); cond_resched(); } while (start_gfn); ret = 0; @@ -1010,8 +1011,6 @@ static int kvm_s390_set_mem_control(struct kvm *kvm, struct kvm_device_attr *att if (get_user(new_limit, (u64 __user *)attr->addr)) return -EFAULT; - guard(mutex)(&kvm->lock); - new_limit = ALIGN(new_limit, HPAGE_SIZE); if (kvm->arch.mem_limit != KVM_S390_NO_MEM_LIMIT && new_limit > kvm->arch.mem_limit) -- 2.54.0