diff mbox series

[v2,2/4] userfaultfd.2: Add write-protect mode

Message ID 20210304163140.543171-3-peterx@redhat.com (mailing list archive)
State New, archived
Headers show
Series man2: udpate mm/userfaultfd manpages to latest | expand

Commit Message

Peter Xu March 4, 2021, 4:31 p.m. UTC
Write-protect mode is supported starting from Linux 5.7.

Signed-off-by: Peter Xu <peterx@redhat.com>
---
 man2/userfaultfd.2 | 98 +++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 96 insertions(+), 2 deletions(-)

Comments

Alejandro Colomar March 10, 2021, 7:16 p.m. UTC | #1
Hi Peter,

Please see a few comments below.

Thanks,

Alex

On 3/4/21 5:31 PM, Peter Xu wrote:
> Write-protect mode is supported starting from Linux 5.7.
> 
> Signed-off-by: Peter Xu <peterx@redhat.com>
> ---
>   man2/userfaultfd.2 | 98 +++++++++++++++++++++++++++++++++++++++++++++-
>   1 file changed, 96 insertions(+), 2 deletions(-)
> 
> diff --git a/man2/userfaultfd.2 b/man2/userfaultfd.2
> index 0cd426a8a..426307bcf 100644
> --- a/man2/userfaultfd.2
> +++ b/man2/userfaultfd.2
> @@ -78,6 +78,30 @@ all memory ranges that were registered with the object are unregistered
>   and unread events are flushed.
>   .\"
>   .PP
> +Currently, userfaultfd supports two modes of registration:

"Currently"

Than word is quite unstable and unprecise.
I think it would be better to use an absolute reference, such as "Since 
Linux x.y, ...".

> +.TP
> +.B UFFDIO_REGISTER_MODE_MISSING
> +When registered with
> +.B UFFDIO_REGISTER_MODE_MISSING
> +mode, the userspace will receive a page fault message when a missing page is
> +accessed.  The faulted thread will be stopped from execution until the page
> +fault is resolved from the userspace by either an
> +.B UFFDIO_COPY
> +or an
> +.B UFFDIO_ZEROPAGE
> +ioctl.
> +.TP
> +.B UFFDIO_REGISTER_MODE_WP
> +When registered with
> +.B UFFDIO_REGISTER_MODE_WP
> +mode, the userspace will receive a page fault message when a write-protected
> +page is written.  The faulted thread will be stopped from execution until the

Please, use "semantic newlines".

$ man 7 man-pages |sed -n '/semantic newlines/,/^$/p'
    Use semantic newlines
        In the source of a manual page,  new  sentences  should  be
        started  on new lines, and long sentences should split into
        lines at clause breaks (commas, semicolons, colons, and  so
        on).   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 or sen-
        tence clauses.



> +userspace un-write-protect the page using an
> +.B UFFDIO_WRITEPROTECT
> +ioctl.
> +.PP
> +Multiple modes can be enabled at the same time for the same memory range.
> +.PP
>   Since Linux 4.14, userfaultfd page fault message can selectively embed faulting
>   thread ID information into the fault message.  One needs to enable this feature
>   explicitly using the
> @@ -144,6 +168,16 @@ single threaded non-cooperative userfaultfd manager implementations.
>   .\" and limitations remaining in 4.11
>   .\" Maybe it's worth adding a dedicated sub-section...
>   .\"
> +.PP
> +Starting from Linux 5.7, userfaultfd is able to do synchronous page dirty
> +tracking using the new write-protection register mode.  One should check
> +against the feature bit
> +.B UFFD_FEATURE_PAGEFAULT_FLAG_WP
> +before using this feature.  Similar to the original userfaultfd missing mode,
> +the write-protect mode will generate an userfaultfd message when the protected
> +page is written.  The user needs to resolve the page fault by unprotecting the
> +faulted page and kick the faulted thread to continue.  For more information,
> +please read the "Userfaultfd write-protect mode" section below.
>   .SS Userfaultfd operation
>   After the userfaultfd object is created with
>   .BR userfaultfd (),
> @@ -219,6 +253,62 @@ userfaultfd can be used only with anonymous private memory mappings.
>   Since Linux 4.11,
>   userfaultfd can be also used with hugetlbfs and shared memory mappings.
>   .\"
> +.SS Userfaultfd write-protect mode
> +Since Linux 5.7, userfaultfd supports write-protect mode.  The user needs to
> +first check availability of this feature using
> +.B UFFDIO_API
> +ioctl against the feature bit
> +.BR UFFD_FEATURE_PAGEFAULT_FLAG_WP .
> +.PP
> +To register with userfaultfd write-protect mode, the user needs to initiate the
> +.B UFFDIO_REGISTER
> +ioctl with mode
> +.B UFFDIO_REGISTER_MODE_WP
> +set.  Note that it's legal to monitor the same memory range with multiple
> +modes.  For example, the user can do
> +.B UFFDIO_REGISTER
> +with the mode set to
> +.BR UFFDIO_REGISTER_MODE_MISSING\ |\ UFFDIO_REGISTER_MODE_WP .

