// SPDX-License-Identifier: GPL-2.0-only
/*
 * Stress userfaultfd syscall.
 *
 *  Copyright (C) 2015  Red Hat, Inc.
 *
 * This test allocates two virtual areas and bounces the physical
 * memory across the two virtual areas (from area_src to area_dst)
 * using userfaultfd.
 *
 * There are three threads running per CPU:
 *
 * 1) one per-CPU thread takes a per-page pthread_mutex in a random
 *    page of the area_dst (while the physical page may still be in
 *    area_src), and increments a per-page counter in the same page,
 *    and checks its value against a verification region.
 *
 * 2) another per-CPU thread handles the userfaults generated by
 *    thread 1 above. userfaultfd blocking reads or poll() modes are
 *    exercised interleaved.
 *
 * 3) one last per-CPU thread transfers the memory in the background
 *    at maximum bandwidth (if not already transferred by thread
 *    2). Each cpu thread takes cares of transferring a portion of the
 *    area.
 *
 * When all threads of type 3 completed the transfer, one bounce is
 * complete. area_src and area_dst are then swapped. All threads are
 * respawned and so the bounce is immediately restarted in the
 * opposite direction.
 *
 * per-CPU threads 1 by triggering userfaults inside
 * pthread_mutex_lock will also verify the atomicity of the memory
 * transfer (UFFDIO_COPY).
 */

#define _GNU_SOURCE
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>
#include <signal.h>
#include <poll.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/syscall.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <pthread.h>
#include <linux/userfaultfd.h>
#include <setjmp.h>
#include <stdbool.h>
#include <assert.h>
#include <inttypes.h>
#include <stdint.h>

#include "../kselftest.h"

#ifdef __NR_userfaultfd

static unsigned long nr_cpus, nr_pages, nr_pages_per_cpu, page_size;

#define BOUNCE_RANDOM		(1<<0)
#define BOUNCE_RACINGFAULTS	(1<<1)
#define BOUNCE_VERIFY		(1<<2)
#define BOUNCE_POLL		(1<<3)
static int bounces;

#define TEST_ANON	1
#define TEST_HUGETLB	2
#define TEST_SHMEM	3
static int test_type;

/* exercise the test_uffdio_*_eexist every ALARM_INTERVAL_SECS */
#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 write-protection */
static bool test_uffdio_wp = false;
/* Whether to test uffd minor faults */
static bool test_uffdio_minor = false;

static bool map_shared;
static int shm_fd;
static int huge_fd;
static char *huge_fd_off0;
static unsigned long long *count_verify;
static int uffd = -1;
static int uffd_flags, finished, *pipefd;
static char *area_src, *area_src_alias, *area_dst, *area_dst_alias;
static char *zeropage;
pthread_attr_t attr;

/* Userfaultfd test statistics */
struct uffd_stats {
	int cpu;
	unsigned long missing_faults;
	unsigned long wp_faults;
	unsigned long minor_faults;
};

/* pthread_mutex_t starts at page offset 0 */
#define area_mutex(___area, ___nr)					\
	((pthread_mutex_t *) ((___area) + (___nr)*page_size))
/*
 * count is placed in the page after pthread_mutex_t naturally aligned
 * to avoid non alignment faults on non-x86 archs.
 */
#define area_count(___area, ___nr)					\
	((volatile unsigned long long *) ((unsigned long)		\
				 ((___area) + (___nr)*page_size +	\
				  sizeof(pthread_mutex_t) +		\
				  sizeof(unsigned long long) - 1) &	\
				 ~(unsigned long)(sizeof(unsigned long long) \
						  -  1)))

const char *examples =
    "# Run anonymous memory test on 100MiB region with 99999 bounces:\n"
    "./userfaultfd anon 100 99999\n\n"
    "# Run share memory test on 1GiB region with 99 bounces:\n"
    "./userfaultfd shmem 1000 99\n\n"
    "# Run hugetlb memory test on 256MiB region with 50 bounces (using /dev/hugepages/hugefile):\n"
    "./userfaultfd hugetlb 256 50 /dev/hugepages/hugefile\n\n"
    "# Run the same hugetlb test but using shmem:\n"
    "./userfaultfd hugetlb_shared 256 50 /dev/hugepages/hugefile\n\n"
    "# 10MiB-~6GiB 999 bounces anonymous test, "
    "continue forever unless an error triggers\n"
    "while ./userfaultfd anon $[RANDOM % 6000 + 10] 999; do true; done\n\n";

static void usage(void)
{
	fprintf(stderr, "\nUsage: ./userfaultfd <test type> <MiB> <bounces> "
		"[hugetlbfs_file]\n\n");
	fprintf(stderr, "Supported <test type>: anon, hugetlb, "
		"hugetlb_shared, shmem\n\n");
	fprintf(stderr, "Examples:\n\n");
	fprintf(stderr, "%s", examples);
	exit(1);
}

