133be4e89SPeter Xu // SPDX-License-Identifier: GPL-2.0-only 233be4e89SPeter Xu /* 333be4e89SPeter Xu * Userfaultfd tests common header 433be4e89SPeter Xu * 533be4e89SPeter Xu * Copyright (C) 2015-2023 Red Hat, Inc. 633be4e89SPeter Xu */ 733be4e89SPeter Xu #ifndef __UFFD_COMMON_H__ 833be4e89SPeter Xu #define __UFFD_COMMON_H__ 933be4e89SPeter Xu 1033be4e89SPeter Xu #define _GNU_SOURCE 1176697523SMichael Ellerman #define __SANE_USERSPACE_TYPES__ // Use ll64 1233be4e89SPeter Xu #include <stdio.h> 1333be4e89SPeter Xu #include <errno.h> 1433be4e89SPeter Xu #include <unistd.h> 1533be4e89SPeter Xu #include <stdlib.h> 1633be4e89SPeter Xu #include <sys/types.h> 1733be4e89SPeter Xu #include <sys/stat.h> 1833be4e89SPeter Xu #include <fcntl.h> 1933be4e89SPeter Xu #include <time.h> 2033be4e89SPeter Xu #include <signal.h> 2133be4e89SPeter Xu #include <poll.h> 2233be4e89SPeter Xu #include <string.h> 2333be4e89SPeter Xu #include <linux/mman.h> 2433be4e89SPeter Xu #include <sys/mman.h> 2533be4e89SPeter Xu #include <sys/syscall.h> 2633be4e89SPeter Xu #include <sys/ioctl.h> 2733be4e89SPeter Xu #include <sys/wait.h> 2833be4e89SPeter Xu #include <pthread.h> 2933be4e89SPeter Xu #include <linux/userfaultfd.h> 3033be4e89SPeter Xu #include <setjmp.h> 3133be4e89SPeter Xu #include <stdbool.h> 3233be4e89SPeter Xu #include <assert.h> 3333be4e89SPeter Xu #include <inttypes.h> 3433be4e89SPeter Xu #include <stdint.h> 3533be4e89SPeter Xu #include <sys/random.h> 36*0b9be246SEdward Liaw #include <stdatomic.h> 3733be4e89SPeter Xu 3833be4e89SPeter Xu #include "../kselftest.h" 3933be4e89SPeter Xu #include "vm_util.h" 4033be4e89SPeter Xu 4133be4e89SPeter Xu #define UFFD_FLAGS (O_CLOEXEC | O_NONBLOCK | UFFD_USER_MODE_ONLY) 4233be4e89SPeter Xu 4333be4e89SPeter Xu #define _err(fmt, ...) \ 4433be4e89SPeter Xu do { \ 4533be4e89SPeter Xu int ret = errno; \ 4633be4e89SPeter Xu fprintf(stderr, "ERROR: " fmt, ##__VA_ARGS__); \ 4733be4e89SPeter Xu fprintf(stderr, " (errno=%d, @%s:%d)\n", \ 4833be4e89SPeter Xu ret, __FILE__, __LINE__); \ 4933be4e89SPeter Xu } while (0) 5033be4e89SPeter Xu 5133be4e89SPeter Xu #define errexit(exitcode, fmt, ...) \ 5233be4e89SPeter Xu do { \ 5333be4e89SPeter Xu _err(fmt, ##__VA_ARGS__); \ 5433be4e89SPeter Xu exit(exitcode); \ 5533be4e89SPeter Xu } while (0) 5633be4e89SPeter Xu 5733be4e89SPeter Xu #define err(fmt, ...) errexit(1, fmt, ##__VA_ARGS__) 5833be4e89SPeter Xu 5933be4e89SPeter Xu /* pthread_mutex_t starts at page offset 0 */ 6033be4e89SPeter Xu #define area_mutex(___area, ___nr) \ 6133be4e89SPeter Xu ((pthread_mutex_t *) ((___area) + (___nr)*page_size)) 6233be4e89SPeter Xu /* 6333be4e89SPeter Xu * count is placed in the page after pthread_mutex_t naturally aligned 6433be4e89SPeter Xu * to avoid non alignment faults on non-x86 archs. 6533be4e89SPeter Xu */ 6633be4e89SPeter Xu #define area_count(___area, ___nr) \ 6733be4e89SPeter Xu ((volatile unsigned long long *) ((unsigned long) \ 6833be4e89SPeter Xu ((___area) + (___nr)*page_size + \ 6933be4e89SPeter Xu sizeof(pthread_mutex_t) + \ 7033be4e89SPeter Xu sizeof(unsigned long long) - 1) & \ 7133be4e89SPeter Xu ~(unsigned long)(sizeof(unsigned long long) \ 7233be4e89SPeter Xu - 1))) 7333be4e89SPeter Xu 7433be4e89SPeter Xu /* Userfaultfd test statistics */ 7550834084SPeter Xu struct uffd_args { 7633be4e89SPeter Xu int cpu; 770210c43eSPeter Xu /* Whether apply wr-protects when installing pages */ 780210c43eSPeter Xu bool apply_wp; 7933be4e89SPeter Xu unsigned long missing_faults; 8033be4e89SPeter Xu unsigned long wp_faults; 8133be4e89SPeter Xu unsigned long minor_faults; 827cf0f9e8SAxel Rasmussen 837cf0f9e8SAxel Rasmussen /* A custom fault handler; defaults to uffd_handle_page_fault. */ 847cf0f9e8SAxel Rasmussen void (*handle_fault)(struct uffd_msg *msg, struct uffd_args *args); 8533be4e89SPeter Xu }; 8633be4e89SPeter Xu 8733be4e89SPeter Xu struct uffd_test_ops { 88be39fec4SPeter Xu int (*allocate_area)(void **alloc_area, bool is_src); 8933be4e89SPeter Xu void (*release_pages)(char *rel_area); 9033be4e89SPeter Xu void (*alias_mapping)(__u64 *start, size_t len, unsigned long offset); 9133be4e89SPeter Xu void (*check_pmd_mapping)(void *p, int expect_nr_hpages); 9233be4e89SPeter Xu }; 9333be4e89SPeter Xu typedef struct uffd_test_ops uffd_test_ops_t; 9433be4e89SPeter Xu 95265818efSPeter Xu extern unsigned long nr_cpus, nr_pages, nr_pages_per_cpu, page_size; 9633be4e89SPeter Xu extern char *area_src, *area_src_alias, *area_dst, *area_dst_alias, *area_remap; 97c5cb9036SPeter Xu extern int uffd, uffd_flags, finished, *pipefd, test_type; 98111fd29bSPeter Xu extern bool map_shared; 9962515b5fSPeter Xu extern bool test_uffdio_wp; 10033be4e89SPeter Xu extern unsigned long long *count_verify; 10133be4e89SPeter Xu extern volatile bool test_uffdio_copy_eexist; 102*0b9be246SEdward Liaw extern atomic_bool ready_for_fork; 10333be4e89SPeter Xu 10433be4e89SPeter Xu extern uffd_test_ops_t anon_uffd_test_ops; 10533be4e89SPeter Xu extern uffd_test_ops_t shmem_uffd_test_ops; 10633be4e89SPeter Xu extern uffd_test_ops_t hugetlb_uffd_test_ops; 10733be4e89SPeter Xu extern uffd_test_ops_t *uffd_test_ops; 10833be4e89SPeter Xu 10950834084SPeter Xu void uffd_stats_report(struct uffd_args *args, int n_cpus); 110f9da2426SPeter Xu int uffd_test_ctx_init(uint64_t features, const char **errmsg); 111f9da2426SPeter Xu int userfaultfd_open(uint64_t *features); 11233be4e89SPeter Xu int uffd_read_msg(int ufd, struct uffd_msg *msg); 11333be4e89SPeter Xu void wp_range(int ufd, __u64 start, __u64 len, bool wp); 11450834084SPeter Xu void uffd_handle_page_fault(struct uffd_msg *msg, struct uffd_args *args); 1150210c43eSPeter Xu int __copy_page(int ufd, unsigned long offset, bool retry, bool wp); 1160210c43eSPeter Xu int copy_page(int ufd, unsigned long offset, bool wp); 11733be4e89SPeter Xu void *uffd_poll_thread(void *arg); 11833be4e89SPeter Xu 11956d2afffSJohn Hubbard int uffd_open_dev(unsigned int flags); 12056d2afffSJohn Hubbard int uffd_open_sys(unsigned int flags); 12156d2afffSJohn Hubbard int uffd_open(unsigned int flags); 12256d2afffSJohn Hubbard int uffd_get_features(uint64_t *features); 12356d2afffSJohn Hubbard 12433be4e89SPeter Xu #define TEST_ANON 1 12533be4e89SPeter Xu #define TEST_HUGETLB 2 12633be4e89SPeter Xu #define TEST_SHMEM 3 12733be4e89SPeter Xu 12833be4e89SPeter Xu #endif 129