Lines Matching +full:no +full:- +full:wp
1 // SPDX-License-Identifier: GPL-2.0-only
5 * Copyright (C) 2015-2023 Red Hat, Inc.
8 #include "uffd-common.h"
48 .name = "shmem-private",
60 .name = "hugetlb-private",
186 map_shared = mem_type->shared; in uffd_setup_environment()
187 uffd_test_ops = mem_type->mem_ops; in uffd_setup_environment()
189 if (mem_type->mem_flag & (MEM_HUGETLB_PRIVATE | MEM_HUGETLB)) in uffd_setup_environment()
199 args->mem_type = mem_type; in uffd_setup_environment()
201 return uffd_test_ctx_init(test->uffd_feature_required, errmsg); in uffd_setup_environment()
211 return (features & test->uffd_feature_required) == in uffd_feature_supported()
212 test->uffd_feature_required; in uffd_feature_supported()
226 #define pagemap_check_wp(value, wp) do { \ argument
227 if (!!(value & PM_UFFD_WP) != wp) \
228 err("pagemap uffd-wp bit error: 0x%"PRIx64, value); \
241 while (uffd_read_msg(args->parent_uffd, &msg)); in fork_event_consumer()
247 args->child_uffd = msg.arg.fork.ufd; in fork_event_consumer()
267 /* Read-only pins */ in pin_pages()
271 if (args->pinned) in pin_pages()
274 args->gup_fd = open("/sys/kernel/debug/gup_test", O_RDWR); in pin_pages()
275 if (args->gup_fd < 0) in pin_pages()
276 return -errno; in pin_pages()
278 if (ioctl(args->gup_fd, PIN_LONGTERM_TEST_START, &test)) { in pin_pages()
280 close(args->gup_fd); in pin_pages()
281 return -errno; in pin_pages()
283 args->pinned = true; in pin_pages()
289 if (!args->pinned) in unpin_pages()
291 if (ioctl(args->gup_fd, PIN_LONGTERM_TEST_STOP)) in unpin_pages()
293 close(args->gup_fd); in unpin_pages()
294 args->pinned = false; in unpin_pages()
299 fork_event_args args = { .parent_uffd = uffd, .child_uffd = -1 }; in pagemap_test_fork()
327 * After fork(), we should handle uffd-wp bit differently: in pagemap_test_fork()
387 /* Test read-zero-page upon pte marker */ in uffd_wp_unpopulated_test()
415 uffd_test_fail("Detected %s uffd-wp bit in child in present pte", in uffd_wp_fork_test_common()
431 if (args->mem_type->shared) { in uffd_wp_fork_test_common()
436 * NOTE: ignore retval because private-hugetlb doesn't yet in uffd_wp_fork_test_common()
442 /* Uffd-wp should persist even swapped out */ in uffd_wp_fork_test_common()
446 uffd_test_fail("Detected %s uffd-wp bit in child in zapped pte", in uffd_wp_fork_test_common()
505 uffd_test_fail("Detected %s uffd-wp bit in early CoW of fork()", in uffd_wp_fork_pin_test_common()
518 uffd_test_fail("Detected %s uffd-wp bit when RO pin", in uffd_wp_fork_pin_test_common()
545 expected_byte = ~((uint8_t)(i % ((uint8_t)-1))); in check_memory_contents()
562 * NOTE: MADV_COLLAPSE is not yet compatible with WP, so testing in uffd_minor_test_common()
568 /* NOTE! MADV_COLLAPSE may not work with uffd-wp */ in uffd_minor_test_common()
573 * After registering with UFFD, populate the non-UFFD-registered side of in uffd_minor_test_common()
577 memset(area_dst + (p * page_size), p % ((uint8_t)-1), in uffd_minor_test_common()
585 * Read each of the pages back using the UFFD-registered mapping. We in uffd_minor_test_common()
587 * fault. uffd_poll_thread will resolve the fault by bit-flipping the in uffd_minor_test_common()
605 uffd_test_ops->check_pmd_mapping(area_dst, in uffd_minor_test_common()
609 * This won't cause uffd-fault - it purely just makes sure there in uffd_minor_test_common()
610 * was no corruption. in uffd_minor_test_common()
648 * For non-cooperative userfaultfd test we fork() a process that will
663 * test robustness use case - we release monitored area, fork a process
666 * feature. Using monitor thread, verify no userfault events are generated.
668 static int faulting_process(int signal_test, bool wp) in faulting_process() argument
686 lastnr = (unsigned long)-1; in faulting_process()
703 if (copy_page(uffd, offset, wp)) in faulting_process()
706 /* This is a WP request */ in faulting_process()
754 uffd_test_ops->release_pages(area_dst); in faulting_process()
764 static void uffd_sigbus_test_common(bool wp) in uffd_sigbus_test_common() argument
776 true, wp, false)) in uffd_sigbus_test_common()
779 if (faulting_process(1, wp)) in uffd_sigbus_test_common()
782 uffd_test_ops->release_pages(area_dst); in uffd_sigbus_test_common()
784 args.apply_wp = wp; in uffd_sigbus_test_common()
793 exit(faulting_process(2, wp)); in uffd_sigbus_test_common()
819 static void uffd_events_test_common(bool wp) in uffd_events_test_common() argument
829 true, wp, false)) in uffd_events_test_common()
832 args.apply_wp = wp; in uffd_events_test_common()
841 exit(faulting_process(0, wp)); in uffd_events_test_common()
870 uffd_test_ops->alias_mapping(&uffdio_zeropage->range.start, in retry_uffdio_zeropage()
871 uffdio_zeropage->range.len, in retry_uffdio_zeropage()
874 if (uffdio_zeropage->zeropage != -EEXIST) in retry_uffdio_zeropage()
876 (int64_t)uffdio_zeropage->zeropage); in retry_uffdio_zeropage()
879 (int64_t)uffdio_zeropage->zeropage); in retry_uffdio_zeropage()
898 else if (res != -EINVAL) in do_uffdio_zeropage()
899 err("UFFDIO_ZEROPAGE not -EINVAL"); in do_uffdio_zeropage()
943 err("data non-zero at offset %d\n", i); in uffd_zeropage_test()
990 if (msg->event != UFFD_EVENT_PAGEFAULT) in uffd_poison_handle_fault()
991 err("unexpected msg event %u", msg->event); in uffd_poison_handle_fault()
993 if (msg->arg.pagefault.flags & in uffd_poison_handle_fault()
995 err("unexpected fault type %llu", msg->arg.pagefault.flags); in uffd_poison_handle_fault()
997 offset = (char *)(unsigned long)msg->arg.pagefault.address - area_dst; in uffd_poison_handle_fault()
998 offset &= ~(page_size-1); in uffd_poison_handle_fault()
1000 /* Odd pages -> copy zeroed page; even pages -> poison. */ in uffd_poison_handle_fault()
1070 do_register_ioctls_test(uffd_test_args_t *args, bool miss, bool wp, bool minor) in do_register_ioctls_test() argument
1073 mem_type_t *mem_type = args->mem_type; in do_register_ioctls_test()
1077 miss, wp, minor, &ioctls); in do_register_ioctls_test()
1081 * just fail with -EINVAL first.. in do_register_ioctls_test()
1084 * Case 2: register with no mode selected in do_register_ioctls_test()
1086 if ((minor && (mem_type->mem_flag == MEM_ANON)) || in do_register_ioctls_test()
1087 (!miss && !wp && !minor)) { in do_register_ioctls_test()
1088 if (ret != -EINVAL) in do_register_ioctls_test()
1089 err("register (miss=%d, wp=%d, minor=%d) failed " in do_register_ioctls_test()
1090 "with wrong errno=%d", miss, wp, minor, ret); in do_register_ioctls_test()
1097 if (wp) in do_register_ioctls_test()
1104 "(miss=%d, wp=%d, minor=%d): expected=0x%"PRIx64", " in do_register_ioctls_test()
1105 "returned=0x%"PRIx64, miss, wp, minor, expected, ioctls); in do_register_ioctls_test()
1113 int miss, wp, minor; in uffd_register_ioctls_test() local
1116 for (wp = 0; wp <= 1; wp++) in uffd_register_ioctls_test()
1118 do_register_ioctls_test(args, miss, wp, minor); in uffd_register_ioctls_test()
1126 .name = "register-ioctls",
1143 .name = "wp-fork",
1150 .name = "wp-fork-with-event",
1155 /* when set, child process should inherit uffd-wp bits */
1159 .name = "wp-fork-pin",
1166 .name = "wp-fork-pin-with-event",
1171 /* when set, child process should inherit uffd-wp bits */
1175 .name = "wp-unpopulated",
1189 .name = "minor-wp",
1197 * minor mode supports wr-protect. There's no feature flag
1203 .name = "minor-collapse",
1218 .name = "sigbus-wp",
1232 .name = "events-wp",
1250 printf("usage: %s [-f TESTNAME]\n", prog); in usage()
1252 puts(" -f: test name to filter (e.g., event)"); in usage()
1253 puts(" -h: show the help msg"); in usage()
1254 puts(" -l: list tests only"); in usage()
1272 while ((opt = getopt(argc, argv, "f:hl")) != -1) { in main()
1300 if (test_filter && !strstr(test->name, test_filter)) in main()
1303 printf("%s\n", test->name); in main()
1308 if (!(test->mem_targets & mem_type->mem_flag)) in main()
1311 uffd_test_start("%s on %s", test->name, mem_type->name); in main()
1312 if ((mem_type->mem_flag == MEM_HUGETLB || in main()
1313 mem_type->mem_flag == MEM_HUGETLB_PRIVATE) && in main()
1327 test->uffd_fn(&args); in main()