]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
KVM: s390: vsie: Use mmu cache to allocate rmap
authorClaudio Imbrenda <imbrenda@linux.ibm.com>
Thu, 11 Jun 2026 10:48:50 +0000 (12:48 +0200)
committerClaudio Imbrenda <imbrenda@linux.ibm.com>
Thu, 11 Jun 2026 11:50:09 +0000 (13:50 +0200)
Use kvm_s390_mmu_cache_alloc_rmap() to allocate the rmap in
gmap_insert_rmap(), instead of a normal kzalloc_obj() with GFP_ATOMIC.

This guarantees forward progress.

Fixes: a2c17f9270cc ("KVM: s390: New gmap code")
CC: stable@vger.kernel.org # 7.1
Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Message-ID: <20260611104850.110313-6-imbrenda@linux.ibm.com>

arch/s390/kvm/gaccess.c
arch/s390/kvm/gmap.c
arch/s390/kvm/gmap.h

index 0584fc91606faab930ba6d9c31f42b3fd472e170..36102b2727fbffc2e77ed1500f100bb5ec4b8084 100644 (file)
@@ -1419,8 +1419,8 @@ edat_applies:
        return kvm_s390_get_guest_page(kvm, entries + LEVEL_MEM, table.pte.pfra, wr);
 }
 
-static int _do_shadow_pte(struct gmap *sg, gpa_t raddr, union pte *ptep_h, union pte *ptep,
-                         struct guest_fault *f, bool p)
+static int _do_shadow_pte(struct kvm_s390_mmu_cache *mc, struct gmap *sg, gpa_t raddr,
+                         union pte *ptep_h, union pte *ptep, struct guest_fault *f, bool p)
 {
        union pgste pgste;
        union pte newpte;
@@ -1430,7 +1430,7 @@ static int _do_shadow_pte(struct gmap *sg, gpa_t raddr, union pte *ptep_h, union
        lockdep_assert_held(&sg->parent->children_lock);
 
        scoped_guard(spinlock, &sg->host_to_rmap_lock)
-               rc = gmap_insert_rmap(sg, f->gfn, gpa_to_gfn(raddr), TABLE_TYPE_PAGE_TABLE);
+               rc = gmap_insert_rmap(mc, sg, f->gfn, gpa_to_gfn(raddr), TABLE_TYPE_PAGE_TABLE);
        if (rc)
                return rc;
 
@@ -1462,8 +1462,8 @@ static int _do_shadow_pte(struct gmap *sg, gpa_t raddr, union pte *ptep_h, union
        return 0;
 }
 
-static int _do_shadow_crste(struct gmap *sg, gpa_t raddr, union crste *host, union crste *table,
-                           struct guest_fault *f, bool p)
+static int _do_shadow_crste(struct kvm_s390_mmu_cache *mc, struct gmap *sg, gpa_t raddr,
+                           union crste *host, union crste *table, struct guest_fault *f, bool p)
 {
        union crste newcrste, oldcrste;
        unsigned long mask;
@@ -1476,7 +1476,7 @@ static int _do_shadow_crste(struct gmap *sg, gpa_t raddr, union crste *host, uni
        mask = is_pmd(*table) ? _SEGMENT_FR_MASK : _REGION3_FR_MASK;
        r_gfn = gpa_to_gfn(raddr) & mask;
        scoped_guard(spinlock, &sg->host_to_rmap_lock)
-               rc = gmap_insert_rmap(sg, f->gfn & mask, r_gfn, host->h.tt);
+               rc = gmap_insert_rmap(mc, sg, f->gfn & mask, r_gfn, host->h.tt);
        if (rc)
                return rc;
 
@@ -1578,8 +1578,8 @@ real_address_space:
        if (KVM_BUG_ON(l > TABLE_TYPE_REGION3, sg->kvm))
                return -EFAULT;
        if (l == TABLE_TYPE_PAGE_TABLE)
-               return _do_shadow_pte(sg, saddr, ptep_h, ptep, entries + LEVEL_MEM, w->p);
-       return _do_shadow_crste(sg, saddr, host, table, entries + LEVEL_MEM, w->p);
+               return _do_shadow_pte(mc, sg, saddr, ptep_h, ptep, entries + LEVEL_MEM, w->p);
+       return _do_shadow_crste(mc, sg, saddr, host, table, entries + LEVEL_MEM, w->p);
 }
 
 static inline int ___gaccess_shadow_fault(struct kvm_vcpu *vcpu, struct gmap *sg, gpa_t saddr,
index 52d55ddea8d4fcb427b75b3d3aa7b5e4f2fefce9..1d289f8fa3b2098ab259f34b0ab298a237558e0f 100644 (file)
@@ -1000,7 +1000,8 @@ int gmap_pv_destroy_range(struct gmap *gmap, gfn_t start, gfn_t end, bool interr
        return 0;
 }
 
-int gmap_insert_rmap(struct gmap *sg, gfn_t p_gfn, gfn_t r_gfn, int level)
+int gmap_insert_rmap(struct kvm_s390_mmu_cache *mc, struct gmap *sg, gfn_t p_gfn,
+                    gfn_t r_gfn, int level)
 {
        struct vsie_rmap *rmap __free(kvfree) = NULL;
        struct vsie_rmap *temp;
@@ -1010,7 +1011,7 @@ int gmap_insert_rmap(struct gmap *sg, gfn_t p_gfn, gfn_t r_gfn, int level)
        KVM_BUG_ON(!is_shadow(sg), sg->kvm);
        lockdep_assert_held(&sg->host_to_rmap_lock);
 
-       rmap = kzalloc_obj(*rmap, GFP_ATOMIC);
+       rmap = kvm_s390_mmu_cache_alloc_rmap(mc);
        if (!rmap)
                return -ENOMEM;
 
@@ -1057,7 +1058,7 @@ int gmap_protect_rmap(struct kvm_s390_mmu_cache *mc, struct gmap *sg, gfn_t p_gf
        if (level <= TABLE_TYPE_REGION1) {
                bitmask = -1UL << (8 + 11 * level);
                scoped_guard(spinlock, &sg->host_to_rmap_lock)
-                       rc = gmap_insert_rmap(sg, p_gfn, r_gfn & bitmask, level);
+                       rc = gmap_insert_rmap(mc, sg, p_gfn, r_gfn & bitmask, level);
        }
        if (rc)
                return rc;
index 20881e3ce9d86cee1dd8ec196fa27babeff15e06..1c040472f56d7a04ff382fb4d65db0ef5a37925a 100644 (file)
@@ -100,7 +100,8 @@ int gmap_ucas_map(struct gmap *gmap, gfn_t p_gfn, gfn_t c_gfn, unsigned long cou
 void gmap_ucas_unmap(struct gmap *gmap, gfn_t c_gfn, unsigned long count);
 int gmap_enable_skeys(struct gmap *gmap);
 int gmap_pv_destroy_range(struct gmap *gmap, gfn_t start, gfn_t end, bool interruptible);
-int gmap_insert_rmap(struct gmap *sg, gfn_t p_gfn, gfn_t r_gfn, int level);
+int gmap_insert_rmap(struct kvm_s390_mmu_cache *mc, struct gmap *sg, gfn_t p_gfn,
+                    gfn_t r_gfn, int level);
 int gmap_protect_rmap(struct kvm_s390_mmu_cache *mc, struct gmap *sg, gfn_t p_gfn, gfn_t r_gfn,
                      kvm_pfn_t pfn, int level, bool wr);
 void gmap_set_cmma_all_dirty(struct gmap *gmap);