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