On Mon, 20 Oct 2025 10:41:28 +0200
David Hildenbrand <[email protected]> wrote:
> On 20.10.25 09:00, Christian Borntraeger wrote:
> > Am 17.10.25 um 23:56 schrieb Balbir Singh:
> >
> >> In the meanwhile, does this fix/workaround work?
> >>
> >> diff --git a/mm/pgtable-generic.c b/mm/pgtable-generic.c
> >> index 0c847cdf4fd3..31c1754d5bd4 100644
> >> --- a/mm/pgtable-generic.c
> >> +++ b/mm/pgtable-generic.c
> >> @@ -290,7 +290,7 @@ pte_t *___pte_offset_map(pmd_t *pmd, unsigned long
> >> addr, pmd_t *pmdvalp)
> >>
> >> if (pmdvalp)
> >> *pmdvalp = pmdval;
> >> - if (unlikely(pmd_none(pmdval) || !pmd_present(pmdval)))
> >> + if (unlikely(pmd_none(pmdval) ||
> >> is_pmd_non_present_folio_entry(pmdval)))
> >> goto nomap;
> >> if (unlikely(pmd_trans_huge(pmdval)))
> >> goto nomap;
> >>
> >
> > Yes, this seems to work.
>
> Right, but that's not what we will want here. We'll have to adjust s390x
> gmap code (which is getting redesigned either way) to only take the page
> lock.
>
> In the end, we'll want here later a single
>
> if (!pmd_present(pmdval))
> goto nomap;
>
this seems to do the trick:
diff --git a/arch/s390/mm/gmap.c b/arch/s390/mm/gmap.c
index 8ff6bba107e8..22c448b32340 100644
--- a/arch/s390/mm/gmap.c
+++ b/arch/s390/mm/gmap.c
@@ -599,8 +599,9 @@ int __gmap_link(struct gmap *gmap, unsigned long
gaddr, unsigned long vmaddr) | _SEGMENT_ENTRY_GMAP_UC
| _SEGMENT_ENTRY;
} else
- *table = pmd_val(*pmd) &
- _SEGMENT_ENTRY_HARDWARE_BITS;
+ *table = (pmd_val(*pmd) &
+ _SEGMENT_ENTRY_HARDWARE_BITS)
+ | _SEGMENT_ENTRY;
}
} else if (*table & _SEGMENT_ENTRY_PROTECT &&
!(pmd_val(*pmd) & _SEGMENT_ENTRY_PROTECT)) {
it marks non-leaf gmap segment (pmd) entries as present, just as normal
pmds would be.
I think it's a good enough fix for now, pending the rewrite, which I
hope to get in the next merge window