Since we are no longer switching from a BSCA to a ESCA we can completely get rid of the sca_lock. The write lock was only taken for that conversion. After removal of the lock some local code cleanups are possible. Signed-off-by: Christoph Schlameuss <schlameuss@xxxxxxxxxxxxx> --- The patch depends on "KVM: s390: Use ESCA instead of BSCA at VM init" Link: https://lore.kernel.org/r/20250603-rm-bsca-v5-1-f691288ada5c@xxxxxxxxxxxxx Checkpatch fails for a already preexisting BUG macro. --- arch/s390/include/asm/kvm_host.h | 1 - arch/s390/kvm/gaccess.c | 19 ++----------------- arch/s390/kvm/interrupt.c | 29 ++++++++++------------------- arch/s390/kvm/kvm-s390.c | 27 ++++++++------------------- 4 files changed, 20 insertions(+), 56 deletions(-) diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index 4d651e6e8b12ecd7796070e9da659b0b2b94d302..b6761a9aaed73233dc4138462c71cf0cdf2ef56a 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h @@ -633,7 +633,6 @@ struct kvm_s390_pv { struct kvm_arch { struct esca_block *sca; - rwlock_t sca_lock; debug_info_t *dbf; struct kvm_s390_float_interrupt float_int; struct kvm_device *flic; diff --git a/arch/s390/kvm/gaccess.c b/arch/s390/kvm/gaccess.c index ee37d397d9218a4d33c7a33bd877d0b974ca9003..2285ef6d19e752b4de77daf2f643305698f3a130 100644 --- a/arch/s390/kvm/gaccess.c +++ b/arch/s390/kvm/gaccess.c @@ -108,14 +108,9 @@ struct aste { int ipte_lock_held(struct kvm *kvm) { - if (sclp.has_siif) { - int rc; + if (sclp.has_siif) + return kvm->arch.sca->ipte_control.kh != 0; - read_lock(&kvm->arch.sca_lock); - rc = kvm->arch.sca->ipte_control.kh != 0; - read_unlock(&kvm->arch.sca_lock); - return rc; - } return kvm->arch.ipte_lock_count != 0; } @@ -128,19 +123,16 @@ static void ipte_lock_simple(struct kvm *kvm) if (kvm->arch.ipte_lock_count > 1) goto out; retry: - read_lock(&kvm->arch.sca_lock); ic = &kvm->arch.sca->ipte_control; old = READ_ONCE(*ic); do { if (old.k) { - read_unlock(&kvm->arch.sca_lock); cond_resched(); goto retry; } new = old; new.k = 1; } while (!try_cmpxchg(&ic->val, &old.val, new.val)); - read_unlock(&kvm->arch.sca_lock); out: mutex_unlock(&kvm->arch.ipte_mutex); } @@ -153,14 +145,12 @@ static void ipte_unlock_simple(struct kvm *kvm) kvm->arch.ipte_lock_count--; if (kvm->arch.ipte_lock_count) goto out; - read_lock(&kvm->arch.sca_lock); ic = &kvm->arch.sca->ipte_control; old = READ_ONCE(*ic); do { new = old; new.k = 0; } while (!try_cmpxchg(&ic->val, &old.val, new.val)); - read_unlock(&kvm->arch.sca_lock); wake_up(&kvm->arch.ipte_wq); out: mutex_unlock(&kvm->arch.ipte_mutex); @@ -171,12 +161,10 @@ static void ipte_lock_siif(struct kvm *kvm) union ipte_control old, new, *ic; retry: - read_lock(&kvm->arch.sca_lock); ic = &kvm->arch.sca->ipte_control; old = READ_ONCE(*ic); do { if (old.kg) { - read_unlock(&kvm->arch.sca_lock); cond_resched(); goto retry; } @@ -184,14 +172,12 @@ static void ipte_lock_siif(struct kvm *kvm) new.k = 1; new.kh++; } while (!try_cmpxchg(&ic->val, &old.val, new.val)); - read_unlock(&kvm->arch.sca_lock); } static void ipte_unlock_siif(struct kvm *kvm) { union ipte_control old, new, *ic; - read_lock(&kvm->arch.sca_lock); ic = &kvm->arch.sca->ipte_control; old = READ_ONCE(*ic); do { @@ -200,7 +186,6 @@ static void ipte_unlock_siif(struct kvm *kvm) if (!new.kh) new.k = 0; } while (!try_cmpxchg(&ic->val, &old.val, new.val)); - read_unlock(&kvm->arch.sca_lock); if (!new.kh) wake_up(&kvm->arch.ipte_wq); } diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index 95a876ff7aca9c632c3e361275da6781ec070c07..58c5a6734dc733b6ede600d0ea4e445d4772b581 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c @@ -44,35 +44,28 @@ static struct kvm_s390_gib *gib; /* handle external calls via sigp interpretation facility */ static int sca_ext_call_pending(struct kvm_vcpu *vcpu, int *src_id) { - int c, scn; + struct esca_block *sca = vcpu->kvm->arch.sca; + union esca_sigp_ctrl sigp_ctrl = sca->cpu[vcpu->vcpu_id].sigp_ctrl; if (!kvm_s390_test_cpuflags(vcpu, CPUSTAT_ECALL_PEND)) return 0; BUG_ON(!kvm_s390_use_sca_entries()); - read_lock(&vcpu->kvm->arch.sca_lock); - struct esca_block *sca = vcpu->kvm->arch.sca; - union esca_sigp_ctrl sigp_ctrl = sca->cpu[vcpu->vcpu_id].sigp_ctrl; - - c = sigp_ctrl.c; - scn = sigp_ctrl.scn; - read_unlock(&vcpu->kvm->arch.sca_lock); if (src_id) - *src_id = scn; + *src_id = sigp_ctrl.scn; - return c; + return sigp_ctrl.c; } static int sca_inject_ext_call(struct kvm_vcpu *vcpu, int src_id) { - int expect, rc; - - BUG_ON(!kvm_s390_use_sca_entries()); - read_lock(&vcpu->kvm->arch.sca_lock); struct esca_block *sca = vcpu->kvm->arch.sca; union esca_sigp_ctrl *sigp_ctrl = &sca->cpu[vcpu->vcpu_id].sigp_ctrl; union esca_sigp_ctrl new_val = {0}, old_val; + int expect, rc; + + BUG_ON(!kvm_s390_use_sca_entries()); old_val = READ_ONCE(*sigp_ctrl); new_val.scn = src_id; @@ -81,7 +74,6 @@ static int sca_inject_ext_call(struct kvm_vcpu *vcpu, int src_id) expect = old_val.value; rc = cmpxchg(&sigp_ctrl->value, old_val.value, new_val.value); - read_unlock(&vcpu->kvm->arch.sca_lock); if (rc != expect) { /* another external call is pending */ @@ -93,15 +85,14 @@ static int sca_inject_ext_call(struct kvm_vcpu *vcpu, int src_id) static void sca_clear_ext_call(struct kvm_vcpu *vcpu) { + struct esca_block *sca = vcpu->kvm->arch.sca; + union esca_sigp_ctrl *sigp_ctrl = &sca->cpu[vcpu->vcpu_id].sigp_ctrl; + if (!kvm_s390_use_sca_entries()) return; kvm_s390_clear_cpuflags(vcpu, CPUSTAT_ECALL_PEND); - read_lock(&vcpu->kvm->arch.sca_lock); - struct esca_block *sca = vcpu->kvm->arch.sca; - union esca_sigp_ctrl *sigp_ctrl = &sca->cpu[vcpu->vcpu_id].sigp_ctrl; WRITE_ONCE(sigp_ctrl->value, 0); - read_unlock(&vcpu->kvm->arch.sca_lock); } int psw_extint_disabled(struct kvm_vcpu *vcpu) diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 6a2a5207e199aef9f602ff1f4d29686840da7235..0163f2632eb7a396e6ff9f76fb4e53f58a3e4c9e 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -1937,14 +1937,12 @@ static void kvm_s390_update_topology_change_report(struct kvm *kvm, bool val) union sca_utility new, old; struct esca_block *sca; - read_lock(&kvm->arch.sca_lock); sca = kvm->arch.sca; old = READ_ONCE(sca->utility); do { new = old; new.mtcr = val; } while (!try_cmpxchg(&sca->utility.val, &old.val, new.val)); - read_unlock(&kvm->arch.sca_lock); } static int kvm_s390_set_topo_change_indication(struct kvm *kvm, @@ -1965,9 +1963,7 @@ static int kvm_s390_get_topo_change_indication(struct kvm *kvm, if (!test_kvm_facility(kvm, 11)) return -ENXIO; - read_lock(&kvm->arch.sca_lock); topo = kvm->arch.sca->utility.mtcr; - read_unlock(&kvm->arch.sca_lock); return put_user(topo, (u8 __user *)attr->addr); } @@ -3342,7 +3338,6 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) if (!sclp.has_64bscao) alloc_flags |= GFP_DMA; - rwlock_init(&kvm->arch.sca_lock); mutex_lock(&kvm_lock); kvm->arch.sca = alloc_pages_exact(sizeof(*kvm->arch.sca), alloc_flags); @@ -3527,36 +3522,30 @@ static int __kvm_ucontrol_vcpu_init(struct kvm_vcpu *vcpu) static void sca_del_vcpu(struct kvm_vcpu *vcpu) { + struct esca_block *sca = vcpu->kvm->arch.sca; + if (!kvm_s390_use_sca_entries()) return; - read_lock(&vcpu->kvm->arch.sca_lock); - struct esca_block *sca = vcpu->kvm->arch.sca; clear_bit_inv(vcpu->vcpu_id, (unsigned long *)sca->mcn); sca->cpu[vcpu->vcpu_id].sda = 0; - read_unlock(&vcpu->kvm->arch.sca_lock); } static void sca_add_vcpu(struct kvm_vcpu *vcpu) { - if (!kvm_s390_use_sca_entries()) { - phys_addr_t sca_phys = virt_to_phys(vcpu->kvm->arch.sca); - - /* we still need the basic sca for the ipte control */ - vcpu->arch.sie_block->scaoh = sca_phys >> 32; - vcpu->arch.sie_block->scaol = sca_phys; - return; - } - read_lock(&vcpu->kvm->arch.sca_lock); struct esca_block *sca = vcpu->kvm->arch.sca; phys_addr_t sca_phys = virt_to_phys(sca); - sca->cpu[vcpu->vcpu_id].sda = virt_to_phys(vcpu->arch.sie_block); + /* we still need the sca header for the ipte control */ vcpu->arch.sie_block->scaoh = sca_phys >> 32; vcpu->arch.sie_block->scaol = sca_phys & ESCA_SCAOL_MASK; vcpu->arch.sie_block->ecb2 |= ECB2_ESCA; + + if (!kvm_s390_use_sca_entries()) + return; + set_bit_inv(vcpu->vcpu_id, (unsigned long *)sca->mcn); - read_unlock(&vcpu->kvm->arch.sca_lock); + sca->cpu[vcpu->vcpu_id].sda = virt_to_phys(vcpu->arch.sie_block); } static int sca_can_add_vcpu(struct kvm *kvm, unsigned int id) --- base-commit: 0a4b866d08c6adaea2f4592d31edac6deeb4dcbd change-id: 20250602-rm-sca-lock-d7c1eca252b1 prerequisite-change-id: 20250513-rm-bsca-ab1e8649aca7:v5 prerequisite-patch-id: e9e66d612c16d9bbfb0c6377d333d88e50a6078b Best regards, -- Christoph Schlameuss <schlameuss@xxxxxxxxxxxxx>