Re: [PATCH man-pages v1 1/6] userfaultfd.2: Add read-write protect mode

Alejandro Colomar <[email protected]> Mon, 25 May 2026 15:53:15 +0200
Newsgroups org.kernel.vger.linux-man,org.kvack.linux-mm
Message-ID <ahRL3DldN7z58vDH@devuan>
Hi Kiryl,

On 2026-05-25T13:28:11+0100, Kiryl Shutsemau wrote:
> From: "Kiryl Shutsemau (Meta)" <[email protected]>
> 
> Read-write protect mode (UFFDIO_REGISTER_MODE_RWP) is supported starting
> from Linux 7.2. It traps every access -- read or write -- to a present
> page within a registered range. The matching UAPI consists of:
> 
>   - UFFDIO_REGISTER_MODE_RWP   registration-mode bit
>   - UFFD_FEATURE_RWP           capability bit
>   - UFFD_FEATURE_RWP_ASYNC     async (in-kernel) fault resolution
>   - UFFDIO_RWPROTECT           install / remove RWP on a range
>   - UFFDIO_SET_MODE            runtime sync/async toggle
>   - UFFD_PAGEFAULT_FLAG_RWP    new pagefault.flags bit
> 
> Document the new registration-mode entry, the "Userfaultfd read-write
> protect mode" section, the new pagefault flag, and a VERSIONS line.
> 
> Signed-off-by: Kiryl Shutsemau <[email protected]>
> ---
>  man/man2/userfaultfd.2 | 152 +++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 148 insertions(+), 4 deletions(-)
> 
> diff --git a/man/man2/userfaultfd.2 b/man/man2/userfaultfd.2
> index 6d56085f1534..a179660f4105 100644
> --- a/man/man2/userfaultfd.2
> +++ b/man/man2/userfaultfd.2
> @@ -111,6 +111,28 @@ The faulted thread will be stopped from execution

Please have a look at the CONTRIBUTING file, and the CONTRIBUTING.d
directory.  In particular, it would be nice to see more useful hunk
contexts, which can be done following this documentation:

<https://git.kernel.org/pub/scm/docs/man-pages/man-pages.git/tree/CONTRIBUTING.d/git#n11>