Please use quotes when possible:

.BR "asdasd asdsadf dfgsdfg dsf" .

> +When there is only
> +.B UFFDIO_REGISTER_MODE_WP
> +registered, the userspace will
> +.I not
> +receive any message when a missing page is written.  Instead, the userspace
> +will only receive a write-protect page fault message when an existing but
> +write-protected page got written.
> +.PP
> +After the
> +.B UFFDIO_REGISTER
> +ioctl completed with
> +.B UFFDIO_REGISTER_MODE_WP
> +mode set, the user can write-protect any existing memory within the range using
> +the ioctl
> +.B UFFDIO_WRITEPROTECT
> +where
> +.I uffdio_writeprotect.mode
> +should be set to
> +.BR UFFDIO_WRITEPROTECT_MODE_WP .
> +.PP
> +When a write-protect event happens, the userspace will receive a page fault
> +message whose
> +.I uffd_msg.pagefault.flags
> +will be with
> +.B UFFD_PAGEFAULT_FLAG_WP
> +flag set.  Note: since only writes can trigger such kind of fault,
> +write-protect messages will always be with
> +.B UFFD_PAGEFAULT_FLAG_WRITE
> +bit set too along with
> +.BR UFFD_PAGEFAULT_FLAG_WP .
> +.PP
> +To resolve a write-protection page fault, the user should initiate another
> +.B UFFDIO_WRITEPROTECT
> +ioctl whose
> +.I uffd_msg.pagefault.flags
> +should have the flag
> +.BR UFFDIO_WRITEPROTECT_MODE_WP

.B

> +cleared upon the faulted page or range.
> +.PP
> +Currently, write-protect mode only supports private anonymous memory.
>   .SS Reading from the userfaultfd structure
>   Each
>   .BR read (2)
> @@ -364,8 +454,12 @@ flag (see
>   .BR ioctl_userfaultfd (2))
>   and this flag is set, this a write fault;
>   otherwise it is a read fault.
> -.\"
> -.\" UFFD_PAGEFAULT_FLAG_WP is not yet supported.
> +.TP
> +.B UFFD_PAGEFAULT_FLAG_WP
> +If the address is in a range that was registered with the
> +.B UFFDIO_REGISTER_MODE_WP
> +flag, when this bit is set it means it's a write-protect fault.  Otherwise it's
> +a page missing fault.
>   .RE
>   .TP
>   .I pagefault.feat.pid
>
Peter Xu March 10, 2021, 9:46 p.m. UTC | #2
On Wed, Mar 10, 2021 at 08:16:24PM +0100, Alejandro Colomar (man-pages) wrote:
> Hi Peter,
> 
> Please see a few comments below.
> 
> Thanks,
> 
> Alex
> 
> On 3/4/21 5:31 PM, Peter Xu wrote:
> > Write-protect mode is supported starting from Linux 5.7.
> > 
> > Signed-off-by: Peter Xu <peterx@redhat.com>
> > ---
> >   man2/userfaultfd.2 | 98 +++++++++++++++++++++++++++++++++++++++++++++-
> >   1 file changed, 96 insertions(+), 2 deletions(-)
> > 
> > diff --git a/man2/userfaultfd.2 b/man2/userfaultfd.2
> > index 0cd426a8a..426307bcf 100644
> > --- a/man2/userfaultfd.2
> > +++ b/man2/userfaultfd.2
> > @@ -78,6 +78,30 @@ all memory ranges that were registered with the object are unregistered
> >   and unread events are flushed.
> >   .\"
> >   .PP
> > +Currently, userfaultfd supports two modes of registration:
> 
> "Currently"
> 
> Than word is quite unstable and unprecise.
> I think it would be better to use an absolute reference, such as "Since
> Linux x.y, ...".

