Create a helper method release_gmap_shadow_safe() to simplify releasing the gmap shadow of a vsie_page and a method kvm_s390_vsie_destroy_page() reduce nesting. Both methods will be called from multiple places in upcoming patches. Signed-off-by: Christoph Schlameuss --- arch/s390/kvm/s390/vsie.c | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/arch/s390/kvm/s390/vsie.c b/arch/s390/kvm/s390/vsie.c index 75676f493ab2..5e41dd151f8e 100644 --- a/arch/s390/kvm/s390/vsie.c +++ b/arch/s390/kvm/s390/vsie.c @@ -164,6 +164,17 @@ static void release_gmap_shadow(struct vsie_page *vsie_page) } } +static void release_gmap_shadow_safe(struct kvm *kvm, struct vsie_page *vsie_page) +{ + if (!vsie_page->gmap_cache.gmap) + return; + + guard(spinlock)(&kvm->arch.gmap->children_lock); + + if (vsie_page->gmap_cache.gmap) + release_gmap_shadow(vsie_page); +} + static struct gmap *acquire_gmap_shadow(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page) { union ctlreg0 cr0; @@ -1585,11 +1596,7 @@ static struct vsie_page *get_vsie_page(struct kvm *kvm, unsigned long addr) mutex_unlock(&kvm->arch.vsie.mutex); memset(&vsie_page->scb_s, 0, sizeof(struct kvm_s390_sie_block)); - if (vsie_page->gmap_cache.gmap) { - scoped_guard(spinlock, &kvm->arch.gmap->children_lock) - if (vsie_page->gmap_cache.gmap) - release_gmap_shadow(vsie_page); - } + release_gmap_shadow_safe(kvm, vsie_page); prefix_unmapped(vsie_page); vsie_page->fault_addr = 0; vsie_page->scb_s.ihcpu = 0xffffU; @@ -1658,24 +1665,29 @@ void kvm_s390_vsie_init(struct kvm *kvm) xa_init_flags(&kvm->arch.vsie.addr_to_page, XA_FLAGS_ACCOUNT); } +static void kvm_s390_vsie_destroy_page(struct kvm *kvm, struct vsie_page *vsie_page) +{ + unpin_scb(kvm, vsie_page); + release_gmap_shadow_safe(kvm, vsie_page); + free_vsie_page(vsie_page); +} + /* Destroy the vsie data structures. To be called when a vm is destroyed. */ void kvm_s390_vsie_destroy(struct kvm *kvm) { struct vsie_page *vsie_page; int i; - mutex_lock(&kvm->arch.vsie.mutex); + guard(mutex)(&kvm->arch.vsie.mutex); + for (i = 0; i < kvm->arch.vsie.page_count; i++) { vsie_page = kvm->arch.vsie.pages[i]; - scoped_guard(spinlock, &kvm->arch.gmap->children_lock) - if (vsie_page->gmap_cache.gmap) - release_gmap_shadow(vsie_page); kvm->arch.vsie.pages[i] = NULL; - free_vsie_page(vsie_page); + kvm_s390_vsie_destroy_page(kvm, vsie_page); } - xa_destroy(&kvm->arch.vsie.addr_to_page); + kvm->arch.vsie.page_count = 0; - mutex_unlock(&kvm->arch.vsie.mutex); + xa_destroy(&kvm->arch.vsie.addr_to_page); } void kvm_s390_vsie_kick(struct kvm_vcpu *vcpu) -- 2.55.0