From: Peter Xu <peterx@redhat.com> Date: 2021-03-04 16:34:11
v2 changes:
- Fix wordings as suggested [MikeR]
- convert ".BR" to ".B" where proper for the patchset [Alex]
- rearrange a few lines in the last two patches where they got messed up
- document more things, e.g. UFFDIO_COPY_MODE_WP; and also on how to resolve a
wr-protect page fault.
There're two features missing in current manpage, namely:
(1) Userfaultfd Thread-ID feature
(2) Userfaultfd write protect mode
There's also a 3rd one which was just contributed from Axel - Axel, I think it
would be great if you can add that part too, probably after the whole
hugetlbfs/shmem minor mode reaches the linux master branch.
Please review, thanks.
Peter Xu (4):
userfaultfd.2: Add UFFD_FEATURE_THREAD_ID docs
userfaultfd.2: Add write-protect mode
ioctl_userfaultfd.2: Add UFFD_FEATURE_THREAD_ID docs
ioctl_userfaultfd.2: Add write-protect mode docs
man2/ioctl_userfaultfd.2 | 81 ++++++++++++++++++++++++++--
man2/userfaultfd.2 | 111 ++++++++++++++++++++++++++++++++++++++-
2 files changed, 187 insertions(+), 5 deletions(-)
--
2.26.2
From: Peter Xu <peterx@redhat.com> Date: 2021-03-04 16:34:11
UFFD_FEATURE_THREAD_ID is supported in Linux 4.14.
Signed-off-by: Peter Xu <peterx@redhat.com>
---
man2/ioctl_userfaultfd.2 | 5 +++++
1 file changed, 5 insertions(+)
@@ -208,6 +208,11 @@ signal will be sent to the faulting process. Applications using this feature will not require the use of a userfaultfd monitor for processing memory accesses to the regions registered with userfaultfd.+.TP+.BRUFFD_FEATURE_THREAD_ID" (since Linux 4.14)"+If this feature bit is set,+.Iuffd_msg.pagefault.feat.ptid+Will be set to the faulted thread ID for each page fault message. .PP The returned .Iioctls
@@ -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+.BUFFDIO_REGISTER_MODE_MISSING+When registered with+.BUFFDIO_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+.BUFFDIO_COPY+or an+.BUFFDIO_ZEROPAGE+ioctl.+.TP+.BUFFDIO_REGISTER_MODE_WP+When registered with+.BUFFDIO_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+.BUFFDIO_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+.BUFFD_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. .SSUserfaultfdoperation After the userfaultfd object is created with .BRuserfaultfd(),
@@ -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..\"+.SSUserfaultfdwrite-protectmode+Since Linux 5.7, userfaultfd supports write-protect mode. The user needs to+first check availability of this feature using+.BUFFDIO_API+ioctl against the feature bit+.BRUFFD_FEATURE_PAGEFAULT_FLAG_WP.+.PP+To register with userfaultfd write-protect mode, the user needs to initiate the+.BUFFDIO_REGISTER+ioctl with mode+.BUFFDIO_REGISTER_MODE_WP+set. Note that it's legal to monitor the same memory range with multiple+modes. For example, the user can do+.BUFFDIO_REGISTER+with the mode set to+.BRUFFDIO_REGISTER_MODE_MISSING\|\UFFDIO_REGISTER_MODE_WP.+When there is only+.BUFFDIO_REGISTER_MODE_WP+registered, the userspace will+.Inot+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+.BUFFDIO_REGISTER+ioctl completed with+.BUFFDIO_REGISTER_MODE_WP+mode set, the user can write-protect any existing memory within the range using+the ioctl+.BUFFDIO_WRITEPROTECT+where+.Iuffdio_writeprotect.mode+should be set to+.BRUFFDIO_WRITEPROTECT_MODE_WP.+.PP+When a write-protect event happens, the userspace will receive a page fault+message whose+.Iuffd_msg.pagefault.flags+will be with+.BUFFD_PAGEFAULT_FLAG_WP+flag set. Note: since only writes can trigger such kind of fault,+write-protect messages will always be with+.BUFFD_PAGEFAULT_FLAG_WRITE+bit set too along with+.BRUFFD_PAGEFAULT_FLAG_WP.+.PP+To resolve a write-protection page fault, the user should initiate another+.BUFFDIO_WRITEPROTECT+ioctl whose+.Iuffd_msg.pagefault.flags+should have the flag+.BRUFFDIO_WRITEPROTECT_MODE_WP+cleared upon the faulted page or range.+.PP+Currently, write-protect mode only supports private anonymous memory. .SSReadingfromtheuserfaultfdstructure Each .BRread(2)
@@ -364,8 +454,12 @@ flag (see .BRioctl_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+.BUFFD_PAGEFAULT_FLAG_WP+If the address is in a range that was registered with the+.BUFFDIO_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 .Ipagefault.feat.pid
@@ -234,6 +234,11 @@ operation is supported. The .BUFFDIO_UNREGISTER operation is supported.+.TP+.B1<<_UFFDIO_WRITEPROTECT+The+.BUFFDIO_WRITEPROTECT+operation is supported. .PP This .BRioctl(2)
@@ -322,9 +327,6 @@ Track page faults on missing pages. .BUFFDIO_REGISTER_MODE_WP Track page faults on write-protected pages. .PP-Currently, the only supported mode is-.BRUFFDIO_REGISTER_MODE_MISSING.-.PP If the operation is successful, the kernel modifies the .Iioctls bit-mask field to indicate which
@@ -443,6 +445,11 @@ operation: .TP .BUFFDIO_COPY_MODE_DONTWAKE Do not wake up the thread that waits for page-fault resolution+.TP+.BUFFDIO_COPY_MODE_WP+Do not set write permission when copying the page. The next write to the page+will trigger a write fault. This can be used in conjunction with write-protect+mode so that there will be another message generated when the page is written again. .PP The .Icopy
@@ -654,6 +661,69 @@ field of the structure was not a multiple of the system page size; or .Ilen was zero; or the specified range was otherwise invalid.+.SSUFFDIO_WRITEPROTECT+(Since Linux 5.7) Do write-protect or write-unprotect for an userfaultfd+registered memory range with mode+.BRUFFDIO_REGISTER_MODE_WP.+.PP+The+.Iargp+argument is a pointer to a+.Iuffdio_range+structure as shown below:+.PP+.in+4n+.EX+struct uffdio_writeprotect {+ struct uffdio_range range; /* Range to change write permission */+ __u64 mode; /* Mode to change write permission */+};+.EE+.in+There're two modes that are supported in this structure:+.TP+.BUFFDIO_WRITEPROTECT_MODE_WP+When this mode bit is set, the ioctl will be a write-protect operation upon the+memory range specified by+.IRrange.+Otherwise it'll be a write-unprotect operation upon the specified range.+.TP+.BUFFDIO_WRITEPROTECT_MODE_DONTWAKE+Do not wake up the thread that waits for page-fault resolution after the+operation. This could only be specified if+.BUFFDIO_WRITEPROTECT_MODE_WP+is not specified (in a resolving stage, not protecting stage).+.PP+This+.BRioctl(2)+operation returns 0 on success.+On error, \-1 is returned and+.Ierrno+is set to indicate the error.+Possible errors include:+.TP+.BEINVAL+The+.Istart+or the+.Ilen+field of the+.Iufdio_range+structure was not a multiple of the system page size; or+.Ilen+was zero; or the specified range was otherwise invalid.+.TP+.BEAGAIN+The process was interrupted and need to retry.+.TP+.BENOENT+The range specified in+.Irange+is not valid. E.g., the virtual address does not exist, or not registered with+userfaultfd write-protect mode.+.TP+.BEFAULT+Encountered a generic fault during processing. .SHRETURNVALUE See descriptions of the individual operations, above. .SHERRORS
From: Peter Xu <peterx@redhat.com> Date: 2021-03-04 16:34:14
UFFD_FEATURE_THREAD_ID is supported since Linux 4.14.
Signed-off-by: Peter Xu <peterx@redhat.com>
---
man2/userfaultfd.2 | 13 +++++++++++++
1 file changed, 13 insertions(+)
@@ -77,6 +77,13 @@ When the last file descriptor referring to a userfaultfd object is closed, all memory ranges that were registered with the object are unregistered and unread events are flushed..\"+.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+.BRUFFD_FEATURE_THREAD_ID+feature bit when initializing the userfaultfd context. By default, thread ID+reporting is diabled. .SSUsage The userfaultfd mechanism is designed to allow a thread in a multithreaded program to perform user-space paging for the other threads in the process.
@@ -229,6 +236,9 @@ struct uffd_msg { struct { __u64 flags; /* Flags describing fault */ __u64 address; /* Faulting address */+ union {+ __u32 ptid; /* Thread ID of the fault */+ } feat; } pagefault; struct { /* Since Linux 4.11 */
@@ -358,6 +368,9 @@ otherwise it is a read fault..\" UFFD_PAGEFAULT_FLAG_WP is not yet supported. .RE .TP+.Ipagefault.feat.pid+The thread ID that triggered the page fault.+.TP .Ifork.ufd The file descriptor associated with the userfault object created for the child created by
From: Axel Rasmussen <axelrasmussen@google.com> Date: 2021-03-04 17:57:00
On Thu, Mar 4, 2021 at 8:31 AM Peter Xu [off-list ref] wrote:
v2 changes:
- Fix wordings as suggested [MikeR]
- convert ".BR" to ".B" where proper for the patchset [Alex]
- rearrange a few lines in the last two patches where they got messed up
- document more things, e.g. UFFDIO_COPY_MODE_WP; and also on how to resolve a
wr-protect page fault.
There're two features missing in current manpage, namely:
(1) Userfaultfd Thread-ID feature
(2) Userfaultfd write protect mode
There's also a 3rd one which was just contributed from Axel - Axel, I think it
would be great if you can add that part too, probably after the whole
hugetlbfs/shmem minor mode reaches the linux master branch.
Ack, this is on my list of "todos". Agree it makes sense to wait until
the code is in Linus' tree, then I'll send a patch for the man pages.
@@ -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.
quoted hunk
+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
quoted hunk
+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
@@ -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:
@@ -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-.BUFFDIO_REGISTER_MODE_MISSING+.BRUFFDIO_REGISTER_MODE_MISSING" (since 4.10)" When registered with .BUFFDIO_REGISTER_MODE_MISSING mode, the userspace will receive a page fault message when a missing page is
@@ -91,7 +91,7 @@ or an .BUFFDIO_ZEROPAGE ioctl. .TP-.BUFFDIO_REGISTER_MODE_WP+.BRUFFDIO_REGISTER_MODE_WP" (since 5.7)" When registered with .BUFFDIO_REGISTER_MODE_WP mode, the userspace will receive a page fault message when a write-protected
quoted
+.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.
quoted
+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.
quoted
+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