I decided to remove the "Currently" and put the "(since x.y)" into each mode:

diff --git a/man2/userfaultfd.2 b/man2/userfaultfd.2
index 426307bcf..1132f52a3 100644
--- a/man2/userfaultfd.2
+++ b/man2/userfaultfd.2
@@ -78,9 +78,9 @@ all memory ranges that were registered with the object are unregistered
 and unread events are flushed.
 .\"
 .PP
-Currently, userfaultfd supports two modes of registration:
+Userfaultfd supports two modes of registration:
 .TP
-.B UFFDIO_REGISTER_MODE_MISSING
+.BR UFFDIO_REGISTER_MODE_MISSING " (since 4.10)"
 When registered with
 .B UFFDIO_REGISTER_MODE_MISSING
 mode, the userspace will receive a page fault message when a missing page is
@@ -91,7 +91,7 @@ or an
 .B UFFDIO_ZEROPAGE
 ioctl.
 .TP
-.B UFFDIO_REGISTER_MODE_WP
+.BR UFFDIO_REGISTER_MODE_WP " (since 5.7)"
 When registered with
 .B UFFDIO_REGISTER_MODE_WP
 mode, the userspace will receive a page fault message when a write-protected

> 
> > +.TP
> > +.B UFFDIO_REGISTER_MODE_MISSING
> > +When registered with
> > +.B UFFDIO_REGISTER_MODE_MISSING
> > +mode, the userspace will receive a page fault message when a missing page is
> > +accessed.  The faulted thread will be stopped from execution until the page
> > +fault is resolved from the userspace by either an
> > +.B UFFDIO_COPY
> > +or an
> > +.B UFFDIO_ZEROPAGE
> > +ioctl.
> > +.TP
> > +.B UFFDIO_REGISTER_MODE_WP
> > +When registered with
> > +.B UFFDIO_REGISTER_MODE_WP
> > +mode, the userspace will receive a page fault message when a write-protected
> > +page is written.  The faulted thread will be stopped from execution until the
> 
> Please, use "semantic newlines".
> 
> $ man 7 man-pages |sed -n '/semantic newlines/,/^$/p'
>    Use semantic newlines
>        In the source of a manual page,  new  sentences  should  be
>        started  on new lines, and long sentences should split into
>        lines at clause breaks (commas, semicolons, colons, and  so
>        on).   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 or sen-
>        tence clauses.

Will do.

> 
> 
> 
> > +userspace un-write-protect the page using an
> > +.B UFFDIO_WRITEPROTECT
> > +ioctl.
> > +.PP
> > +Multiple modes can be enabled at the same time for the same memory range.
> > +.PP
> >   Since Linux 4.14, userfaultfd page fault message can selectively embed faulting
> >   thread ID information into the fault message.  One needs to enable this feature
> >   explicitly using the
> > @@ -144,6 +168,16 @@ single threaded non-cooperative userfaultfd manager implementations.
> >   .\" and limitations remaining in 4.11
> >   .\" Maybe it's worth adding a dedicated sub-section...
> >   .\"
> > +.PP
> > +Starting from Linux 5.7, userfaultfd is able to do synchronous page dirty
> > +tracking using the new write-protection register mode.  One should check
> > +against the feature bit
> > +.B UFFD_FEATURE_PAGEFAULT_FLAG_WP
> > +before using this feature.  Similar to the original userfaultfd missing mode,
> > +the write-protect mode will generate an userfaultfd message when the protected
> > +page is written.  The user needs to resolve the page fault by unprotecting the
> > +faulted page and kick the faulted thread to continue.  For more information,
> > +please read the "Userfaultfd write-protect mode" section below.
> >   .SS Userfaultfd operation
> >   After the userfaultfd object is created with
> >   .BR userfaultfd (),
> > @@ -219,6 +253,62 @@ userfaultfd can be used only with anonymous private memory mappings.
> >   Since Linux 4.11,
> >   userfaultfd can be also used with hugetlbfs and shared memory mappings.
> >   .\"
> > +.SS Userfaultfd write-protect mode
> > +Since Linux 5.7, userfaultfd supports write-protect mode.  The user needs to
> > +first check availability of this feature using
> > +.B UFFDIO_API
> > +ioctl against the feature bit
> > +.BR UFFD_FEATURE_PAGEFAULT_FLAG_WP .
> > +.PP
> > +To register with userfaultfd write-protect mode, the user needs to initiate the
> > +.B UFFDIO_REGISTER
> > +ioctl with mode
> > +.B UFFDIO_REGISTER_MODE_WP
> > +set.  Note that it's legal to monitor the same memory range with multiple
> > +modes.  For example, the user can do
> > +.B UFFDIO_REGISTER
> > +with the mode set to
> > +.BR UFFDIO_REGISTER_MODE_MISSING\ |\ UFFDIO_REGISTER_MODE_WP .
> 
> Please use quotes when possible:
> 
> .BR "asdasd asdsadf dfgsdfg dsf" .