#define _err(fmt, ...)						\
	do {							\
		int ret = errno;				\
		fprintf(stderr, "ERROR: " fmt, ##__VA_ARGS__);	\
		fprintf(stderr, " (errno=%d, line=%d)\n",	\
			ret, __LINE__);				\
	} while (0)

#define err(fmt, ...)				\
	do {					\
		_err(fmt, ##__VA_ARGS__);	\
		exit(1);			\
	} while (0)

static void uffd_stats_reset(struct uffd_stats *uffd_stats,
			     unsigned long n_cpus)
{
	int i;

	for (i = 0; i < n_cpus; i++) {
		uffd_stats[i].cpu = i;
		uffd_stats[i].missing_faults = 0;
		uffd_stats[i].wp_faults = 0;
		uffd_stats[i].minor_faults = 0;
	}
}

static void uffd_stats_report(struct uffd_stats *stats, int n_cpus)
{
	int i;
	unsigned long long miss_total = 0, wp_total = 0, minor_total = 0;

	for (i = 0; i < n_cpus; i++) {
		miss_total += stats[i].missing_faults;
		wp_total += stats[i].wp_faults;
		minor_total += stats[i].minor_faults;
	}

	printf("userfaults: ");
	if (miss_total) {
		printf("%llu missing (", miss_total);
		for (i = 0; i < n_cpus; i++)
			printf("%lu+", stats[i].missing_faults);
		printf("\b) ");
	}
	if (wp_total) {
		printf("%llu wp (", wp_total);
		for (i = 0; i < n_cpus; i++)
			printf("%lu+", stats[i].wp_faults);
		printf("\b) ");
	}
	if (minor_total) {
		printf("%llu minor (", minor_total);
		for (i = 0; i < n_cpus; i++)
			printf("%lu+", stats[i].minor_faults);
		printf("\b)");
	}
	printf("\n");
}

static void anon_release_pages(char *rel_area)
{
	if (madvise(rel_area, nr_pages * page_size, MADV_DONTNEED))
		err("madvise(MADV_DONTNEED) failed");
}

static void anon_allocate_area(void **alloc_area)
{
	*alloc_area = mmap(NULL, nr_pages * page_size, PROT_READ | PROT_WRITE,
			   MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
	if (*alloc_area == MAP_FAILED)
		err("mmap of anonymous memory failed");
}

static void noop_alias_mapping(__u64 *start, size_t len, unsigned long offset)
{
}

static void hugetlb_release_pages(char *rel_area)
{
	if (fallocate(huge_fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
		      rel_area == huge_fd_off0 ? 0 : nr_pages * page_size,
		      nr_pages * page_size))
		err("fallocate() failed");
}

static void hugetlb_allocate_area(void **alloc_area)
{
	void *area_alias = NULL;
	char **alloc_area_alias;

	*alloc_area = mmap(NULL, nr_pages * page_size, PROT_READ | PROT_WRITE,
			   (map_shared ? MAP_SHARED : MAP_PRIVATE) |
			   MAP_HUGETLB,
			   huge_fd, *alloc_area == area_src ? 0 :
			   nr_pages * page_size);
	if (*alloc_area == MAP_FAILED)
		err("mmap of hugetlbfs file failed");

	if (map_shared) {
		area_alias = mmap(NULL, nr_pages * page_size, PROT_READ | PROT_WRITE,
				  MAP_SHARED | MAP_HUGETLB,
				  huge_fd, *alloc_area == area_src ? 0 :
				  nr_pages * page_size);
		if (area_alias == MAP_FAILED)
			err("mmap of hugetlb file alias failed");
	}

	if (*alloc_area == area_src) {
		huge_fd_off0 = *alloc_area;
		alloc_area_alias = &area_src_alias;
	} else {
		alloc_area_alias = &area_dst_alias;
	}
	if (area_alias)
		*alloc_area_alias = area_alias;
}

static void hugetlb_alias_mapping(__u64 *start, size_t len, unsigned long offset)
{
	if (!map_shared)
		return;
	/*
	 * We can't zap just the pagetable with hugetlbfs because
	 * MADV_DONTEED won't work. So exercise -EEXIST on a alias
	 * mapping where the pagetables are not established initially,
	 * this way we'll exercise the -EEXEC at the fs level.
	 */
	*start = (unsigned long) area_dst_alias + offset;
}

static void shmem_release_pages(char *rel_area)
{
	if (madvise(rel_area, nr_pages * page_size, MADV_REMOVE))
		err("madvise(MADV_REMOVE) failed");
}

static void shmem_allocate_area(void **alloc_area)
{
	void *area_alias = NULL;
	bool is_src = alloc_area == (void **)&area_src;
	unsigned long offset = is_src ? 0 : nr_pages * page_size;

	*alloc_area = mmap(NULL, nr_pages * page_size, PROT_READ | PROT_WRITE,
			   MAP_SHARED, shm_fd, offset);
	if (*alloc_area == MAP_FAILED)
		err("mmap of memfd failed");

	area_alias = mmap(NULL, nr_pages * page_size, PROT_READ | PROT_WRITE,
			  MAP_SHARED, shm_fd, offset);
	if (area_alias == MAP_FAILED)
		err("mmap of memfd alias failed");

	if (is_src)
		area_src_alias = area_alias;
	else
		area_dst_alias = area_alias;
}

static void shmem_alias_mapping(__u64 *start, size_t len, unsigned long offset)
{
	*start = (unsigned long)area_dst_alias + offset;
}

struct uffd_test_ops {
	unsigned long expected_ioctls;
	void (*allocate_area)(void **alloc_area);
	void (*release_pages)(char *rel_area);
	void (*alias_mapping)(__u64 *start, size_t len, unsigned long offset);
};

#define SHMEM_EXPECTED_IOCTLS		((1 << _UFFDIO_WAKE) | \
					 (1 << _UFFDIO_COPY) | \
					 (1 << _UFFDIO_ZEROPAGE))

#define ANON_EXPECTED_IOCTLS		((1 << _UFFDIO_WAKE) | \
					 (1 << _UFFDIO_COPY) | \
					 (1 << _UFFDIO_ZEROPAGE) | \
					 (1 << _UFFDIO_WRITEPROTECT))

static struct uffd_test_ops anon_uffd_test_ops = {
	.expected_ioctls = ANON_EXPECTED_IOCTLS,
	.allocate_area	= anon_allocate_area,
	.release_pages	= anon_release_pages,
	.alias_mapping = noop_alias_mapping,
};

static struct uffd_test_ops shmem_uffd_test_ops = {
	.expected_ioctls = SHMEM_EXPECTED_IOCTLS,
	.allocate_area	= shmem_allocate_area,
	.release_pages	= shmem_release_pages,
	.alias_mapping = shmem_alias_mapping,
};

static struct uffd_test_ops hugetlb_uffd_test_ops = {
	.expected_ioctls = UFFD_API_RANGE_IOCTLS_BASIC & ~(1 << _UFFDIO_CONTINUE),
	.allocate_area	= hugetlb_allocate_area,
	.release_pages	= hugetlb_release_pages,
	.alias_mapping = hugetlb_alias_mapping,
};

static struct uffd_test_ops *uffd_test_ops;

static void userfaultfd_open(uint64_t *features)
{
	struct uffdio_api uffdio_api;

	uffd = syscall(__NR_userfaultfd, O_CLOEXEC | O_NONBLOCK | UFFD_USER_MODE_ONLY);
	if (uffd < 0)
		err("userfaultfd syscall not available in this kernel");
	uffd_flags = fcntl(uffd, F_GETFD, NULL);

	uffdio_api.api = UFFD_API;
	uffdio_api.features = *features;
	if (ioctl(uffd, UFFDIO_API, &uffdio_api))
		err("UFFDIO_API failed.\nPlease make sure to "
		    "run with either root or ptrace capability.");
	if (uffdio_api.api != UFFD_API)
		err("UFFDIO_API error: %" PRIu64, (uint64_t)uffdio_api.api);

	*features = uffdio_api.features;
}

static inline void munmap_area(void **area)
{
	if (*area)
		if (munmap(*area, nr_pages * page_size))
			err("munmap");

	*area = NULL;
}

static void uffd_test_ctx_clear(void)
{
	size_t i;

	if (pipefd) {
		for (i = 0; i < nr_cpus * 2; ++i) {
			if (close(pipefd[i]))
				err("close pipefd");
		}
		free(pipefd);
		pipefd = NULL;
	}

	if (count_verify) {
		free(count_verify);
		count_verify = NULL;
	}

	if (uffd != -1) {
		if (close(uffd))
			err("close uffd");
		uffd = -1;
	}

	huge_fd_off0 = NULL;
	munmap_area((void **)&area_src);
	munmap_area((void **)&area_src_alias);
	munmap_area((void **)&area_dst);
	munmap_area((void **)&area_dst_alias);
}

static void uffd_test_ctx_init_ext(uint64_t *features)
{
	unsigned long nr, cpu;

	uffd_test_ctx_clear();

	uffd_test_ops->allocate_area((void **)&area_src);
	uffd_test_ops->allocate_area((void **)&area_dst);

	userfaultfd_open(features);

	count_verify = malloc(nr_pages * sizeof(unsigned long long));
	if (!count_verify)
		err("count_verify");

	for (nr = 0; nr < nr_pages; nr++) {
		*area_mutex(area_src, nr) =
			(pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER;
		count_verify[nr] = *area_count(area_src, nr) = 1;
		/*
		 * In the transition between 255 to 256, powerpc will
		 * read out of order in my_bcmp and see both bytes as
		 * zero, so leave a placeholder below always non-zero
		 * after the count, to avoid my_bcmp to trigger false
		 * positives.
		 */
		*(area_count(area_src, nr) + 1) = 1;
	}

	/*
	 * After initialization of area_src, we must explicitly release pages
	 * for area_dst to make sure it's fully empty.  Otherwise we could have
	 * some area_dst pages be errornously initialized with zero pages,
	 * hence we could hit memory corruption later in the test.
	 *
	 * One example is when THP is globally enabled, above allocate_area()
	 * calls could have the two areas merged into a single VMA (as they
	 * will have the same VMA flags so they're mergeable).  When we
	 * initialize the area_src above, it's possible that some part of
	 * area_dst could have been faulted in via one huge THP that will be
	 * shared between area_src and area_dst.  It could cause some of the
	 * area_dst won't be trapped by missing userfaults.
	 *
	 * This release_pages() will guarantee even if that happened, we'll
	 * proactively split the thp and drop any accidentally initialized
	 * pages within area_dst.
	 */
	uffd_test_ops->release_pages(area_dst);

	pipefd = malloc(sizeof(int) * nr_cpus * 2);
	if (!pipefd)
		err("pipefd");
	for (cpu = 0; cpu < nr_cpus; cpu++)
		if (pipe2(&pipefd[cpu * 2], O_CLOEXEC | O_NONBLOCK))
			err("pipe");
}

static inline void uffd_test_ctx_init(uint64_t features)
{
	uffd_test_ctx_init_ext(&features);
}

static int my_bcmp(char *str1, char *str2, size_t n)
{
	unsigned long i;
	for (i = 0; i < n; i++)
		if (str1[i] != str2[i])
			return 1;
	return 0;
}

static void wp_range(int ufd, __u64 start, __u64 len, bool wp)
{
	struct uffdio_writeprotect prms;

	/* Write protection page faults */
	prms.range.start = start;
	prms.range.len = len;
	/* Undo write-protect, do wakeup after that */
	prms.mode = wp ? UFFDIO_WRITEPROTECT_MODE_WP : 0;

	if (ioctl(ufd, UFFDIO_WRITEPROTECT, &prms))
		err("clear WP failed: address=0x%"PRIx64, (uint64_t)start);
}

static void continue_range(int ufd, __u64 start, __u64 len)
{
	struct uffdio_continue req;
	int ret;

	req.range.start = start;
	req.range.len = len;
	req.mode = 0;

	if (ioctl(ufd, UFFDIO_CONTINUE, &req))
		err("UFFDIO_CONTINUE failed for address 0x%" PRIx64,
		    (uint64_t)start);

	/*
	 * Error handling within the kernel for continue is subtly different
	 * from copy or zeropage, so it may be a source of bugs. Trigger an
	 * error (-EEXIST) on purpose, to verify doing so doesn't cause a BUG.
	 */
	req.mapped = 0;
	ret = ioctl(ufd, UFFDIO_CONTINUE, &req);
	if (ret >= 0 || req.mapped != -EEXIST)
		err("failed to exercise UFFDIO_CONTINUE error handling, ret=%d, mapped=%" PRId64,
		    ret, (int64_t) req.mapped);
}

static void *locking_thread(void *arg)
{
	unsigned long cpu = (unsigned long) arg;
	struct random_data rand;
	unsigned long page_nr = *(&(page_nr)); /* uninitialized warning */
	int32_t rand_nr;
	unsigned long long count;
	char randstate[64];
	unsigned int seed;

	if (bounces & BOUNCE_RANDOM) {
		seed = (unsigned int) time(NULL) - bounces;
		if (!(bounces & BOUNCE_RACINGFAULTS))
			seed += cpu;
		bzero(&rand, sizeof(rand));
		bzero(&randstate, sizeof(randstate));
		if (initstate_r(seed, randstate, sizeof(randstate), &rand))
			err("initstate_r failed");
	} else {
		page_nr = -bounces;
		if (!(bounces & BOUNCE_RACINGFAULTS))
			page_nr += cpu * nr_pages_per_cpu;
	}

	while (!finished) {
		if (bounces & BOUNCE_RANDOM) {
			if (random_r(&rand, &rand_nr))
				err("random_r failed");
			page_nr = rand_nr;
			if (sizeof(page_nr) > sizeof(rand_nr)) {
				if (random_r(&rand, &rand_nr))
					err("random_r failed");
				page_nr |= (((unsigned long) rand_nr) << 16) <<
					   16;
			}
		} else
			page_nr += 1;
		page_nr %= nr_pages;
		pthread_mutex_lock(area_mutex(area_dst, page_nr));
		count = *area_count(area_dst, page_nr);
		if (count != count_verify[page_nr])
			err("page_nr %lu memory corruption %llu %llu",
			    page_nr, count, count_verify[page_nr]);
		count++;
		*area_count(area_dst, page_nr) = count_verify[page_nr] = count;
		pthread_mutex_unlock(area_mutex(area_dst, page_nr));
	}

	return NULL;
}

static void retry_copy_page(int ufd, struct uffdio_copy *uffdio_copy,
			    unsigned long offset)
{
	uffd_test_ops->alias_mapping(&uffdio_copy->dst,
				     uffdio_copy->len,
				     offset);
	if (ioctl(ufd, UFFDIO_COPY, uffdio_copy)) {
		/* real retval in ufdio_copy.copy */
		if (uffdio_copy->copy != -EEXIST)
			err("UFFDIO_COPY retry error: %"PRId64,
			    (int64_t)uffdio_copy->copy);
	} else {
		err("UFFDIO_COPY retry unexpected: %"PRId64,
		    (int64_t)uffdio_copy->copy);
	}
}

static void wake_range(int ufd, unsigned long addr, unsigned long len)
{
	struct uffdio_range uffdio_wake;

	uffdio_wake.start = addr;
	uffdio_wake.len = len;

	if (ioctl(ufd, UFFDIO_WAKE, &uffdio_wake))
		fprintf(stderr, "error waking %lu\n",
			addr), exit(1);
}

static int __copy_page(int ufd, unsigned long offset, bool retry)
{
	struct uffdio_copy uffdio_copy;

	if (offset >= nr_pages * page_size)
		err("unexpected offset %lu\n", offset);
	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)
		uffdio_copy.mode = UFFDIO_COPY_MODE_WP;
	else
		uffdio_copy.mode = 0;
	uffdio_copy.copy = 0;
	if (ioctl(ufd, UFFDIO_COPY, &uffdio_copy)) {
		/* real retval in ufdio_copy.copy */
		if (uffdio_copy.copy != -EEXIST)
			err("UFFDIO_COPY error: %"PRId64,
			    (int64_t)uffdio_copy.copy);
		wake_range(ufd, uffdio_copy.dst, page_size);
	} else if (uffdio_copy.copy != page_size) {
		err("UFFDIO_COPY error: %"PRId64, (int64_t)uffdio_copy.copy);
	} else {
		if (test_uffdio_copy_eexist && retry) {
			test_uffdio_copy_eexist = false;
			retry_copy_page(ufd, &uffdio_copy, offset);
		}
		return 1;
	}
	return 0;
}

static int copy_page_retry(int ufd, unsigned long offset)
{
	return __copy_page(ufd, offset, true);
}

static int copy_page(int ufd, unsigned long offset)
{
	return __copy_page(ufd, offset, false);
}

static int uffd_read_msg(int ufd, struct uffd_msg *msg)
{
	int ret = read(uffd, msg, sizeof(*msg));

	if (ret != sizeof(*msg)) {
		if (ret < 0) {
			if (errno == EAGAIN)
				return 1;
			err("blocking read error");
		} else {
			err("short read");
		}
	}

	return 0;
}

static void uffd_handle_page_fault(struct uffd_msg *msg,
				   struct uffd_stats *stats)
{
	unsigned long offset;

	if (msg->event != UFFD_EVENT_PAGEFAULT)
		err("unexpected msg event %u", msg->event);

	if (msg->arg.pagefault.flags & UFFD_PAGEFAULT_FLAG_WP) {
		/* Write protect page faults */
		wp_range(uffd, msg->arg.pagefault.address, page_size, false);
		stats->wp_faults++;
	} else if (msg->arg.pagefault.flags & UFFD_PAGEFAULT_FLAG_MINOR) {
		uint8_t *area;
		int b;

		/*
		 * 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).
		 */

		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);
		stats->minor_faults++;
	} else {
		/* Missing page faults */
		if (msg->arg.pagefault.flags & UFFD_PAGEFAULT_FLAG_WRITE)
			err("unexpected write fault");

		offset = (char *)(unsigned long)msg->arg.pagefault.address - area_dst;
		offset &= ~(page_size-1);

		if (copy_page(uffd, offset))
			stats->missing_faults++;
	}
}

