The quilt patch titled Subject: selftests/mm: let uffd_handle_page_fault() take wp parameter has been removed from the -mm tree. Its filename was selftests-mm-let-uffd_handle_page_fault-take-wp-parameter.patch This patch was dropped because it was merged into the mm-stable branch of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm ------------------------------------------------------ From: Peter Xu <peterx@xxxxxxxxxx> Subject: selftests/mm: let uffd_handle_page_fault() take wp parameter Date: Wed, 12 Apr 2023 12:43:41 -0400 Make the handler optionally apply WP bit when resolving page faults for either missing or minor page faults. This moves towards removing global test_uffdio_wp outside of the common code. Link: https://lkml.kernel.org/r/20230412164341.328618-1-peterx@xxxxxxxxxx Signed-off-by: Peter Xu <peterx@xxxxxxxxxx> Cc: Axel Rasmussen <axelrasmussen@xxxxxxxxxx> Cc: David Hildenbrand <david@xxxxxxxxxx> Cc: Dmitry Safonov <0x7f454c46@xxxxxxxxx> Cc: Mike Kravetz <mike.kravetz@xxxxxxxxxx> Cc: Mike Rapoport (IBM) <rppt@xxxxxxxxxx> Cc: Zach O'Keefe <zokeefe@xxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- tools/testing/selftests/mm/uffd-common.c | 17 +++++++++-------- tools/testing/selftests/mm/uffd-common.h | 6 ++++-- tools/testing/selftests/mm/uffd-stress.c | 16 ++++++++++------ 3 files changed, 23 insertions(+), 16 deletions(-) --- a/tools/testing/selftests/mm/uffd-common.c~selftests-mm-let-uffd_handle_page_fault-take-wp-parameter +++ a/tools/testing/selftests/mm/uffd-common.c @@ -353,7 +353,7 @@ void wp_range(int ufd, __u64 start, __u6 err("clear WP failed: address=0x%"PRIx64, (uint64_t)start); } -static void continue_range(int ufd, __u64 start, __u64 len) +static void continue_range(int ufd, __u64 start, __u64 len, bool wp) { struct uffdio_continue req; int ret; @@ -361,7 +361,7 @@ static void continue_range(int ufd, __u6 req.range.start = start; req.range.len = len; req.mode = 0; - if (test_uffdio_wp) + if (wp) req.mode |= UFFDIO_CONTINUE_MODE_WP; if (ioctl(ufd, UFFDIO_CONTINUE, &req)) @@ -429,7 +429,8 @@ void uffd_handle_page_fault(struct uffd_ area_dst_alias)); for (b = 0; b < page_size; ++b) area[b] = ~area[b]; - continue_range(uffd, msg->arg.pagefault.address, page_size); + continue_range(uffd, msg->arg.pagefault.address, page_size, + args->apply_wp); args->minor_faults++; } else { /* @@ -459,7 +460,7 @@ void uffd_handle_page_fault(struct uffd_ offset = (char *)(unsigned long)msg->arg.pagefault.address - area_dst; offset &= ~(page_size-1); - if (copy_page(uffd, offset)) + if (copy_page(uffd, offset, args->apply_wp)) args->missing_faults++; } } @@ -555,7 +556,7 @@ static void wake_range(int ufd, unsigned addr), exit(1); } -int __copy_page(int ufd, unsigned long offset, bool retry) +int __copy_page(int ufd, unsigned long offset, bool retry, bool wp) { struct uffdio_copy uffdio_copy; @@ -564,7 +565,7 @@ int __copy_page(int ufd, unsigned long o uffdio_copy.dst = (unsigned long) area_dst + offset; uffdio_copy.src = (unsigned long) area_src + offset; uffdio_copy.len = page_size; - if (test_uffdio_wp) + if (wp) uffdio_copy.mode = UFFDIO_COPY_MODE_WP; else uffdio_copy.mode = 0; @@ -587,7 +588,7 @@ int __copy_page(int ufd, unsigned long o return 0; } -int copy_page(int ufd, unsigned long offset) +int copy_page(int ufd, unsigned long offset, bool wp) { - return __copy_page(ufd, offset, false); + return __copy_page(ufd, offset, false, wp); } --- a/tools/testing/selftests/mm/uffd-common.h~selftests-mm-let-uffd_handle_page_fault-take-wp-parameter +++ a/tools/testing/selftests/mm/uffd-common.h @@ -72,6 +72,8 @@ /* Userfaultfd test statistics */ struct uffd_args { int cpu; + /* Whether apply wr-protects when installing pages */ + bool apply_wp; unsigned long missing_faults; unsigned long wp_faults; unsigned long minor_faults; @@ -104,8 +106,8 @@ void userfaultfd_open(uint64_t *features int uffd_read_msg(int ufd, struct uffd_msg *msg); void wp_range(int ufd, __u64 start, __u64 len, bool wp); void uffd_handle_page_fault(struct uffd_msg *msg, struct uffd_args *args); -int __copy_page(int ufd, unsigned long offset, bool retry); -int copy_page(int ufd, unsigned long offset); +int __copy_page(int ufd, unsigned long offset, bool retry, bool wp); +int copy_page(int ufd, unsigned long offset, bool wp); void *uffd_poll_thread(void *arg); #define TEST_ANON 1 --- a/tools/testing/selftests/mm/uffd-stress.c~selftests-mm-let-uffd_handle_page_fault-take-wp-parameter +++ a/tools/testing/selftests/mm/uffd-stress.c @@ -96,6 +96,7 @@ static void uffd_stats_reset(struct uffd for (i = 0; i < n_cpus; i++) { args[i].cpu = i; + args[i].apply_wp = test_uffdio_wp; args[i].missing_faults = 0; args[i].wp_faults = 0; args[i].minor_faults = 0; @@ -155,7 +156,7 @@ static void *locking_thread(void *arg) static int copy_page_retry(int ufd, unsigned long offset) { - return __copy_page(ufd, offset, true); + return __copy_page(ufd, offset, true, test_uffdio_wp); } pthread_mutex_t uffd_read_mutex = PTHREAD_MUTEX_INITIALIZER; @@ -308,7 +309,7 @@ static void sighndl(int sig, siginfo_t * * This also tests UFFD_FEATURE_EVENT_FORK event along with the signal * feature. Using monitor thread, verify no userfault events are generated. */ -static int faulting_process(int signal_test) +static int faulting_process(int signal_test, bool wp) { unsigned long nr; unsigned long long count; @@ -343,7 +344,7 @@ static int faulting_process(int signal_t if (steps == 1) { /* This is a MISSING request */ steps++; - if (copy_page(uffd, offset)) + if (copy_page(uffd, offset, wp)) signalled++; } else { /* This is a WP request */ @@ -507,6 +508,7 @@ static int userfaultfd_events_test(void) true, test_uffdio_wp, false)) err("register failure"); + args.apply_wp = test_uffdio_wp; if (pthread_create(&uffd_mon, &attr, uffd_poll_thread, &args)) err("uffd_poll_thread create"); @@ -515,7 +517,7 @@ static int userfaultfd_events_test(void) err("fork"); if (!pid) - exit(faulting_process(0)); + exit(faulting_process(0, test_uffdio_wp)); waitpid(pid, &err, 0); if (err) @@ -551,11 +553,12 @@ static int userfaultfd_sig_test(void) true, test_uffdio_wp, false)) err("register failure"); - if (faulting_process(1)) + if (faulting_process(1, test_uffdio_wp)) err("faulting process failed"); uffd_test_ops->release_pages(area_dst); + args.apply_wp = test_uffdio_wp; if (pthread_create(&uffd_mon, &attr, uffd_poll_thread, &args)) err("uffd_poll_thread create"); @@ -564,7 +567,7 @@ static int userfaultfd_sig_test(void) err("fork"); if (!pid) - exit(faulting_process(2)); + exit(faulting_process(2, test_uffdio_wp)); waitpid(pid, &err, 0); if (err) @@ -628,6 +631,7 @@ static int userfaultfd_minor_test(void) page_size); } + args.apply_wp = test_uffdio_wp; if (pthread_create(&uffd_mon, &attr, uffd_poll_thread, &args)) err("uffd_poll_thread create"); _ Patches currently in -mm which might be from peterx@xxxxxxxxxx are selftests-mm-allow-allocate_area-to-fail-properly.patch selftests-mm-add-framework-for-uffd-unit-test.patch selftests-mm-move-uffd-pagemap-test-to-unit-test.patch selftests-mm-move-uffd-minor-test-to-unit-test.patch selftests-mm-move-uffd-sig-events-tests-into-uffd-unit-tests.patch selftests-mm-move-zeropage-test-into-uffd-unit-tests.patch selftests-mm-workaround-no-way-to-detect-uffd-minor-wp.patch selftests-mm-allow-uffd-test-to-skip-properly-with-no-privilege.patch selftests-mm-drop-sys-dev-test-in-uffd-stress-test.patch selftests-mm-add-shmem-private-test-to-uffd-stress.patch selftests-mm-add-uffdio-register-ioctls-test.patch mm-hugetlb-fix-uffd-wp-during-fork.patch mm-hugetlb-fix-uffd-wp-bit-lost-when-unsharing-happens.patch selftests-mm-add-a-few-options-for-uffd-unit-test.patch selftests-mm-extend-and-rename-uffd-pagemap-test.patch selftests-mm-rename-cow_extra_libs-to-iouring_extra_libs.patch selftests-mm-add-tests-for-ro-pinning-vs-fork.patch