Fixed.

> 
> > +When there is only
> > +.B UFFDIO_REGISTER_MODE_WP
> > +registered, the userspace will
> > +.I not
> > +receive any message when a missing page is written.  Instead, the userspace
> > +will only receive a write-protect page fault message when an existing but
> > +write-protected page got written.
> > +.PP
> > +After the
> > +.B UFFDIO_REGISTER
> > +ioctl completed with
> > +.B UFFDIO_REGISTER_MODE_WP
> > +mode set, the user can write-protect any existing memory within the range using
> > +the ioctl
> > +.B UFFDIO_WRITEPROTECT
> > +where
> > +.I uffdio_writeprotect.mode
> > +should be set to
> > +.BR UFFDIO_WRITEPROTECT_MODE_WP .
> > +.PP
> > +When a write-protect event happens, the userspace will receive a page fault
> > +message whose
> > +.I uffd_msg.pagefault.flags
> > +will be with
> > +.B UFFD_PAGEFAULT_FLAG_WP
> > +flag set.  Note: since only writes can trigger such kind of fault,
> > +write-protect messages will always be with
> > +.B UFFD_PAGEFAULT_FLAG_WRITE
> > +bit set too along with
> > +.BR UFFD_PAGEFAULT_FLAG_WP .
> > +.PP
> > +To resolve a write-protection page fault, the user should initiate another
> > +.B UFFDIO_WRITEPROTECT
> > +ioctl whose
> > +.I uffd_msg.pagefault.flags
> > +should have the flag
> > +.BR UFFDIO_WRITEPROTECT_MODE_WP
> 
> .B

Fixed.

Thanks,
diff mbox series

Patch

diff --git a/man2/userfaultfd.2 b/man2/userfaultfd.2
index 0cd426a8a..426307bcf 100644
--- a/man2/userfaultfd.2
+++ b/man2/userfaultfd.2
@@ -78,6 +78,30 @@  all memory ranges that were registered with the object are unregistered
 and unread events are flushed.
 .\"
 .PP
+Currently, userfaultfd supports two modes of registration:
+.TP
+.B UFFDIO_REGISTER_MODE_MISSING
+When registered with
+.B UFFDIO_REGISTER_MODE_MISSING
+mode, the userspace will receive a page fault message when a missing page is
+accessed.  The faulted thread will be stopped from execution until the page
+fault is resolved from the userspace by either an
+.B UFFDIO_COPY
+or an
+.B UFFDIO_ZEROPAGE
+ioctl.
+.TP
+.B UFFDIO_REGISTER_MODE_WP
+When registered with
+.B UFFDIO_REGISTER_MODE_WP
+mode, the userspace will receive a page fault message when a write-protected
+page is written.  The faulted thread will be stopped from execution until the
+userspace un-write-protect the page using an
+.B UFFDIO_WRITEPROTECT
+ioctl.
+.PP
+Multiple modes can be enabled at the same time for the same memory range.
+.PP
 Since Linux 4.14, userfaultfd page fault message can selectively embed faulting
 thread ID information into the fault message.  One needs to enable this feature
 explicitly using the
