gmap_protect_asce_top_level() write-protects the guest top-level region- or segment-table so that later modifications by the guest are noticed and the shadow is unshadowed. It faults in and protects asce.dt + 1 pages, but the number of pages occupied by the top-level table is given by the table-length field (tl), not by the designation-type field (dt). dt and tl are independent fields of the ASCE: tl + 1 is the size of the table in 4K pages, while dt only encodes the table type. The rest of the code already uses the table length. The guest table walker in walk_guest_tables() bounds the top-level index with asce.tl, and _gmap_handle_vsie_unshadow_event() computes the table extent as [rsto, rsto + guest_asce.tl + 1). Only the protection step uses dt. Whenever tl > dt - for instance a guest using a full four-page segment table (dt == 0, tl == 3) - only dt + 1 pages of the table get write- protected and armed with the vsie notification bit. The remaining pages stay writable, so the guest can modify top-level table entries located in them without triggering gmap_unshadow(). The shadow then keeps stale translations, allowing the lower guest to keep accessing host pages that the upper guest's tables no longer map, breaking isolation between the nested guests. Protect asce.tl + 1 pages, matching the table walker and the unshadow event handler. context.f has room for the maximum of CRST_TABLE_PAGES (4) pages, so the upper bound is unchanged. Fixes: abeb7eb57f16 ("KVM: s390: vsie: Use mmu cache to allocate rmap") Signed-off-by: Naveed Khan --- diff --git a/arch/s390/kvm/gmap.c b/arch/s390/kvm/gmap.c index 77829f787d..e1e734cbc0 100644 --- a/arch/s390/kvm/gmap.c +++ b/arch/s390/kvm/gmap.c @@ -1287,7 +1287,7 @@ static int gmap_protect_asce_top_level(struct kvm_s390_mmu_cache *mc, struct gma /* Pairs with the smp_wmb() in kvm_mmu_invalidate_end(). */ smp_rmb(); - rc = kvm_s390_get_guest_pages(sg->kvm, context.f, asce.rsto, asce.dt + 1, false); + rc = kvm_s390_get_guest_pages(sg->kvm, context.f, asce.rsto, asce.tl + 1, false); if (rc > 0) rc = -EFAULT; if (!rc) -- 2.52.0