static void *uffd_poll_thread(void *arg)
{
	struct uffd_stats *stats = (struct uffd_stats *)arg;
	unsigned long cpu = stats->cpu;
	struct pollfd pollfd[2];
	struct uffd_msg msg;
	struct uffdio_register uffd_reg;
	int ret;
	char tmp_chr;

	pollfd[0].fd = uffd;
	pollfd[0].events = POLLIN;
	pollfd[1].fd = pipefd[cpu*2];
	pollfd[1].events = POLLIN;

	for (;;) {
		ret = poll(pollfd, 2, -1);
		if (ret <= 0)
			err("poll error: %d", ret);
		if (pollfd[1].revents & POLLIN) {
			if (read(pollfd[1].fd, &tmp_chr, 1) != 1)
				err("read pipefd error");
			break;
		}
		if (!(pollfd[0].revents & POLLIN))
			err("pollfd[0].revents %d", pollfd[0].revents);
		if (uffd_read_msg(uffd, &msg))
			continue;
		switch (msg.event) {
		default:
			err("unexpected msg event %u\n", msg.event);
			break;
		case UFFD_EVENT_PAGEFAULT:
			uffd_handle_page_fault(&msg, stats);
			break;
		case UFFD_EVENT_FORK:
			close(uffd);
			uffd = msg.arg.fork.ufd;
			pollfd[0].fd = uffd;
			break;
		case UFFD_EVENT_REMOVE:
			uffd_reg.range.start = msg.arg.remove.start;
			uffd_reg.range.len = msg.arg.remove.end -
				msg.arg.remove.start;
			if (ioctl(uffd, UFFDIO_UNREGISTER, &uffd_reg.range))
				err("remove failure");
			break;
		case UFFD_EVENT_REMAP:
			area_dst = (char *)(unsigned long)msg.arg.remap.to;
			break;
		}
	}

	return NULL;
}