@@ -144,6 +168,16 @@  single threaded non-cooperative userfaultfd manager implementations.
 .\" and limitations remaining in 4.11
 .\" Maybe it's worth adding a dedicated sub-section...
 .\"
+.PP
+Starting from Linux 5.7, userfaultfd is able to do synchronous page dirty
+tracking using the new write-protection register mode.  One should check
+against the feature bit
+.B UFFD_FEATURE_PAGEFAULT_FLAG_WP
+before using this feature.  Similar to the original userfaultfd missing mode,
+the write-protect mode will generate an userfaultfd message when the protected
+page is written.  The user needs to resolve the page fault by unprotecting the
+faulted page and kick the faulted thread to continue.  For more information,
+please read the "Userfaultfd write-protect mode" section below.
 .SS Userfaultfd operation
 After the userfaultfd object is created with
 .BR userfaultfd (),
@@ -219,6 +253,62 @@  userfaultfd can be used only with anonymous private memory mappings.
 Since Linux 4.11,
 userfaultfd can be also used with hugetlbfs and shared memory mappings.
 .\"
+.SS Userfaultfd write-protect mode
+Since Linux 5.7, userfaultfd supports write-protect mode.  The user needs to
+first check availability of this feature using
+.B UFFDIO_API
+ioctl against the feature bit
+.BR UFFD_FEATURE_PAGEFAULT_FLAG_WP .
+.PP
+To register with userfaultfd write-protect mode, the user needs to initiate the
+.B UFFDIO_REGISTER
+ioctl with mode
+.B UFFDIO_REGISTER_MODE_WP
+set.  Note that it's legal to monitor the same memory range with multiple
+modes.  For example, the user can do
+.B UFFDIO_REGISTER
+with the mode set to
+.BR UFFDIO_REGISTER_MODE_MISSING\ |\ UFFDIO_REGISTER_MODE_WP .
+When there is only
+.B UFFDIO_REGISTER_MODE_WP
+registered, the userspace will
+.I not
+receive any message when a missing page is written.  Instead, the userspace
+will only receive a write-protect page fault message when an existing but
+write-protected page got written.
+.PP
+After the
+.B UFFDIO_REGISTER
+ioctl completed with
+.B UFFDIO_REGISTER_MODE_WP
+mode set, the user can write-protect any existing memory within the range using
+the ioctl
+.B UFFDIO_WRITEPROTECT
+where
+.I uffdio_writeprotect.mode
+should be set to
+.BR UFFDIO_WRITEPROTECT_MODE_WP .
+.PP
+When a write-protect event happens, the userspace will receive a page fault
+message whose
+.I uffd_msg.pagefault.flags
+will be with
+.B UFFD_PAGEFAULT_FLAG_WP
+flag set.  Note: since only writes can trigger such kind of fault,
+write-protect messages will always be with
+.B UFFD_PAGEFAULT_FLAG_WRITE
+bit set too along with
+.BR UFFD_PAGEFAULT_FLAG_WP .
+.PP
+To resolve a write-protection page fault, the user should initiate another
+.B UFFDIO_WRITEPROTECT
+ioctl whose
+.I uffd_msg.pagefault.flags
+should have the flag
+.BR UFFDIO_WRITEPROTECT_MODE_WP
+cleared upon the faulted page or range.
+.PP
+Currently, write-protect mode only supports private anonymous memory.
 .SS Reading from the userfaultfd structure
 Each
 .BR read (2)
@@ -364,8 +454,12 @@  flag (see
 .BR ioctl_userfaultfd (2))
 and this flag is set, this a write fault;
 otherwise it is a read fault.
-.\"
-.\" UFFD_PAGEFAULT_FLAG_WP is not yet supported.
+.TP
+.B UFFD_PAGEFAULT_FLAG_WP
+If the address is in a range that was registered with the
+.B UFFDIO_REGISTER_MODE_WP
+flag, when this bit is set it means it's a write-protect fault.  Otherwise it's
+a page missing fault.
 .RE
 .TP
 .I pagefault.feat.pid