On Fri, May 29, 2026 at 02:07:16PM +0100, Kiryl Shutsemau wrote:
> On Fri, May 29, 2026 at 08:24:55AM +0100, Lorenzo Stoakes wrote:
> > On Tue, May 26, 2026 at 02:04:56PM +0100, Kiryl Shutsemau wrote:
> > > From: "Kiryl Shutsemau (Meta)" <[email protected]>
> > >
> > > Preparatory patch for userfaultfd read-write protection (RWP). RWP
> > > extends userfaultfd protection from plain write-protection (WP) to
> > > full read-write protection: accesses to an RWP-protected range --
> > > reads as well as writes -- trap through userfaultfd.
> > >
> > > Reserve VM_UFFD_RWP, add the userfaultfd_rwp() and
> > > userfaultfd_protected() helpers, and wire up the smaps "ur" entry and
> > > the trace-flag table the rest of the series will use. The flag is
> > > gated on CONFIG_USERFAULTFD_RWP, which is introduced together with the
> > > UAPI in a later patch; until then VM_UFFD_RWP aliases VM_NONE and
> > > every downstream check folds to dead code.
> > >
> > > Nothing sets or queries the flag yet.
> > >
> > > Signed-off-by: Kiryl Shutsemau <[email protected]>
> > > Assisted-by: Claude:claude-opus-4-6
> >
> > Hm, if you've just used claude to bounce ideas off, I'm really not sure if
> > it's necessary to disclose, though I respect your thoroughness for doing so
> > :)
>
> I've elaborated on how I used Claude in reply to Andrew:
>
> https://lore.kernel.org/all/af5eALk9yO8pPcHv@thinkstation
>
> It is more than bouncing ideas.

Ah interesting! Fair enough then.

>
> > > diff --git a/include/linux/mm.h b/include/linux/mm.h
> > > index 71b11945e4fc..6499cfb61dc4 100644
> > > --- a/include/linux/mm.h
> > > +++ b/include/linux/mm.h
> > > @@ -362,6 +362,7 @@ enum {
> > >  #endif
> > >   DECLARE_VMA_BIT(UFFD_MINOR, 41),
> > >   DECLARE_VMA_BIT(SEALED, 42),
> > > + DECLARE_VMA_BIT(UFFD_RWP, 43),
> >
> > I'm guessing CONFIG_USERFAULTFD_RWP is predicated on CONFIG_64BIT?
>
> Yes:
>       depends on 64BIT && ARCH_HAS_PTE_PROTNONE && HAVE_ARCH_USERFAULTFD_WP
> >
> > It's a silly situation and once my VMA flags stuff is done it'll be
> > eliminated but for now... :)
>
> Yeah. I actually would appreciate your take on 04/18. It is related.

I'll reply there.

>
> > > diff --git a/include/linux/userfaultfd_k.h b/include/linux/userfaultfd_k.h
> > > index f4cf5763f92c..0aef628514df 100644
> > > --- a/include/linux/userfaultfd_k.h
> > > +++ b/include/linux/userfaultfd_k.h
> > > @@ -21,10 +21,11 @@
> > >  #include <linux/hugetlb_inline.h>
> > >
> > >  /* The set of all possible UFFD-related VM flags. */
> > > -#define __VM_UFFD_FLAGS (VM_UFFD_MISSING | VM_UFFD_WP | VM_UFFD_MINOR)
> > > +#define __VM_UFFD_FLAGS (VM_UFFD_MISSING | VM_UFFD_MINOR | \
> > > +                  VM_UFFD_WP | VM_UFFD_RWP)
> > >
> > >  #define __VMA_UFFD_FLAGS mk_vma_flags(VMA_UFFD_MISSING_BIT, 
> > > VMA_UFFD_WP_BIT, \
> > > -                               VMA_UFFD_MINOR_BIT)
> > > +                               VMA_UFFD_MINOR_BIT, VMA_UFFD_RWP_BIT)
> > >
> > >  /*
> > >   * CAREFUL: Check include/uapi/asm-generic/fcntl.h when defining
> > > @@ -178,7 +179,7 @@ static inline bool 
> > > is_mergeable_vm_userfaultfd_ctx(struct vm_area_struct *vma,
> > >   */
> > >  static inline bool uffd_disable_huge_pmd_share(struct vm_area_struct 
> > > *vma)
> > >  {
> > > - return vma->vm_flags & (VM_UFFD_WP | VM_UFFD_MINOR);
> > > + return vma->vm_flags & (VM_UFFD_MINOR | VM_UFFD_WP | VM_UFFD_RWP);
> >
> > While we're here we might as well switch to using the new API?
> >
> > Can do:
> >
> >     return vma_test_any_mask(vma, __VMA_UFFD_FLAGS);
> >
> > One unfortunate thing is using bit values means we can't do the VM_NONE
> > trick, but if !CONFIG_USERFAULTFD_RWP then VMA_UFFD_RWP_BIT wouldn't be set
> > anyway, same for minor so this should be fine?
>
> I think we need to decide first if the 04/18 direction is right.
> We can define VMA_UFFD_RWP_BIT to VMA_NO_BIT if !CONFIG_USERFAULTFD_RWP.

Yeah I don't think that approach is workable unfortunately (see my reply
there).

But I suggest some workarounds there with VMA_UFFD_RWP.

>
> > >  }
> > >
> > >  /*
> > > @@ -208,6 +209,16 @@ static inline bool userfaultfd_minor(struct 
> > > vm_area_struct *vma)
> > >   return vma->vm_flags & VM_UFFD_MINOR;
> > >  }
> > >
> > > +static inline bool userfaultfd_rwp(struct vm_area_struct *vma)
> > > +{
> > > + return vma->vm_flags & VM_UFFD_RWP;
> > > +}
> >
> > Can be:
> >
> >     return vma_test(vma, VMA_UFFD_RWP_BIT);
>
> Yep.

With the approach suggested in 04/18 we could do this as:

        return vma_test_any_mask(vma, VMA_UFFD_RWP);

Which is a bit fugly but will work.

>
>
> --
>   Kiryl Shutsemau / Kirill A. Shutemov

Cheers, Lorenzo

Reply via email to