Subject: Re: linux-next: KVM/s390x regression

From: Claudio Imbrenda <[email-masked]>
Date: Mon, 27 Oct 2025 17:47:26 +0100

On Mon, 20 Oct 2025 10:41:28 +0200
David Hildenbrand <[email-masked]> 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