History

userfaultfd: add UFFDIO_CONTINUE ioctl

This ioctl is how userspace ought to resolve "minor" userfaults. The idea is, userspace is notified that a minor fault has occurred. It might change the contents of the page using its second non-UFFD mapping, or not. Then, it calls UFFDIO_CONTINUE to tell the kernel "I have ensured the page contents are correct, carry on setting up the mapping". Note that it doesn't make much sense to use UFFDIO_{COPY,ZEROPAGE} for MINOR registered VMAs. ZEROPAGE maps the VMA to the zero page; but in the minor fault case, we already have some pre-existing underlying page. Likewise, UFFDIO_COPY isn't useful if we have a second non-UFFD mapping. We'd just use memcpy() or similar instead. It turns out hugetlb_mcopy_atomic_pte() already does very close to what we want, if an existing page is provided via `struct page **pagep`. We already special-case the behavior a bit for the UFFDIO_ZEROPAGE case, so just extend that design: add an enum for the three modes of operation, and make the small adjustments needed for the MCOPY_ATOMIC_CONTINUE case. (Basically, look up the existing page, and avoid adding the existing page to the page cache or calling set_page_huge_active() on it.)

Axel Rasmussen committed 5 years ago

Commit f6191471 parent 714c1896 files · +156 −30Browse files

Showing the changes to include/uapi/linux (1 of 6 files). Show all

Unified · Split

include/uapi/linux/userfaultfd.h+19−2
@@ -40,10 +40,12 @@ · 39 unmodified lines
4040 ((__u64)1 << _UFFDIO_WAKE | \
4141 (__u64)1 << _UFFDIO_COPY | \
4242 (__u64)1 << _UFFDIO_ZEROPAGE | \
43− (__u64)1 << _UFFDIO_WRITEPROTECT)
43+ (__u64)1 << _UFFDIO_WRITEPROTECT | \
44+ (__u64)1 << _UFFDIO_CONTINUE)
4445 #define UFFD_API_RANGE_IOCTLS_BASIC \
4546 ((__u64)1 << _UFFDIO_WAKE | \
46− (__u64)1 << _UFFDIO_COPY)
47+ (__u64)1 << _UFFDIO_COPY | \
48+ (__u64)1 << _UFFDIO_CONTINUE)
4749
4850 /*
4951 * Valid ioctl command number range with this API is from 0x00 to
@@ -59,6 +61,7 @@ · 9 unmodified lines
5961 #define _UFFDIO_COPY (0x03)
6062 #define _UFFDIO_ZEROPAGE (0x04)
6163 #define _UFFDIO_WRITEPROTECT (0x06)
64+#define _UFFDIO_CONTINUE (0x07)
6265 #define _UFFDIO_API (0x3F)
6366
6467 /* userfaultfd ioctl ids */
@@ -77,6 +80,8 @@ · 12 unmodified lines
7780 struct uffdio_zeropage)
7881 #define UFFDIO_WRITEPROTECT _IOWR(UFFDIO, _UFFDIO_WRITEPROTECT, \
7982 struct uffdio_writeprotect)
83+#define UFFDIO_CONTINUE _IOR(UFFDIO, _UFFDIO_CONTINUE, \
84+ struct uffdio_continue)
8085
8186 /* read() structure */
8287 struct uffd_msg {
@@ -268,6 +273,18 @@ struct uffdio_writeprotect { · 185 unmodified lines
268273 __u64 mode;
269274 };
270275
276+struct uffdio_continue {
277+ struct uffdio_range range;
278+#define UFFDIO_CONTINUE_MODE_DONTWAKE ((__u64)1<<0)
279+ __u64 mode;
280+
281+ /*
282+ * Fields below here are written by the ioctl and must be at the end:
283+ * the copy_from_user will not read past here.
284+ */
285+ __s64 mapped;
286+};
287+
271288 /*
272289 * Flags for the userfaultfd(2) system call itself.
273290 */