From 9ade12757182cbdde47145796cf167585b7e3687 Mon Sep 17 00:00:00 2001 From: Lokesh Gidra Date: Fri, 21 May 2021 03:52:12 -0700 Subject: [PATCH] Revert "BACKPORT: FROMGIT: userfaultfd/selftests: add test exercising minor fault handling" This reverts commit 2b2f7d6a04d65c2ebd53f9e5d3de6b55635d57b6 so that it can be re-applied once dependcies are brought in. Signed-off-by: Lokesh Gidra Bug: 187930641 Change-Id: Ib24c94e1d8ec6c46004d35f58e48d9d35eeb8312 --- tools/testing/selftests/vm/userfaultfd.c | 169 ++--------------------- 1 file changed, 10 insertions(+), 159 deletions(-) diff --git a/tools/testing/selftests/vm/userfaultfd.c b/tools/testing/selftests/vm/userfaultfd.c index 5fa64c5cd8c7..f9efa096faf0 100644 --- a/tools/testing/selftests/vm/userfaultfd.c +++ b/tools/testing/selftests/vm/userfaultfd.c @@ -77,8 +77,6 @@ static int test_type; #define ALARM_INTERVAL_SECS 10 static volatile bool test_uffdio_copy_eexist = true; static volatile bool test_uffdio_zeropage_eexist = true; -/* Whether to test uffd minor faults */ -static bool test_uffdio_minor = false; static bool map_shared; static int huge_fd; @@ -269,7 +267,7 @@ static struct uffd_test_ops shmem_uffd_test_ops = { }; static struct uffd_test_ops hugetlb_uffd_test_ops = { - .expected_ioctls = UFFD_API_RANGE_IOCTLS_BASIC & ~(1 << _UFFDIO_CONTINUE), + .expected_ioctls = UFFD_API_RANGE_IOCTLS_BASIC, .allocate_area = hugetlb_allocate_area, .release_pages = hugetlb_release_pages, .alias_mapping = hugetlb_alias_mapping, @@ -286,22 +284,6 @@ static int my_bcmp(char *str1, char *str2, size_t n) return 0; } -static void continue_range(int ufd, __u64 start, __u64 len) -{ - struct uffdio_continue req; - - req.range.start = start; - req.range.len = len; - req.mode = 0; - - if (ioctl(ufd, UFFDIO_CONTINUE, &req)) { - fprintf(stderr, - "UFFDIO_CONTINUE failed for address 0x%" PRIx64 "\n", - (uint64_t)start); - exit(1); - } -} - static void *locking_thread(void *arg) { unsigned long cpu = (unsigned long) arg; @@ -440,41 +422,13 @@ static int uffd_handle_page_fault(struct uffd_msg *msg) fprintf(stderr, "unexpected msg event %u\n", msg->event), exit(1); - if (msg->arg.pagefault.flags & UFFD_PAGEFAULT_FLAG_MINOR) { - uint8_t *area; - int b; + if (msg->arg.pagefault.flags & UFFD_PAGEFAULT_FLAG_WRITE) + fprintf(stderr, "unexpected write fault\n"), exit(1); - /* - * Minor page faults - * - * To prove we can modify the original range for testing - * purposes, we're going to bit flip this range before - * continuing. - * - * Note that this requires all minor page fault tests operate on - * area_dst (non-UFFD-registered) and area_dst_alias - * (UFFD-registered). - */ + offset = (char *)(unsigned long)msg->arg.pagefault.address - area_dst; + offset &= ~(page_size-1); - area = (uint8_t *)(area_dst + - ((char *)msg->arg.pagefault.address - - area_dst_alias)); - for (b = 0; b < page_size; ++b) - area[b] = ~area[b]; - continue_range(uffd, msg->arg.pagefault.address, page_size); - return 1; - } else { - /* Missing page faults */ - if (msg->arg.pagefault.flags & UFFD_PAGEFAULT_FLAG_WRITE) { - fprintf(stderr, "unexpected write fault\n"); - exit(1); - } - - offset = (char *)(unsigned long)msg->arg.pagefault.address - area_dst; - offset &= ~(page_size-1); - - return copy_page(uffd, offset); - } + return copy_page(uffd, offset); } static void *uffd_poll_thread(void *arg) @@ -641,7 +595,7 @@ static int stress(unsigned long *userfaults) return 0; } -static int userfaultfd_open_ext(uint64_t *features) +static int userfaultfd_open(int features) { struct uffdio_api uffdio_api; @@ -654,7 +608,7 @@ static int userfaultfd_open_ext(uint64_t *features) uffd_flags = fcntl(uffd, F_GETFD, NULL); uffdio_api.api = UFFD_API; - uffdio_api.features = *features; + uffdio_api.features = features; if (ioctl(uffd, UFFDIO_API, &uffdio_api)) { fprintf(stderr, "UFFDIO_API\n"); return 1; @@ -664,15 +618,9 @@ static int userfaultfd_open_ext(uint64_t *features) return 1; } - *features = uffdio_api.features; return 0; } -static int userfaultfd_open(uint64_t features) -{ - return userfaultfd_open_ext(&features); -} - sigjmp_buf jbuf, *sigbuf; static void sighndl(int sig, siginfo_t *siginfo, void *ptr) @@ -944,7 +892,7 @@ static int userfaultfd_events_test(void) perror("fork"), exit(1); if (!pid) - exit(faulting_process(0)); + return faulting_process(0); waitpid(pid, &err, 0); if (err) @@ -1027,101 +975,6 @@ static int userfaultfd_sig_test(void) close(uffd); return userfaults != 0; } - -static int userfaultfd_minor_test(void) -{ - struct uffdio_register uffdio_register; - unsigned long expected_ioctls; - unsigned long userfaults; - unsigned long p; - pthread_t uffd_mon; - uint8_t expected_byte; - void *expected_page; - char c; - uint64_t features = UFFD_FEATURE_MINOR_HUGETLBFS; - - if (!test_uffdio_minor) - return 0; - - printf("testing minor faults: "); - fflush(stdout); - - if (uffd_test_ops->release_pages(area_dst)) - return 1; - - if (userfaultfd_open_ext(&features)) - return 1; - /* If kernel reports the feature isn't supported, skip the test. */ - if (!(features & UFFD_FEATURE_MINOR_HUGETLBFS)) { - printf("skipping test due to lack of feature support\n"); - fflush(stdout); - return 0; - } - - uffdio_register.range.start = (unsigned long)area_dst_alias; - uffdio_register.range.len = nr_pages * page_size; - uffdio_register.mode = UFFDIO_REGISTER_MODE_MINOR; - if (ioctl(uffd, UFFDIO_REGISTER, &uffdio_register)) { - fprintf(stderr, "register failure\n"); - exit(1); - } - - expected_ioctls = uffd_test_ops->expected_ioctls; - expected_ioctls |= 1 << _UFFDIO_CONTINUE; - if ((uffdio_register.ioctls & expected_ioctls) != expected_ioctls) { - fprintf(stderr, "unexpected missing ioctl(s)\n"); - exit(1); - } - - /* - * After registering with UFFD, populate the non-UFFD-registered side of - * the shared mapping. This should *not* trigger any UFFD minor faults. - */ - for (p = 0; p < nr_pages; ++p) { - memset(area_dst + (p * page_size), p % ((uint8_t)-1), - page_size); - } - - if (pthread_create(&uffd_mon, &attr, uffd_poll_thread, NULL)) { - perror("uffd_poll_thread create"); - exit(1); - } - - /* - * Read each of the pages back using the UFFD-registered mapping. We - * expect that the first time we touch a page, it will result in a minor - * fault. uffd_poll_thread will resolve the fault by bit-flipping the - * page's contents, and then issuing a CONTINUE ioctl. - */ - - if (posix_memalign(&expected_page, page_size, page_size)) { - fprintf(stderr, "out of memory\n"); - return 1; - } - - for (p = 0; p < nr_pages; ++p) { - expected_byte = ~((uint8_t)(p % ((uint8_t)-1))); - memset(expected_page, expected_byte, page_size); - if (my_bcmp(expected_page, area_dst_alias + (p * page_size), - page_size)) { - fprintf(stderr, - "unexpected page contents after minor fault\n"); - exit(1); - } - } - - if (write(pipefd[1], &c, sizeof(c)) != sizeof(c)) { - perror("pipe write"); - exit(1); - } - if (pthread_join(uffd_mon, (void **)&userfaults)) - return 1; - printf("userfaults: %ld\n", userfaults); - - close(uffd); - return userfaults != nr_pages; -} - static int userfaultfd_stress(void) { void *area; @@ -1312,7 +1165,7 @@ static int userfaultfd_stress(void) close(uffd); return userfaultfd_zeropage_test() || userfaultfd_sig_test() - || userfaultfd_events_test() || userfaultfd_minor_test(); + || userfaultfd_events_test(); } /* @@ -1351,8 +1204,6 @@ static void set_test_type(const char *type) map_shared = true; test_type = TEST_HUGETLB; uffd_test_ops = &hugetlb_uffd_test_ops; - /* Minor faults require shared hugetlb; only enable here. */ - test_uffdio_minor = true; } else if (!strcmp(type, "shmem")) { map_shared = true; test_type = TEST_SHMEM;