pthread_mutex_t uffd_read_mutex = PTHREAD_MUTEX_INITIALIZER;

static void *uffd_read_thread(void *arg)
{
	struct uffd_stats *stats = (struct uffd_stats *)arg;
	struct uffd_msg msg;

	pthread_mutex_unlock(&uffd_read_mutex);
	/* from here cancellation is ok */

	for (;;) {
		if (uffd_read_msg(uffd, &msg))
			continue;
		uffd_handle_page_fault(&msg, stats);
	}

	return NULL;
}

static void *background_thread(void *arg)
{
	unsigned long cpu = (unsigned long) arg;
	unsigned long page_nr, start_nr, mid_nr, end_nr;

	start_nr = cpu * nr_pages_per_cpu;
	end_nr = (cpu+1) * nr_pages_per_cpu;
	mid_nr = (start_nr + end_nr) / 2;

	/* Copy the first half of the pages */
	for (page_nr = start_nr; page_nr < mid_nr; page_nr++)
		copy_page_retry(uffd, page_nr * page_size);

	/*
	 * If we need to test uffd-wp, set it up now.  Then we'll have
	 * at least the first half of the pages mapped already which
	 * can be write-protected for testing
	 */
	if (test_uffdio_wp)
		wp_range(uffd, (unsigned long)area_dst + start_nr * page_size,
			nr_pages_per_cpu * page_size, true);

	/*
	 * Continue the 2nd half of the page copying, handling write
	 * protection faults if any
	 */
	for (page_nr = mid_nr; page_nr < end_nr; page_nr++)
		copy_page_retry(uffd, page_nr * page_size);

	return NULL;
}

