On 27.10.25 17:47, Claudio Imbrenda wrote:
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;
Probably worth adding a comment. I remember we don't reuse this bit as a
SW bit in gmap code, right?
}
} 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.
Yeah, I looked into hand-coding the PTL lookup but it just gets nasty
real quick.
I think it's a good enough fix for now, pending the rewrite, which I
hope to get in the next merge window
Agreed.
--
Cheers
David / dhildenb