>  until user-space write-unprotects the page using an
>  .B UFFDIO_WRITEPROTECT
>  ioctl.
> +.TP
> +.BR UFFDIO_REGISTER_MODE_RWP " (since Linux 7.2)"
> +When registered with
> +.B UFFDIO_REGISTER_MODE_RWP
> +mode, user-space will receive a page-fault notification
> +on any access \(em read or write \(em to a present page within the range.

Please use \[em] instead of \(em, and use spaces around them as if they
were parentheses --like this--.

Also, please use semantic newlines.  See man-pages(7):

$ MANWIDTH=64 man man-pages | awk '/Use semantic newlines/,/^$/'
   Use semantic newlines
     In  the  source  of a manual page, new sentences should be
     started on new lines, long sentences should be split  into
     lines at clause breaks (commas, semicolons, colons, and so
     on),  and  long  clauses  should be split at phrase bound‐
     aries.  This convention, sometimes known as "semantic new‐
     lines", makes it easier to  see  the  effect  of  patches,
     which  often operate at the level of individual sentences,
     clauses, or phrases.

That would be:

	When registered with
	.B UFFDIO_REGISTER_MODE_RWP
	mode,
	user-space will receive a page-fault notification
	on any access
	\[em]read or write\[em]
	to a present page within the range.

BTW, about the last line, I think you may want to mean
s/present page/page present/, with inverted order of the words, that is,
the page is present within the range, right?

> +By default the faulted thread will be stopped from execution until

'By default' should be followed by a comma.  Also, because of semantic
newlines, I'd move 'until' to the next line.  Thus:

	By default,
	the faulted thread will be stopped from execution
	until user space removes the protection using a


> +user-space removes the protection using a

We say user space, as two words.  'user-space' is used when it works as
a compound adjective (usual English rules).

> +.B UFFDIO_RWPROTECT
> +ioctl;
> +if
> +.B UFFD_FEATURE_RWP_ASYNC
> +was negotiated, the kernel restores access in place and the faulted
> +thread continues without blocking.

Again semantic newlines:

	...
	was negotiated,
	the kernel restores access in place
	and the faulted thread continues without blocking.

A rule of thumb when separating lines semantically is that it should be
relatively easy to understand full lines without reading the surrounding
lines.

> +.IP
> +.B UFFDIO_REGISTER_MODE_RWP
> +and
> +.B UFFDIO_REGISTER_MODE_WP
> +cannot be combined on the same range; attempting to register with both

Please break the line after the ';' (semantic newlines).

> +bits set returns

s/returns/fails with/

I user space, we transform the return value to an errno code, and return
-1.

> +.BR EINVAL .
> +See the "Userfaultfd read-write protect mode" section below.

This should probably be read-write-protect mode, for consistency with
write-prtect mode.  Or maybe read/write-protect mode.

>  .P
>  Multiple modes can be enabled at the same time for the same memory range.
>  .P
> @@ -192,6 +214,21 @@ The user needs to resolve the page fault by unprotecting the faulted page and
>  kicking the faulted thread to continue.
>  For more information,
>  please refer to the "Userfaultfd write-protect mode" section.
> +.PP

We changed to using .P some years ago.  It works exactly the same, and
is easier to type.

> +Since Linux 7.2, userfaultfd can do read-write protection tracking, which
> +traps every access (read or write) to a present page within a registered
> +range.
> +One should check against the feature bit
> +.B UFFD_FEATURE_RWP
> +before using this feature, and optionally negotiate
> +.B UFFD_FEATURE_RWP_ASYNC
> +to have the kernel auto-restore page permissions on fault without
> +delivering a notification.
> +This mode is intended for working-set tracking by VM memory managers and
> +similar callers; cold pages can then be evicted using independent kernel
> +interfaces.
> +For more information,
> +please refer to the "Userfaultfd read-write protect mode" section.

A lot of semantic newlines needed above.

>  .\"
>  .SS Userfaultfd operation
>  After the userfaultfd object is created with
> @@ -387,6 +424,99 @@ wakes up the faulting thread(s).
>  Minor fault mode supports only hugetlbfs-backed (since Linux 5.13)
>  and shmem-backed (since Linux 5.14) memory.
>  .\"
> +.SS Userfaultfd read-write protect mode (since Linux 7.2)
> +Since Linux 7.2, userfaultfd supports read-write protect mode.
> +Unlike write-protect mode, every access \(em read or write \(em to a

Same thing about \[em] and spacing.

> +protected present page generates a userfaultfd notification.
> +It works on anonymous, shmem, and hugetlbfs mappings.
> +.P
> +The user needs to first check availability of this feature using the
> +.B UFFDIO_API
> +ioctl against the feature bit
> +.B UFFD_FEATURE_RWP
> +before using this mode.
> +See
> +.BR UFFDIO_API (2const)
> +for the recommended discovery sequence.
> +.P
> +To register with userfaultfd read-write protect mode, the user needs to
> +initiate the
> +.B UFFDIO_REGISTER
> +ioctl with mode
> +.B UFFDIO_REGISTER_MODE_RWP
> +set.
> +.B UFFDIO_REGISTER_MODE_RWP
> +cannot be combined with
> +.BR UFFDIO_REGISTER_MODE_WP ;
> +however it can be combined with
> +.B UFFDIO_REGISTER_MODE_MISSING
> +when the caller also wants notifications for fresh page populations.
> +.P
> +After registration, the user can read-write-protect any existing memory
> +within the range using the
> +.B UFFDIO_RWPROTECT
> +ioctl where
> +.I uffdio_rwprotect.mode
> +is set to
> +.BR UFFDIO_RWPROTECT_MODE_RWP .
> +Read-write protection only affects pages that are currently populated
> +in the range; unpopulated addresses remain unpopulated and fall through
> +to the normal missing-page path on first access.
> +.P
> +For anonymous mappings, protection is preserved across page reclaim
> +(the marker rides on the swap entry) and migration.
> +For shmem and file-backed mappings, protection is dropped when the
> +backing page is reclaimed and must be re-armed by the caller.
> +Protection is also
> +.I not
> +preserved across operations that explicitly drop the underlying page
> +.RB ( "MADV_DONTNEED " "on anonymous memory, hole-punch on shmem,"

Huh, this is weird.  Why did you write it this way?

> +truncation of a file mapping).
> +Callers must re-arm the range with
> +.B UFFDIO_RWPROTECT
> +after any such operation.
> +.P
> +When an access fault happens against a protected page, user-space will
> +receive a page-fault notification whose
> +.I uffd_msg.pagefault.flags
> +field has the
> +.B UFFD_PAGEFAULT_FLAG_RWP
> +bit set.
> +.P
> +To resolve a read-write-protect page fault, the user initiates another
> +.B UFFDIO_RWPROTECT
> +ioctl whose
> +.I uffdio_rwprotect.mode
> +has the
> +.B UFFDIO_RWPROTECT_MODE_RWP
> +flag cleared.
> +This restores the original VMA permissions on the affected pages and
> +wakes any blocked threads (unless
> +.B UFFDIO_RWPROTECT_MODE_DONTWAKE
> +is also set).
> +.P
> +If
> +.B UFFD_FEATURE_RWP_ASYNC
> +was negotiated alongside
> +.BR UFFD_FEATURE_RWP ,
> +the kernel resolves access faults in place without delivering a
> +notification: page permissions are restored automatically and the
> +faulting thread continues.
> +Callers can later reconstruct which pages were touched by inspecting the
> +.B PAGE_IS_ACCESSED
> +bit returned by the
> +.B PAGEMAP_SCAN
> +ioctl described in
> +.BR ioctl_userfaultfd (2)
> +and
> +.IR Documentation/admin\-guide/mm/pagemap.rst
> +in the Linux kernel source.
> +.P
> +The async mode can be toggled at runtime using the
> +.B UFFDIO_SET_MODE
> +ioctl, which lets a single userfaultfd switch between async detection
> +and synchronous eviction without re-registering the range.
> +.\"
>  .SS Reading from the userfaultfd structure
>  Each
>  .BR read (2)
> @@ -531,13 +661,17 @@ If this flag is set, then the fault was a write-protect fault.
>  .B UFFD_PAGEFAULT_FLAG_MINOR
>  If this flag is set, then the fault was a minor fault.
>  .TP
> +.BR UFFD_PAGEFAULT_FLAG_RWP " (since Linux 7.2)"
> +If this flag is set, then the fault was a read-write-protect fault.
> +.TP
>  .B UFFD_PAGEFAULT_FLAG_WRITE
>  If this flag is set, then the fault was a write fault.
>  .P
> -If neither
> -.B UFFD_PAGEFAULT_FLAG_WP
> -nor
> -.B UFFD_PAGEFAULT_FLAG_MINOR
> +If none of
> +.BR UFFD_PAGEFAULT_FLAG_WP ,
> +.BR UFFD_PAGEFAULT_FLAG_MINOR ,
> +or
> +.B UFFD_PAGEFAULT_FLAG_RWP
>  are set, then the fault was a missing fault.
>  .RE
>  .TP
> @@ -640,6 +774,16 @@ Linux 4.3.
>  .P
>  Support for hugetlbfs and shared memory areas and
>  non-page-fault events was added in Linux 4.11
> +.P
> +Read-write protect mode
> +.RB ( UFFDIO_REGISTER_MODE_RWP ", " UFFD_FEATURE_RWP ", "

This is weird again.  Please don't have more than one identifier per
line.


Have a lovely day!
Alex

> +.BR UFFDIO_RWPROTECT )
> +was added in Linux 7.2,
> +together with
> +.B UFFD_FEATURE_RWP_ASYNC
> +and the
> +.B UFFDIO_SET_MODE
> +runtime mode toggle.
>  .SH NOTES
>  The userfaultfd mechanism can be used as an alternative to
>  traditional user-space paging techniques based on the use of the
> -- 
> 2.54.0
> 
> 

-- 
<https://www.alejandro-colomar.es>
signature.asc (application/pgp-signature, 833 B)
-----BEGIN PGP SIGNATURE-----

iQIzBAABCgAdFiEES7Jt9u9GbmlWADAi64mZXMKQwqkFAmoUVEAACgkQ64mZXMKQ
wqlU2xAAtUs3SkDf6rA2WBgkZgdfw3E4odZx2d4HMPOKk0o2Eoz+eQ0goe20njUg
EOJIr95mIhglsfPU4fE81TRzC1JLU0GByjM85OqIYbgiuW18amtGKC9FAojFP0Mv
FZa2ELKeeYxtWaS9krRBJXypbS7AFH2awHsUQXFOme88nlBMEZccNLERzHt5XdgL
plZJkbEfz9VFu/ccSvL5hayxwtm1GNejz+d5ueiBnCBIiDVKVemyDU/BMOg6RDy4
VdH2GlgK5+CwNwYfIszxarYqhbZuk95jkZvJfjZ0X8nyN2Bpib+TZbk5nIjDZNOF
mVkIm7G5qAGN/dr0PPGsUPJY0F6J/md/JoFuYzAWEPyojY+5TYgPFC/GpXBigfrM
BD84/CTePpygt7ZGLqVuACKyHepMKDtqafMSjjY/3V0yUt+2/Q7m2TxLm/emdosy
QAJ6daPE4UX3Blx2XZMbZs9bq3utaiktbj5hV9VesRq4VGc/6YJNRhbXQ5VFxOPo
VI0yfOZxsWGxHK2ikDomA5GU/EXevvPvwL3HIZhgzA292pxYY4yPCowsbkYR9AwN
2Ws1Y7JPZ8aNn/nq+za+Tjm6I+eYrX+4LuhlyEus7QzCWRE//L/cyFxqiDT5kJ6+
MTyoBXLrPuTTTExUDEGcQehC+Z6IyKhZKm0yklEI+iSLyvb/Ij0=
=1SBD
-----END PGP SIGNATURE-----