static int stress(struct uffd_stats *uffd_stats)
{
	unsigned long cpu;
	pthread_t locking_threads[nr_cpus];
	pthread_t uffd_threads[nr_cpus];
	pthread_t background_threads[nr_cpus];

	finished = 0;
	for (cpu = 0; cpu < nr_cpus; cpu++) {
		if (pthread_create(&locking_threads[cpu], &attr,
				   locking_thread, (void *)cpu))
			return 1;
		if (bounces & BOUNCE_POLL) {
			if (pthread_create(&uffd_threads[cpu], &attr,
					   uffd_poll_thread,
					   (void *)&uffd_stats[cpu]))
				return 1;
		} else {
			if (pthread_create(&uffd_threads[cpu], &attr,
					   uffd_read_thread,
					   (void *)&uffd_stats[cpu]))
				return 1;
			pthread_mutex_lock(&uffd_read_mutex);
		}
		if (pthread_create(&background_threads[cpu], &attr,
				   background_thread, (void *)cpu))
			return 1;
	}
	for (cpu = 0; cpu < nr_cpus; cpu++)
		if (pthread_join(background_threads[cpu], NULL))
			return 1;

	/*
	 * Be strict and immediately zap area_src, the whole area has
	 * been transferred already by the background treads. The
	 * area_src could then be faulted in in a racy way by still
	 * running uffdio_threads reading zeropages after we zapped
	 * area_src (but they're guaranteed to get -EEXIST from
	 * UFFDIO_COPY without writing zero pages into area_dst
	 * because the background threads already completed).
	 */
	uffd_test_ops->release_pages(area_src);

	finished = 1;
	for (cpu = 0; cpu < nr_cpus; cpu++)
		if (pthread_join(locking_threads[cpu], NULL))
			return 1;

	for (cpu = 0; cpu < nr_cpus; cpu++) {
		char c;
		if (bounces & BOUNCE_POLL) {
			if (write(pipefd[cpu*2+1], &c, 1) != 1)
				err("pipefd write error");
			if (pthread_join(uffd_threads[cpu],
					 (void *)&uffd_stats[cpu]))
				return 1;
		} else {
			if (pthread_cancel(uffd_threads[cpu]))
				return 1;
			if (pthread_join(uffd_threads[cpu], NULL))
				return 1;
		}
	}

	return 0;
}

sigjmp_buf jbuf, *sigbuf;

static void sighndl(int sig, siginfo_t *siginfo, void *ptr)
{
	if (sig == SIGBUS) {
		if (sigbuf)
			siglongjmp(*sigbuf, 1);
		abort();
	}
}

/*
 * For non-cooperative userfaultfd test we fork() a process that will
 * generate pagefaults, will mremap the area monitored by the
 * userfaultfd and at last this process will release the monitored
 * area.
 * For the anonymous and shared memory the area is divided into two
 * parts, the first part is accessed before mremap, and the second
 * part is accessed after mremap. Since hugetlbfs does not support
 * mremap, the entire monitored area is accessed in a single pass for
 * HUGETLB_TEST.
 * The release of the pages currently generates event for shmem and
 * anonymous memory (UFFD_EVENT_REMOVE), hence it is not checked
 * for hugetlb.
 * For signal test(UFFD_FEATURE_SIGBUS), signal_test = 1, we register
 * monitored area, generate pagefaults and test that signal is delivered.
 * Use UFFDIO_COPY to allocate missing page and retry. For signal_test = 2
 * test robustness use case - we release monitored area, fork a process
 * that will generate pagefaults and verify signal is generated.
 * 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)
{
	unsigned long nr;
	unsigned long long count;
	unsigned long split_nr_pages;
	unsigned long lastnr;
	struct sigaction act;
	unsigned long signalled = 0;

	if (test_type != TEST_HUGETLB)
		split_nr_pages = (nr_pages + 1) / 2;
	else
		split_nr_pages = nr_pages;

	if (signal_test) {
		sigbuf = &jbuf;
		memset(&act, 0, sizeof(act));
		act.sa_sigaction = sighndl;
		act.sa_flags = SA_SIGINFO;
		if (sigaction(SIGBUS, &act, 0))
			err("sigaction");
		lastnr = (unsigned long)-1;
	}

	for (nr = 0; nr < split_nr_pages; nr++) {
		int steps = 1;
		unsigned long offset = nr * page_size;

		if (signal_test) {
			if (sigsetjmp(*sigbuf, 1) != 0) {
				if (steps == 1 && nr == lastnr)
					err("Signal repeated");

				lastnr = nr;
				if (signal_test == 1) {
					if (steps == 1) {
						/* This is a MISSING request */
						steps++;
						if (copy_page(uffd, offset))
							signalled++;
					} else {
						/* This is a WP request */
						assert(steps == 2);
						wp_range(uffd,
							 (__u64)area_dst +
							 offset,
							 page_size, false);
					}
				} else {
					signalled++;
					continue;
				}
			}
		}

		count = *area_count(area_dst, nr);
		if (count != count_verify[nr])
			err("nr %lu memory corruption %llu %llu\n",
			    nr, count, count_verify[nr]);
		/*
		 * Trigger write protection if there is by writing
		 * the same value back.
		 */
		*area_count(area_dst, nr) = count;
	}

	if (signal_test)
		return signalled != split_nr_pages;

	if (test_type == TEST_HUGETLB)
		return 0;

	area_dst = mremap(area_dst, nr_pages * page_size,  nr_pages * page_size,
			  MREMAP_MAYMOVE | MREMAP_FIXED, area_src);
	if (area_dst == MAP_FAILED)
		err("mremap");
	/* Reset area_src since we just clobbered it */
	area_src = NULL;

	for (; nr < nr_pages; nr++) {
		count = *area_count(area_dst, nr);
		if (count != count_verify[nr]) {
			err("nr %lu memory corruption %llu %llu\n",
			    nr, count, count_verify[nr]);
		}
		/*
		 * Trigger write protection if there is by writing
		 * the same value back.
		 */
		*area_count(area_dst, nr) = count;
	}

	uffd_test_ops->release_pages(area_dst);

	for (nr = 0; nr < nr_pages; nr++)
		if (my_bcmp(area_dst + nr * page_size, zeropage, page_size))
			err("nr %lu is not zero", nr);

	return 0;
}

static void retry_uffdio_zeropage(int ufd,
				  struct uffdio_zeropage *uffdio_zeropage,
				  unsigned long offset)
{
	uffd_test_ops->alias_mapping(&uffdio_zeropage->range.start,
				     uffdio_zeropage->range.len,
				     offset);
	if (ioctl(ufd, UFFDIO_ZEROPAGE, uffdio_zeropage)) {
		if (uffdio_zeropage->zeropage != -EEXIST)
			err("UFFDIO_ZEROPAGE error: %"PRId64,
			    (int64_t)uffdio_zeropage->zeropage);
	} else {
		err("UFFDIO_ZEROPAGE error: %"PRId64,
		    (int64_t)uffdio_zeropage->zeropage);
	}
}

static int __uffdio_zeropage(int ufd, unsigned long offset, bool retry)
{
	struct uffdio_zeropage uffdio_zeropage;
	int ret;
	unsigned long has_zeropage;
	__s64 res;

	has_zeropage = uffd_test_ops->expected_ioctls & (1 << _UFFDIO_ZEROPAGE);

	if (offset >= nr_pages * page_size)
		err("unexpected offset %lu", offset);
	uffdio_zeropage.range.start = (unsigned long) area_dst + offset;
	uffdio_zeropage.range.len = page_size;
	uffdio_zeropage.mode = 0;
	ret = ioctl(ufd, UFFDIO_ZEROPAGE, &uffdio_zeropage);
	res = uffdio_zeropage.zeropage;
	if (ret) {
		/* real retval in ufdio_zeropage.zeropage */
		if (has_zeropage)
			err("UFFDIO_ZEROPAGE error: %"PRId64, (int64_t)res);
		else if (res != -EINVAL)
			err("UFFDIO_ZEROPAGE not -EINVAL");
	} else if (has_zeropage) {
		if (res != page_size) {
			err("UFFDIO_ZEROPAGE unexpected size");
		} else {
			if (test_uffdio_zeropage_eexist && retry) {
				test_uffdio_zeropage_eexist = false;
				retry_uffdio_zeropage(ufd, &uffdio_zeropage,
						      offset);
			}
			return 1;
		}
	} else
		err("UFFDIO_ZEROPAGE succeeded");

	return 0;
}

