Skip to content

Commit

Permalink
selftests/mm: let uffd_handle_page_fault() take wp parameter
Browse files Browse the repository at this point in the history
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/[email protected]
Signed-off-by: Peter Xu <[email protected]>
Cc: Axel Rasmussen <[email protected]>
Cc: David Hildenbrand <[email protected]>
Cc: Dmitry Safonov <[email protected]>
Cc: Mike Kravetz <[email protected]>
Cc: Mike Rapoport (IBM) <[email protected]>
Cc: Zach O'Keefe <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
  • Loading branch information
xzpeter authored and akpm00 committed Apr 18, 2023
1 parent 5083408 commit 0210c43
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 16 deletions.
17 changes: 9 additions & 8 deletions tools/testing/selftests/mm/uffd-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -353,15 +353,15 @@ void wp_range(int ufd, __u64 start, __u64 len, bool wp)
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;

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))
Expand Down Expand Up @@ -429,7 +429,8 @@ void uffd_handle_page_fault(struct uffd_msg *msg, struct uffd_args *args)
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 {
/*
Expand Down Expand Up @@ -459,7 +460,7 @@ void uffd_handle_page_fault(struct uffd_msg *msg, struct uffd_args *args)
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++;
}
}
Expand Down Expand Up @@ -555,7 +556,7 @@ static void wake_range(int ufd, unsigned long addr, unsigned long len)
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;

Expand All @@ -564,7 +565,7 @@ int __copy_page(int ufd, unsigned long offset, bool retry)
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;
Expand All @@ -587,7 +588,7 @@ int __copy_page(int ufd, unsigned long offset, bool retry)
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);
}
6 changes: 4 additions & 2 deletions tools/testing/selftests/mm/uffd-common.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
16 changes: 10 additions & 6 deletions tools/testing/selftests/mm/uffd-stress.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ static void uffd_stats_reset(struct uffd_args *args, unsigned long n_cpus)

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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -308,7 +309,7 @@ static void sighndl(int sig, siginfo_t *siginfo, void *ptr)
* 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;
Expand Down Expand Up @@ -343,7 +344,7 @@ static int faulting_process(int signal_test)
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 */
Expand Down Expand Up @@ -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");

Expand All @@ -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)
Expand Down Expand Up @@ -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");

Expand All @@ -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)
Expand Down Expand Up @@ -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");

Expand Down

0 comments on commit 0210c43

Please sign in to comment.