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

This reverts commit 91b66856b8 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-13 04:49:42 -07:00 committed by Suren Baghdasaryan
commit 8f6445acee

View file

@ -87,8 +87,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;
@ -342,121 +341,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)
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;
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;
uffd_test_ops->release_pages(area_src);
uffd_test_ops->release_pages(area_dst);
if (userfaultfd_open(features))
return 1;
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;
}
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");
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))
err("munmap");
*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]))
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;
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;
@ -841,6 +725,32 @@ static int stress(struct uffd_stats *uffd_stats)
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)
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");
if (uffdio_api.api != UFFD_API) {
err("UFFDIO_API error %Lu", uffdio_api.api);
}
*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)
@ -949,8 +859,6 @@ static int faulting_process(int signal_test)
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);
@ -1044,9 +952,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;
@ -1063,6 +973,7 @@ static int userfaultfd_zeropage_test(void)
if (my_bcmp(area_dst, zeropage, page_size))
err("zeropage is not zero");
close(uffd);
printf("done.\n");
return 0;
}
@ -1080,11 +991,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;
@ -1117,6 +1030,8 @@ static int userfaultfd_events_test(void)
if (pthread_join(uffd_mon, NULL))
return 1;
close(uffd);
uffd_stats_report(&stats, 1);
return stats.missing_faults != nr_pages;
@ -1136,10 +1051,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;
@ -1180,6 +1097,7 @@ static int userfaultfd_sig_test(void)
printf("done.\n");
if (userfaults)
err("Signal test failed, userfaults: %ld", userfaults);
close(uffd);
return userfaults != 0;
}
@ -1201,7 +1119,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)) {
@ -1256,6 +1177,8 @@ static int userfaultfd_minor_test(void)
if (pthread_join(uffd_mon, NULL))
return 1;
close(uffd);
uffd_stats_report(&stats, 1);
return stats.missing_faults != 0 || stats.minor_faults != nr_pages;
@ -1267,10 +1190,47 @@ static int userfaultfd_stress(void)
char *tmp_area;
unsigned long nr;
struct uffdio_register uffdio_register;
unsigned long cpu;
struct uffd_stats uffd_stats[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) {
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;
}
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");
}
}
if (posix_memalign(&area, page_size, page_size))
err("out of memory");
@ -1389,6 +1349,7 @@ static int userfaultfd_stress(void)
uffd_stats_report(uffd_stats, nr_cpus);
}
close(uffd);
return userfaultfd_zeropage_test() || userfaultfd_sig_test()
|| userfaultfd_events_test() || userfaultfd_minor_test();
}