static int uffdio_zeropage(int ufd, unsigned long offset)
{
	return __uffdio_zeropage(ufd, offset, false);
}

/* exercise UFFDIO_ZEROPAGE */
static int userfaultfd_zeropage_test(void)
{
	struct uffdio_register uffdio_register;
	unsigned long expected_ioctls;

	printf("testing UFFDIO_ZEROPAGE: ");
	fflush(stdout);

	uffd_test_ctx_init(0);

	uffdio_register.range.start = (unsigned long) area_dst;
	uffdio_register.range.len = nr_pages * page_size;
	uffdio_register.mode = UFFDIO_REGISTER_MODE_MISSING;
	if (test_uffdio_wp)
		uffdio_register.mode |= UFFDIO_REGISTER_MODE_WP;
	if (ioctl(uffd, UFFDIO_REGISTER, &uffdio_register))
		err("register failure");

	expected_ioctls = uffd_test_ops->expected_ioctls;
	if ((uffdio_register.ioctls & expected_ioctls) != expected_ioctls)
		err("unexpected missing ioctl for anon memory");

	if (uffdio_zeropage(uffd, 0))
		if (my_bcmp(area_dst, zeropage, page_size))
			err("zeropage is not zero");

	printf("done.\n");
	return 0;
}

static int userfaultfd_events_test(void)
{
	struct uffdio_register uffdio_register;
	unsigned long expected_ioctls;
	pthread_t uffd_mon;
	int err, features;
	pid_t pid;
	char c;
	struct uffd_stats stats = { 0 };

	printf("testing events (fork, remap, remove): ");
	fflush(stdout);

	features = UFFD_FEATURE_EVENT_FORK | UFFD_FEATURE_EVENT_REMAP |
		UFFD_FEATURE_EVENT_REMOVE;
	uffd_test_ctx_init(features);

	fcntl(uffd, F_SETFL, uffd_flags | O_NONBLOCK);

	uffdio_register.range.start = (unsigned long) area_dst;
	uffdio_register.range.len = nr_pages * page_size;
	uffdio_register.mode = UFFDIO_REGISTER_MODE_MISSING;
	if (test_uffdio_wp)
		uffdio_register.mode |= UFFDIO_REGISTER_MODE_WP;
	if (ioctl(uffd, UFFDIO_REGISTER, &uffdio_register))
		err("register failure");

	expected_ioctls = uffd_test_ops->expected_ioctls;
	if ((uffdio_register.ioctls & expected_ioctls) != expected_ioctls)
		err("unexpected missing ioctl for anon memory");

	if (pthread_create(&uffd_mon, &attr, uffd_poll_thread, &stats))
		err("uffd_poll_thread create");

	pid = fork();
	if (pid < 0)
		err("fork");

	if (!pid)
		exit(faulting_process(0));

	waitpid(pid, &err, 0);
	if (err)
		err("faulting process failed");
	if (write(pipefd[1], &c, sizeof(c)) != sizeof(c))
		err("pipe write");
	if (pthread_join(uffd_mon, NULL))
		return 1;

	uffd_stats_report(&stats, 1);

	return stats.missing_faults != nr_pages;
}

static int userfaultfd_sig_test(void)
{
	struct uffdio_register uffdio_register;
	unsigned long expected_ioctls;
	unsigned long userfaults;
	pthread_t uffd_mon;
	int err, features;
	pid_t pid;
	char c;
	struct uffd_stats stats = { 0 };

	printf("testing signal delivery: ");
	fflush(stdout);

	features = UFFD_FEATURE_EVENT_FORK|UFFD_FEATURE_SIGBUS;
	uffd_test_ctx_init(features);

	fcntl(uffd, F_SETFL, uffd_flags | O_NONBLOCK);

	uffdio_register.range.start = (unsigned long) area_dst;
	uffdio_register.range.len = nr_pages * page_size;
	uffdio_register.mode = UFFDIO_REGISTER_MODE_MISSING;
	if (test_uffdio_wp)
		uffdio_register.mode |= UFFDIO_REGISTER_MODE_WP;
	if (ioctl(uffd, UFFDIO_REGISTER, &uffdio_register))
		err("register failure");

	expected_ioctls = uffd_test_ops->expected_ioctls;
	if ((uffdio_register.ioctls & expected_ioctls) != expected_ioctls)
		err("unexpected missing ioctl for anon memory");

	if (faulting_process(1))
		err("faulting process failed");

	uffd_test_ops->release_pages(area_dst);

	if (pthread_create(&uffd_mon, &attr, uffd_poll_thread, &stats))
		err("uffd_poll_thread create");

	pid = fork();
	if (pid < 0)
		err("fork");

	if (!pid)
		exit(faulting_process(2));

	waitpid(pid, &err, 0);
	if (err)
		err("faulting process failed");
	if (write(pipefd[1], &c, sizeof(c)) != sizeof(c))
		err("pipe write");
	if (pthread_join(uffd_mon, (void **)&userfaults))
		return 1;

	printf("done.\n");
	if (userfaults)
		err("Signal test failed, userfaults: %ld", userfaults);

	return userfaults != 0;
}

