linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Guillaume Morin <guillaume@morinfr.org>
To: Nathan Chancellor <nathan@kernel.org>
Cc: Guillaume Morin <guillaume@morinfr.org>,
	Heiko Carstens <hca@linux.ibm.com>,
	Vasily Gorbik <gor@linux.ibm.com>,
	Alexander Gordeev <agordeev@linux.ibm.com>,
	linux-kernel@vger.kernel.org, linux-mm@kvack.org,
	Muchun Song <muchun.song@linux.dev>,
	Andrew Morton <akpm@linux-foundation.org>,
	Peter Xu <peterx@redhat.com>,
	David Hildenbrand <david@redhat.com>,
	Eric Hagberg <ehagberg@janestreet.com>,
	linux-s390@vger.kernel.org
Subject: Re: [PATCH v3] mm/hugetlb: support FOLL_FORCE|FOLL_WRITE
Date: Fri, 6 Dec 2024 06:27:09 +0100	[thread overview]
Message-ID: <Z1KLLXpzrDac-oqF@bender.morinfr.org> (raw)
In-Reply-To: <20241206045019.GA2215843@thelio-3990X>

On 05 Dec 21:50, Nathan Chancellor wrote:
>
> Hi Guillaume and s390 folks,
> 
> On Thu, Dec 05, 2024 at 03:02:26AM +0100, Guillaume Morin wrote:
> > 
> > Eric reported that PTRACE_POKETEXT fails when applications use hugetlb
> > for mapping text using huge pages. Before commit 1d8d14641fd9
> > ("mm/hugetlb: support write-faults in shared mappings"), PTRACE_POKETEXT
> > worked by accident, but it was buggy and silently ended up mapping pages
> > writable into the page tables even though VM_WRITE was not set.
> > 
> > In general, FOLL_FORCE|FOLL_WRITE does currently not work with hugetlb.
> > Let's implement FOLL_FORCE|FOLL_WRITE properly for hugetlb, such that
> > what used to work in the past by accident now properly works, allowing
> > applications using hugetlb for text etc. to get properly debugged.
> > 
> > This change might also be required to implement uprobes support for
> > hugetlb [1].
> > 
> > [1] https://lore.kernel.org/lkml/ZiK50qob9yl5e0Xz@bender.morinfr.org/
> > 
> > Cc: Muchun Song <muchun.song@linux.dev>
> > Cc: Andrew Morton <akpm@linux-foundation.org>
> > Cc: Peter Xu <peterx@redhat.com>
> > Cc: David Hildenbrand <david@redhat.com>
> > Cc: Eric Hagberg <ehagberg@janestreet.com>
> > Signed-off-by: Guillaume Morin <guillaume@morinfr.org>
> > ---
> >  Changes in v2:
> >   - Improved commit message
> >  Changes in v3:
> >   - Fix potential unitialized mem access in follow_huge_pud
> >   - define pud_soft_dirty when soft dirty is not enabled
> > 
> >  include/linux/pgtable.h |  5 +++
> >  mm/gup.c                | 99 +++++++++++++++++++++--------------------
> >  mm/hugetlb.c            | 20 +++++----
> >  3 files changed, 66 insertions(+), 58 deletions(-)
> > 
> > diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
> > index adef9d6e9b1b..9335d7c82d20 100644
> > --- a/include/linux/pgtable.h
> > +++ b/include/linux/pgtable.h
> > @@ -1422,6 +1422,11 @@ static inline int pmd_soft_dirty(pmd_t pmd)
> >  	return 0;
> >  }
> >  
> > +static inline int pud_soft_dirty(pud_t pud)
> > +{
> > +	return 0;
> > +}
> > +
> >  static inline pte_t pte_mksoft_dirty(pte_t pte)
> >  {
> >  	return pte;
> > diff --git a/mm/gup.c b/mm/gup.c
> > index 746070a1d8bf..cc3eae458013 100644
> > --- a/mm/gup.c
> > +++ b/mm/gup.c
> > @@ -587,6 +587,33 @@ static struct folio *try_grab_folio_fast(struct page *page, int refs,
> >  }
> >  #endif	/* CONFIG_HAVE_GUP_FAST */
> >  
> > +/* Common code for can_follow_write_* */
> > +static inline bool can_follow_write_common(struct page *page,
> > +		struct vm_area_struct *vma, unsigned int flags)
> > +{
> > +	/* Maybe FOLL_FORCE is set to override it? */
> > +	if (!(flags & FOLL_FORCE))
> > +		return false;
> > +
> > +	/* But FOLL_FORCE has no effect on shared mappings */
> > +	if (vma->vm_flags & (VM_MAYSHARE | VM_SHARED))
> > +		return false;
> > +
> > +	/* ... or read-only private ones */
> > +	if (!(vma->vm_flags & VM_MAYWRITE))
> > +		return false;
> > +
> > +	/* ... or already writable ones that just need to take a write fault */
> > +	if (vma->vm_flags & VM_WRITE)
> > +		return false;
> > +
> > +	/*
> > +	 * See can_change_pte_writable(): we broke COW and could map the page
> > +	 * writable if we have an exclusive anonymous page ...
> > +	 */
> > +	return page && PageAnon(page) && PageAnonExclusive(page);
> > +}
> > +
> >  static struct page *no_page_table(struct vm_area_struct *vma,
> >  				  unsigned int flags, unsigned long address)
> >  {
> > @@ -613,6 +640,22 @@ static struct page *no_page_table(struct vm_area_struct *vma,
> >  }
> >  
> >  #ifdef CONFIG_PGTABLE_HAS_HUGE_LEAVES
> > +/* FOLL_FORCE can write to even unwritable PUDs in COW mappings. */
> > +static inline bool can_follow_write_pud(pud_t pud, struct page *page,
> > +					struct vm_area_struct *vma,
> > +					unsigned int flags)
> > +{
> > +	/* If the pud is writable, we can write to the page. */
> > +	if (pud_write(pud))
> > +		return true;
> > +
> > +	if (!can_follow_write_common(page, vma, flags))
> > +		return false;
> > +
> > +	/* ... and a write-fault isn't required for other reasons. */
> > +	return !vma_soft_dirty_enabled(vma) || pud_soft_dirty(pud);
> 
> This looks to be one of the first uses of pud_soft_dirty() in a generic
> part of the tree from what I can tell, which shows that s390 is lacking
> it despite setting CONFIG_HAVE_ARCH_SOFT_DIRTY:
> 
>   $ make -skj"$(nproc)" ARCH=s390 CROSS_COMPILE=s390-linux- mrproper defconfig mm/gup.o
>   mm/gup.c: In function 'can_follow_write_pud':
>   mm/gup.c:665:48: error: implicit declaration of function 'pud_soft_dirty'; did you mean 'pmd_soft_dirty'? [-Wimplicit-function-declaration]
>     665 |         return !vma_soft_dirty_enabled(vma) || pud_soft_dirty(pud);
>         |                                                ^~~~~~~~~~~~~~
>         |                                                pmd_soft_dirty
> 
> Is this expected?

Yikes! It does look like an oversight in the s390 code since as you said
it has CONFIG_HAVE_ARCH_SOFT_DIRTY and pud_mkdirty seems to be setting
_REGION3_ENTRY_SOFT_DIRTY. But I'll let the s390 folks opine.

I don't mind dropping the pud part of the change (even if that's a bit
of a shame) if it's causing too many issues.

-- 
Guillaume Morin <guillaume@morinfr.org>


  reply	other threads:[~2024-12-06  5:27 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-12-05  2:02 Guillaume Morin
2024-12-06  4:50 ` Nathan Chancellor
2024-12-06  5:27   ` Guillaume Morin [this message]
2024-12-06  9:24     ` Heiko Carstens
2024-12-06  9:29       ` David Hildenbrand
2024-12-06 14:52         ` Guillaume Morin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Z1KLLXpzrDac-oqF@bender.morinfr.org \
    --to=guillaume@morinfr.org \
    --cc=agordeev@linux.ibm.com \
    --cc=akpm@linux-foundation.org \
    --cc=david@redhat.com \
    --cc=ehagberg@janestreet.com \
    --cc=gor@linux.ibm.com \
    --cc=hca@linux.ibm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=linux-s390@vger.kernel.org \
    --cc=muchun.song@linux.dev \
    --cc=nathan@kernel.org \
    --cc=peterx@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox