Revert "BACKPORT: FROMGIT: userfaultfd/selftests: reinitialize test context in each test"

This reverts commit 2ed6377e515707a52d123b735d861a7b8305eceb
as an updated version of the patch-set will be merged later.

Signed-off-by: Lokesh Gidra <lokeshgidra@google.com>
Bug: 187930641
Change-Id: I239e3f80e27d7e86dc9911cc3dd5640fc2d9bf94
This commit is contained in:
Lokesh Gidra 2021-05-17 00:17:01 -07:00 • committed by Michael Bestas
commit 56ccf7d575

View file

@ -85,8 +85,7 @@ 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 int uffd, uffd_flags, finished, *pipefd;
static char *area_src, *area_src_alias, *area_dst, *area_dst_alias;
static char *zeropage;
pthread_attr_t attr;
@ -310,146 +309,6 @@ static struct uffd_test_ops hugetlb_uffd_test_ops = {
static struct uffd_test_ops *uffd_test_ops;
static int 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) {
fprintf(stderr,
"userfaultfd syscall not available in this kernel\n");
return 1;
}
uffd_flags = fcntl(uffd, F_GETFD, NULL);
uffdio_api.api = UFFD_API;
uffdio_api.features = *features;
if (ioctl(uffd, UFFDIO_API, &uffdio_api)) {
fprintf(stderr, "UFFDIO_API failed.\nPlease make sure to "
"run with either root or ptrace capability.\n");
return 1;
}
if (uffdio_api.api != UFFD_API) {
fprintf(stderr, "UFFDIO_API error: %" PRIu64 "\n",
(uint64_t)uffdio_api.api);
return 1;
}
*features = uffdio_api.features;
return 0;
}
static int uffd_test_ctx_init_ext(uint64_t *features)
{
unsigned long nr, cpu;
uffd_test_ops->allocate_area((void **)&area_src);
if (!area_src)
return 1;
uffd_test_ops->allocate_area((void **)&area_dst);
if (!area_dst)
return 1;
if (uffd_test_ops->release_pages(area_src))
return 1;
if (uffd_test_ops->release_pages(area_dst))
return 1;
if (userfaultfd_open(features))
return 1;
count_verify = malloc(nr_pages * sizeof(unsigned long long));
if (!count_verify) {
perror("count_verify");
return 1;
}
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;
}
pipefd = malloc(sizeof(int) * nr_cpus * 2);
if (!pipefd) {
perror("pipefd");
return 1;
}
for (cpu = 0; cpu < nr_cpus; cpu++) {
if (pipe2(&pipefd[cpu * 2], O_CLOEXEC | O_NONBLOCK)) {
perror("pipe");
return 1;
}
}
return 0;
}
static inline int uffd_test_ctx_init(uint64_t features)
{
return uffd_test_ctx_init_ext(&features);
}
static inline int munmap_area(void **area)
{
if (*area) {
if (munmap(*area, nr_pages * page_size)) {
perror("munmap");
return 1;
}
}
*area = NULL;
return 0;
}
static int uffd_test_ctx_clear(void)
{
int ret = 0;
size_t i;
if (pipefd) {
for (i = 0; i < nr_cpus * 2; ++i) {
if (close(pipefd[i])) {
perror("close pipefd");
ret = 1;
}
}
free(pipefd);
pipefd = NULL;
}
if (count_verify) {
free(count_verify);
count_verify = NULL;
}
if (uffd != -1) {
if (close(uffd)) {
perror("close uffd");
ret = 1;
}
uffd = -1;
}
huge_fd_off0 = NULL;
ret |= munmap_area((void **)&area_src);
ret |= munmap_area((void **)&area_src_alias);
ret |= munmap_area((void **)&area_dst);
ret |= munmap_area((void **)&area_dst_alias);
return ret;
}
static int my_bcmp(char *str1, char *str2, size_t n)
{
unsigned long i;
@ -814,6 +673,38 @@ static int stress(unsigned long *userfaults)
return 0;
}
static int userfaultfd_open_ext(uint64_t *features)
{
struct uffdio_api uffdio_api;
uffd = syscall(__NR_userfaultfd, O_CLOEXEC | O_NONBLOCK);
if (uffd < 0) {
fprintf(stderr,
"userfaultfd syscall not available in this kernel\n");
return 1;
}
uffd_flags = fcntl(uffd, F_GETFD, NULL);
uffdio_api.api = UFFD_API;
uffdio_api.features = *features;
if (ioctl(uffd, UFFDIO_API, &uffdio_api)) {
fprintf(stderr, "UFFDIO_API\n");
return 1;
}
if (uffdio_api.api != UFFD_API) {
fprintf(stderr, "UFFDIO_API error %Lu\n", uffdio_api.api);
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)
@ -908,12 +799,8 @@ static int faulting_process(int signal_test)
area_dst = mremap(area_dst, nr_pages * page_size, nr_pages * page_size,
MREMAP_MAYMOVE | MREMAP_FIXED, area_src);
if (area_dst == MAP_FAILED) {
perror("mremap");
exit(1);
}
/* Reset area_src since we just clobbered it */
area_src = NULL;
if (area_dst == MAP_FAILED)
perror("mremap"), exit(1);
for (; nr < nr_pages; nr++) {
count = *area_count(area_dst, nr);
@ -1018,9 +905,11 @@ static int userfaultfd_zeropage_test(void)
printf("testing UFFDIO_ZEROPAGE: ");
fflush(stdout);
if (uffd_test_ctx_clear() || uffd_test_ctx_init(0))
if (uffd_test_ops->release_pages(area_dst))
return 1;
if (userfaultfd_open(0) < 0)
return 1;
uffdio_register.range.start = (unsigned long) area_dst;
uffdio_register.range.len = nr_pages * page_size;
uffdio_register.mode = UFFDIO_REGISTER_MODE_MISSING;
@ -1039,6 +928,7 @@ static int userfaultfd_zeropage_test(void)
fprintf(stderr, "zeropage is not zero\n"), exit(1);
}
close(uffd);
printf("done.\n");
return 0;
}
@ -1056,11 +946,13 @@ static int userfaultfd_events_test(void)
printf("testing events (fork, remap, remove): ");
fflush(stdout);
features = UFFD_FEATURE_EVENT_FORK | UFFD_FEATURE_EVENT_REMAP |
UFFD_FEATURE_EVENT_REMOVE;
if (uffd_test_ctx_clear() || uffd_test_ctx_init(features))
if (uffd_test_ops->release_pages(area_dst))
return 1;
features = UFFD_FEATURE_EVENT_FORK | UFFD_FEATURE_EVENT_REMAP |
UFFD_FEATURE_EVENT_REMOVE;
if (userfaultfd_open(features) < 0)
return 1;
fcntl(uffd, F_SETFL, uffd_flags | O_NONBLOCK);
uffdio_register.range.start = (unsigned long) area_dst;
@ -1095,6 +987,7 @@ static int userfaultfd_events_test(void)
if (pthread_join(uffd_mon, (void **)&userfaults))
return 1;
close(uffd);
printf("userfaults: %ld\n", userfaults);
return userfaults != nr_pages;
@ -1113,10 +1006,12 @@ static int userfaultfd_sig_test(void)
printf("testing signal delivery: ");
fflush(stdout);
features = UFFD_FEATURE_EVENT_FORK|UFFD_FEATURE_SIGBUS;
if (uffd_test_ctx_clear() || uffd_test_ctx_init(features))
if (uffd_test_ops->release_pages(area_dst))
return 1;
features = UFFD_FEATURE_EVENT_FORK|UFFD_FEATURE_SIGBUS;
if (userfaultfd_open(features) < 0)
return 1;
fcntl(uffd, F_SETFL, uffd_flags | O_NONBLOCK);
uffdio_register.range.start = (unsigned long) area_dst;
@ -1161,6 +1056,7 @@ static int userfaultfd_sig_test(void)
if (userfaults)
fprintf(stderr, "Signal test failed, userfaults: %ld\n",
userfaults);
close(uffd);
return userfaults != 0;
}
@ -1182,7 +1078,10 @@ static int userfaultfd_minor_test(void)
printf("testing minor faults: ");
fflush(stdout);
if (uffd_test_ctx_clear() || uffd_test_ctx_init_ext(&features))
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)) {
@ -1251,6 +1150,7 @@ static int userfaultfd_minor_test(void)
return 1;
printf("userfaults: %ld\n", userfaults);
close(uffd);
return userfaults != nr_pages;
}
@ -1260,11 +1160,51 @@ static int userfaultfd_stress(void)
char *tmp_area;
unsigned long nr;
struct uffdio_register uffdio_register;
unsigned long cpu;
int err;
unsigned long userfaults[nr_cpus];
if (uffd_test_ctx_init(0))
uffd_test_ops->allocate_area((void **)&area_src);
if (!area_src)
return 1;
uffd_test_ops->allocate_area((void **)&area_dst);
if (!area_dst)
return 1;
if (userfaultfd_open(0) < 0)
return 1;
count_verify = malloc(nr_pages * sizeof(unsigned long long));
if (!count_verify) {
perror("count_verify");
return 1;
}
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;
}
pipefd = malloc(sizeof(int) * nr_cpus * 2);
if (!pipefd) {
perror("pipefd");
return 1;
}
for (cpu = 0; cpu < nr_cpus; cpu++) {
if (pipe2(&pipefd[cpu*2], O_CLOEXEC | O_NONBLOCK)) {
perror("pipe");
return 1;
}
}
if (posix_memalign(&area, page_size, page_size)) {
fprintf(stderr, "out of memory\n");
@ -1402,6 +1342,7 @@ static int userfaultfd_stress(void)
if (err)
return err;
close(uffd);
return userfaultfd_zeropage_test() || userfaultfd_sig_test()
|| userfaultfd_events_test() || userfaultfd_minor_test();
}