static int userfaultfd_minor_test(void)
{
	struct uffdio_register uffdio_register;
	unsigned long expected_ioctls;
	unsigned long p;
	pthread_t uffd_mon;
	uint8_t expected_byte;
	void *expected_page;
	char c;
	struct uffd_stats stats = { 0 };
	uint64_t req_features, features_out;

	if (!test_uffdio_minor)
		return 0;

	printf("testing minor faults: ");
	fflush(stdout);

	if (test_type == TEST_HUGETLB)
		req_features = UFFD_FEATURE_MINOR_HUGETLBFS;
	else if (test_type == TEST_SHMEM)
		req_features = UFFD_FEATURE_MINOR_SHMEM;
	else
		return 1;

	features_out = req_features;
	uffd_test_ctx_init_ext(&features_out);
	/* If kernel reports required features aren't supported, skip test. */
	if ((features_out & req_features) != req_features) {
		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))
		err("register failure");

	expected_ioctls = uffd_test_ops->expected_ioctls;
	expected_ioctls |= 1 << _UFFDIO_CONTINUE;
	if ((uffdio_register.ioctls & expected_ioctls) != expected_ioctls)
		err("unexpected missing ioctl(s)");

	/*
	 * 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, &stats))
		err("uffd_poll_thread create");

	/*
	 * 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))
		err("out of memory");

	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))
			err("unexpected page contents after minor fault");
	}

	if (write(pipefd[1], &c, sizeof(c)) != sizeof(c))
		err("pipe write");
	if (pthread_join(uffd_mon, NULL))
		return 1;

	uffd_stats_report(&stats, 1);

	return stats.missing_faults != 0 || stats.minor_faults != nr_pages;
}

#define BIT_ULL(nr)                   (1ULL << (nr))
#define PM_SOFT_DIRTY                 BIT_ULL(55)
#define PM_MMAP_EXCLUSIVE             BIT_ULL(56)
#define PM_UFFD_WP                    BIT_ULL(57)
#define PM_FILE                       BIT_ULL(61)
#define PM_SWAP                       BIT_ULL(62)
#define PM_PRESENT                    BIT_ULL(63)

static int pagemap_open(void)
{
	int fd = open("/proc/self/pagemap", O_RDONLY);

	if (fd < 0)
		err("open pagemap");

	return fd;
}

static uint64_t pagemap_read_vaddr(int fd, void *vaddr)
{
	uint64_t value;
	int ret;

	ret = pread(fd, &value, sizeof(uint64_t),
		    ((uint64_t)vaddr >> 12) * sizeof(uint64_t));
	if (ret != sizeof(uint64_t))
		err("pread() on pagemap failed");

	return value;
}

/* This macro let __LINE__ works in err() */
#define  pagemap_check_wp(value, wp) do {				\
		if (!!(value & PM_UFFD_WP) != wp)			\
			err("pagemap uffd-wp bit error: 0x%"PRIx64, value); \
	} while (0)

static int pagemap_test_fork(bool present)
{
	pid_t child = fork();
	uint64_t value;
	int fd, result;

	if (!child) {
		/* Open the pagemap fd of the child itself */
		fd = pagemap_open();
		value = pagemap_read_vaddr(fd, area_dst);
		/*
		 * After fork() uffd-wp bit should be gone as long as we're
		 * without UFFD_FEATURE_EVENT_FORK
		 */
		pagemap_check_wp(value, false);
		/* Succeed */
		exit(0);
	}
	waitpid(child, &result, 0);
	return result;
}

static void userfaultfd_pagemap_test(unsigned int test_pgsize)
{
	struct uffdio_register uffdio_register;
	int pagemap_fd;
	uint64_t value;

	/* Pagemap tests uffd-wp only */
	if (!test_uffdio_wp)
		return;

	/* Not enough memory to test this page size */
	if (test_pgsize > nr_pages * page_size)
		return;

	printf("testing uffd-wp with pagemap (pgsize=%u): ", test_pgsize);
	/* Flush so it doesn't flush twice in parent/child later */
	fflush(stdout);

	uffd_test_ctx_init(0);

	if (test_pgsize > page_size) {
		/* This is a thp test */
		if (madvise(area_dst, nr_pages * page_size, MADV_HUGEPAGE))
			err("madvise(MADV_HUGEPAGE) failed");
	} else if (test_pgsize == page_size) {
		/* This is normal page test; force no thp */
		if (madvise(area_dst, nr_pages * page_size, MADV_NOHUGEPAGE))
			err("madvise(MADV_NOHUGEPAGE) failed");
	}

	uffdio_register.range.start = (unsigned long) area_dst;
	uffdio_register.range.len = nr_pages * page_size;
	uffdio_register.mode = UFFDIO_REGISTER_MODE_WP;
	if (ioctl(uffd, UFFDIO_REGISTER, &uffdio_register))
		err("register failed");

	pagemap_fd = pagemap_open();

	/* Touch the page */
	*area_dst = 1;
	wp_range(uffd, (uint64_t)area_dst, test_pgsize, true);
	value = pagemap_read_vaddr(pagemap_fd, area_dst);
	pagemap_check_wp(value, true);
	/* Make sure uffd-wp bit dropped when fork */
	if (pagemap_test_fork(true))
		err("Detected stall uffd-wp bit in child");

	/* Exclusive required or PAGEOUT won't work */
	if (!(value & PM_MMAP_EXCLUSIVE))
		err("multiple mapping detected: 0x%"PRIx64, value);

	if (madvise(area_dst, test_pgsize, MADV_PAGEOUT))
		err("madvise(MADV_PAGEOUT) failed");

	/* Uffd-wp should persist even swapped out */
	value = pagemap_read_vaddr(pagemap_fd, area_dst);
	pagemap_check_wp(value, true);
	/* Make sure uffd-wp bit dropped when fork */
	if (pagemap_test_fork(false))
		err("Detected stall uffd-wp bit in child");

	/* Unprotect; this tests swap pte modifications */
	wp_range(uffd, (uint64_t)area_dst, page_size, false);
	value = pagemap_read_vaddr(pagemap_fd, area_dst);
	pagemap_check_wp(value, false);

	/* Fault in the page from disk */
	*area_dst = 2;
	value = pagemap_read_vaddr(pagemap_fd, area_dst);
	pagemap_check_wp(value, false);

	close(pagemap_fd);
	printf("done\n");
}

static int userfaultfd_stress(void)
{
	void *area;
	char *tmp_area;
	unsigned long nr;
	struct uffdio_register uffdio_register;
	struct uffd_stats uffd_stats[nr_cpus];

	uffd_test_ctx_init(0);

	if (posix_memalign(&area, page_size, page_size))
		err("out of memory");
	zeropage = area;
	bzero(zeropage, page_size);

	pthread_mutex_lock(&uffd_read_mutex);

	pthread_attr_init(&attr);
	pthread_attr_setstacksize(&attr, 16*1024*1024);

	while (bounces--) {
		unsigned long expected_ioctls;

		printf("bounces: %d, mode:", bounces);
		if (bounces & BOUNCE_RANDOM)
			printf(" rnd");
		if (bounces & BOUNCE_RACINGFAULTS)
			printf(" racing");
		if (bounces & BOUNCE_VERIFY)
			printf(" ver");
		if (bounces & BOUNCE_POLL)
			printf(" poll");
		else
			printf(" read");
		printf(", ");
		fflush(stdout);

		if (bounces & BOUNCE_POLL)
			fcntl(uffd, F_SETFL, uffd_flags | O_NONBLOCK);
		else
			fcntl(uffd, F_SETFL, uffd_flags & ~O_NONBLOCK);

		/* register */
		uffdio_register.range.start = (unsigned long) area_dst;
		uffdio_register.range.len = nr_pages * page_size;
		uffdio_register.mode = UFFDIO_REGISTER_MODE_MISSING;
		if (test_uffdio_wp)
			uffdio_register.mode |= UFFDIO_REGISTER_MODE_WP;
		if (ioctl(uffd, UFFDIO_REGISTER, &uffdio_register))
			err("register failure");
		expected_ioctls = uffd_test_ops->expected_ioctls;
		if ((uffdio_register.ioctls & expected_ioctls) !=
		    expected_ioctls)
			err("unexpected missing ioctl for anon memory");

		if (area_dst_alias) {
			uffdio_register.range.start = (unsigned long)
				area_dst_alias;
			if (ioctl(uffd, UFFDIO_REGISTER, &uffdio_register))
				err("register failure alias");
		}

		/*
		 * The madvise done previously isn't enough: some
		 * uffd_thread could have read userfaults (one of
		 * those already resolved by the background thread)
		 * and it may be in the process of calling
		 * UFFDIO_COPY. UFFDIO_COPY will read the zapped
		 * area_src and it would map a zero page in it (of
		 * course such a UFFDIO_COPY is perfectly safe as it'd
		 * return -EEXIST). The problem comes at the next
		 * bounce though: that racing UFFDIO_COPY would
		 * generate zeropages in the area_src, so invalidating
		 * the previous MADV_DONTNEED. Without this additional
		 * MADV_DONTNEED those zeropages leftovers in the
		 * area_src would lead to -EEXIST failure during the
		 * next bounce, effectively leaving a zeropage in the
		 * area_dst.
		 *
		 * Try to comment this out madvise to see the memory
		 * corruption being caught pretty quick.
		 *
		 * khugepaged is also inhibited to collapse THP after
		 * MADV_DONTNEED only after the UFFDIO_REGISTER, so it's
		 * required to MADV_DONTNEED here.
		 */
		uffd_test_ops->release_pages(area_dst);

		uffd_stats_reset(uffd_stats, nr_cpus);

		/* bounce pass */
		if (stress(uffd_stats))
			return 1;

		/* Clear all the write protections if there is any */
		if (test_uffdio_wp)
			wp_range(uffd, (unsigned long)area_dst,
				 nr_pages * page_size, false);

		/* unregister */
		if (ioctl(uffd, UFFDIO_UNREGISTER, &uffdio_register.range))
			err("unregister failure");
		if (area_dst_alias) {
			uffdio_register.range.start = (unsigned long) area_dst;
			if (ioctl(uffd, UFFDIO_UNREGISTER,
				  &uffdio_register.range))
				err("unregister failure alias");
		}

		/* verification */
		if (bounces & BOUNCE_VERIFY)
			for (nr = 0; nr < nr_pages; nr++)
				if (*area_count(area_dst, nr) != count_verify[nr])
					err("error area_count %llu %llu %lu\n",
					    *area_count(area_src, nr),
					    count_verify[nr], nr);

		/* prepare next bounce */
		tmp_area = area_src;
		area_src = area_dst;
		area_dst = tmp_area;

		tmp_area = area_src_alias;
		area_src_alias = area_dst_alias;
		area_dst_alias = tmp_area;

		uffd_stats_report(uffd_stats, nr_cpus);
	}

	if (test_type == TEST_ANON) {
		/*
		 * shmem/hugetlb won't be able to run since they have different
		 * behavior on fork() (file-backed memory normally drops ptes
		 * directly when fork), meanwhile the pagemap test will verify
		 * pgtable entry of fork()ed child.
		 */
		userfaultfd_pagemap_test(page_size);
		/*
		 * Hard-code for x86_64 for now for 2M THP, as x86_64 is
		 * currently the only one that supports uffd-wp
		 */
		userfaultfd_pagemap_test(page_size * 512);
	}

	return userfaultfd_zeropage_test() || userfaultfd_sig_test()
		|| userfaultfd_events_test() || userfaultfd_minor_test();
}

/*
 * Copied from mlock2-tests.c
 */
unsigned long default_huge_page_size(void)
{
	unsigned long hps = 0;
	char *line = NULL;
	size_t linelen = 0;
	FILE *f = fopen("/proc/meminfo", "r");

	if (!f)
		return 0;
	while (getline(&line, &linelen, f) > 0) {
		if (sscanf(line, "Hugepagesize:       %lu kB", &hps) == 1) {
			hps <<= 10;
			break;
		}
	}

	free(line);
	fclose(f);
	return hps;
}

static void set_test_type(const char *type)
{
	if (!strcmp(type, "anon")) {
		test_type = TEST_ANON;
		uffd_test_ops = &anon_uffd_test_ops;
		/* Only enable write-protect test for anonymous test */
		test_uffdio_wp = true;
	} else if (!strcmp(type, "hugetlb")) {
		test_type = TEST_HUGETLB;
		uffd_test_ops = &hugetlb_uffd_test_ops;
	} else if (!strcmp(type, "hugetlb_shared")) {
		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;
		uffd_test_ops = &shmem_uffd_test_ops;
		test_uffdio_minor = true;
	} else {
		err("Unknown test type: %s", type);
	}

	if (test_type == TEST_HUGETLB)
		page_size = default_huge_page_size();
	else
		page_size = sysconf(_SC_PAGE_SIZE);

	if (!page_size)
		err("Unable to determine page size");
	if ((unsigned long) area_count(NULL, 0) + sizeof(unsigned long long) * 2
	    > page_size)
		err("Impossible to run this test");
}

static void sigalrm(int sig)
{
	if (sig != SIGALRM)
		abort();
	test_uffdio_copy_eexist = true;
	test_uffdio_zeropage_eexist = true;
	alarm(ALARM_INTERVAL_SECS);
}

int main(int argc, char **argv)
{
	if (argc < 4)
		usage();

	if (signal(SIGALRM, sigalrm) == SIG_ERR)
		err("failed to arm SIGALRM");
	alarm(ALARM_INTERVAL_SECS);

	set_test_type(argv[1]);

	nr_cpus = sysconf(_SC_NPROCESSORS_ONLN);
	nr_pages_per_cpu = atol(argv[2]) * 1024*1024 / page_size /
		nr_cpus;
	if (!nr_pages_per_cpu) {
		_err("invalid MiB");
		usage();
	}

	bounces = atoi(argv[3]);
	if (bounces <= 0) {
		_err("invalid bounces");
		usage();
	}
	nr_pages = nr_pages_per_cpu * nr_cpus;

	if (test_type == TEST_HUGETLB) {
		if (argc < 5)
			usage();
		huge_fd = open(argv[4], O_CREAT | O_RDWR, 0755);
		if (huge_fd < 0)
			err("Open of %s failed", argv[4]);
		if (ftruncate(huge_fd, 0))
			err("ftruncate %s to size 0 failed", argv[4]);
	} else if (test_type == TEST_SHMEM) {
		shm_fd = memfd_create(argv[0], 0);
		if (shm_fd < 0)
			err("memfd_create");
		if (ftruncate(shm_fd, nr_pages * page_size * 2))
			err("ftruncate");
		if (fallocate(shm_fd,
			      FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, 0,
			      nr_pages * page_size * 2))
			err("fallocate");
	}
	printf("nr_pages: %lu, nr_pages_per_cpu: %lu\n",
	       nr_pages, nr_pages_per_cpu);
	return userfaultfd_stress();
}

#else /* __NR_userfaultfd */

#warning "missing __NR_userfaultfd definition"

int main(void)
{
	printf("skip: Skipping userfaultfd test (missing __NR_userfaultfd)\n");
	return KSFT_SKIP;
}

#endif /* __NR_userfaultfd */
