1 /*
2  * Stress userfaultfd syscall.
3  *
4  *  Copyright (C) 2015  Red Hat, Inc.
5  *
6  *  This work is licensed under the terms of the GNU GPL, version 2. See
7  *  the COPYING file in the top-level directory.
8  *
9  * This test allocates two virtual areas and bounces the physical
10  * memory across the two virtual areas (from area_src to area_dst)
11  * using userfaultfd.
12  *
13  * There are three threads running per CPU:
14  *
15  * 1) one per-CPU thread takes a per-page pthread_mutex in a random
16  *    page of the area_dst (while the physical page may still be in
17  *    area_src), and increments a per-page counter in the same page,
18  *    and checks its value against a verification region.
19  *
20  * 2) another per-CPU thread handles the userfaults generated by
21  *    thread 1 above. userfaultfd blocking reads or poll() modes are
22  *    exercised interleaved.
23  *
24  * 3) one last per-CPU thread transfers the memory in the background
25  *    at maximum bandwidth (if not already transferred by thread
26  *    2). Each cpu thread takes cares of transferring a portion of the
27  *    area.
28  *
29  * When all threads of type 3 completed the transfer, one bounce is
30  * complete. area_src and area_dst are then swapped. All threads are
31  * respawned and so the bounce is immediately restarted in the
32  * opposite direction.
33  *
34  * per-CPU threads 1 by triggering userfaults inside
35  * pthread_mutex_lock will also verify the atomicity of the memory
36  * transfer (UFFDIO_COPY).
37  *
38  * The program takes two parameters: the amounts of physical memory in
39  * megabytes (MiB) of the area and the number of bounces to execute.
40  *
41  * # 100MiB 99999 bounces
42  * ./userfaultfd 100 99999
43  *
44  * # 1GiB 99 bounces
45  * ./userfaultfd 1000 99
46  *
47  * # 10MiB-~6GiB 999 bounces, continue forever unless an error triggers
48  * while ./userfaultfd $[RANDOM % 6000 + 10] 999; do true; done
49  */
50 
51 #define _GNU_SOURCE
52 #include <stdio.h>
53 #include <errno.h>
54 #include <unistd.h>
55 #include <stdlib.h>
56 #include <sys/types.h>
57 #include <sys/stat.h>
58 #include <fcntl.h>
59 #include <time.h>
60 #include <signal.h>
61 #include <poll.h>
62 #include <string.h>
63 #include <sys/mman.h>
64 #include <sys/syscall.h>
65 #include <sys/ioctl.h>
66 #include <sys/wait.h>
67 #include <pthread.h>
68 #include <linux/userfaultfd.h>
69 #include <setjmp.h>
70 #include <stdbool.h>
71 
72 #include "../kselftest.h"
73 
74 #ifdef __NR_userfaultfd
75 
76 static unsigned long nr_cpus, nr_pages, nr_pages_per_cpu, page_size;
77 
78 #define BOUNCE_RANDOM		(1<<0)
79 #define BOUNCE_RACINGFAULTS	(1<<1)
80 #define BOUNCE_VERIFY		(1<<2)
81 #define BOUNCE_POLL		(1<<3)
82 static int bounces;
83 
84 #define TEST_ANON	1
85 #define TEST_HUGETLB	2
86 #define TEST_SHMEM	3
87 static int test_type;
88 
89 /* exercise the test_uffdio_*_eexist every ALARM_INTERVAL_SECS */
90 #define ALARM_INTERVAL_SECS 10
91 static volatile bool test_uffdio_copy_eexist = true;
92 static volatile bool test_uffdio_zeropage_eexist = true;
93 
94 static bool map_shared;
95 static int huge_fd;
96 static char *huge_fd_off0;
97 static unsigned long long *count_verify;
98 static int uffd, uffd_flags, finished, *pipefd;
99 static char *area_src, *area_src_alias, *area_dst, *area_dst_alias;
100 static char *zeropage;
101 pthread_attr_t attr;
102 
103 /* pthread_mutex_t starts at page offset 0 */
104 #define area_mutex(___area, ___nr)					\
105 	((pthread_mutex_t *) ((___area) + (___nr)*page_size))
106 /*
107  * count is placed in the page after pthread_mutex_t naturally aligned
108  * to avoid non alignment faults on non-x86 archs.
109  */
110 #define area_count(___area, ___nr)					\
111 	((volatile unsigned long long *) ((unsigned long)		\
112 				 ((___area) + (___nr)*page_size +	\
113 				  sizeof(pthread_mutex_t) +		\
114 				  sizeof(unsigned long long) - 1) &	\
115 				 ~(unsigned long)(sizeof(unsigned long long) \
116 						  -  1)))
117 
anon_release_pages(char * rel_area)118 static int anon_release_pages(char *rel_area)
119 {
120 	int ret = 0;
121 
122 	if (madvise(rel_area, nr_pages * page_size, MADV_DONTNEED)) {
123 		perror("madvise");
124 		ret = 1;
125 	}
126 
127 	return ret;
128 }
129 
anon_allocate_area(void ** alloc_area)130 static void anon_allocate_area(void **alloc_area)
131 {
132 	if (posix_memalign(alloc_area, page_size, nr_pages * page_size)) {
133 		fprintf(stderr, "out of memory\n");
134 		*alloc_area = NULL;
135 	}
136 }
137 
noop_alias_mapping(__u64 * start,size_t len,unsigned long offset)138 static void noop_alias_mapping(__u64 *start, size_t len, unsigned long offset)
139 {
140 }
141 
142 /* HugeTLB memory */
hugetlb_release_pages(char * rel_area)143 static int hugetlb_release_pages(char *rel_area)
144 {
145 	int ret = 0;
146 
147 	if (fallocate(huge_fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
148 				rel_area == huge_fd_off0 ? 0 :
149 				nr_pages * page_size,
150 				nr_pages * page_size)) {
151 		perror("fallocate");
152 		ret = 1;
153 	}
154 
155 	return ret;
156 }
157 
158 
hugetlb_allocate_area(void ** alloc_area)159 static void hugetlb_allocate_area(void **alloc_area)
160 {
161 	void *area_alias = NULL;
162 	char **alloc_area_alias;
163 	*alloc_area = mmap(NULL, nr_pages * page_size, PROT_READ | PROT_WRITE,
164 			   (map_shared ? MAP_SHARED : MAP_PRIVATE) |
165 			   MAP_HUGETLB,
166 			   huge_fd, *alloc_area == area_src ? 0 :
167 			   nr_pages * page_size);
168 	if (*alloc_area == MAP_FAILED) {
169 		fprintf(stderr, "mmap of hugetlbfs file failed\n");
170 		*alloc_area = NULL;
171 	}
172 
173 	if (map_shared) {
174 		area_alias = mmap(NULL, nr_pages * page_size, PROT_READ | PROT_WRITE,
175 				  MAP_SHARED | MAP_HUGETLB,
176 				  huge_fd, *alloc_area == area_src ? 0 :
177 				  nr_pages * page_size);
178 		if (area_alias == MAP_FAILED) {
179 			if (munmap(*alloc_area, nr_pages * page_size) < 0)
180 				perror("hugetlb munmap"), exit(1);
181 			*alloc_area = NULL;
182 			return;
183 		}
184 	}
185 	if (*alloc_area == area_src) {
186 		huge_fd_off0 = *alloc_area;
187 		alloc_area_alias = &area_src_alias;
188 	} else {
189 		alloc_area_alias = &area_dst_alias;
190 	}
191 	if (area_alias)
192 		*alloc_area_alias = area_alias;
193 }
194 
hugetlb_alias_mapping(__u64 * start,size_t len,unsigned long offset)195 static void hugetlb_alias_mapping(__u64 *start, size_t len, unsigned long offset)
196 {
197 	if (!map_shared)
198 		return;
199 	/*
200 	 * We can't zap just the pagetable with hugetlbfs because
201 	 * MADV_DONTEED won't work. So exercise -EEXIST on a alias
202 	 * mapping where the pagetables are not established initially,
203 	 * this way we'll exercise the -EEXEC at the fs level.
204 	 */
205 	*start = (unsigned long) area_dst_alias + offset;
206 }
207 
208 /* Shared memory */
shmem_release_pages(char * rel_area)209 static int shmem_release_pages(char *rel_area)
210 {
211 	int ret = 0;
212 
213 	if (madvise(rel_area, nr_pages * page_size, MADV_REMOVE)) {
214 		perror("madvise");
215 		ret = 1;
216 	}
217 
218 	return ret;
219 }
220 
shmem_allocate_area(void ** alloc_area)221 static void shmem_allocate_area(void **alloc_area)
222 {
223 	*alloc_area = mmap(NULL, nr_pages * page_size, PROT_READ | PROT_WRITE,
224 			   MAP_ANONYMOUS | MAP_SHARED, -1, 0);
225 	if (*alloc_area == MAP_FAILED) {
226 		fprintf(stderr, "shared memory mmap failed\n");
227 		*alloc_area = NULL;
228 	}
229 }
230 
231 struct uffd_test_ops {
232 	unsigned long expected_ioctls;
233 	void (*allocate_area)(void **alloc_area);
234 	int (*release_pages)(char *rel_area);
235 	void (*alias_mapping)(__u64 *start, size_t len, unsigned long offset);
236 };
237 
238 #define ANON_EXPECTED_IOCTLS		((1 << _UFFDIO_WAKE) | \
239 					 (1 << _UFFDIO_COPY) | \
240 					 (1 << _UFFDIO_ZEROPAGE))
241 
242 static struct uffd_test_ops anon_uffd_test_ops = {
243 	.expected_ioctls = ANON_EXPECTED_IOCTLS,
244 	.allocate_area	= anon_allocate_area,
245 	.release_pages	= anon_release_pages,
246 	.alias_mapping = noop_alias_mapping,
247 };
248 
249 static struct uffd_test_ops shmem_uffd_test_ops = {
250 	.expected_ioctls = ANON_EXPECTED_IOCTLS,
251 	.allocate_area	= shmem_allocate_area,
252 	.release_pages	= shmem_release_pages,
253 	.alias_mapping = noop_alias_mapping,
254 };
255 
256 static struct uffd_test_ops hugetlb_uffd_test_ops = {
257 	.expected_ioctls = UFFD_API_RANGE_IOCTLS_BASIC,
258 	.allocate_area	= hugetlb_allocate_area,
259 	.release_pages	= hugetlb_release_pages,
260 	.alias_mapping = hugetlb_alias_mapping,
261 };
262 
263 static struct uffd_test_ops *uffd_test_ops;
264 
my_bcmp(char * str1,char * str2,size_t n)265 static int my_bcmp(char *str1, char *str2, size_t n)
266 {
267 	unsigned long i;
268 	for (i = 0; i < n; i++)
269 		if (str1[i] != str2[i])
270 			return 1;
271 	return 0;
272 }
273 
locking_thread(void * arg)274 static void *locking_thread(void *arg)
275 {
276 	unsigned long cpu = (unsigned long) arg;
277 	struct random_data rand;
278 	unsigned long page_nr = *(&(page_nr)); /* uninitialized warning */
279 	int32_t rand_nr;
280 	unsigned long long count;
281 	char randstate[64];
282 	unsigned int seed;
283 	time_t start;
284 
285 	if (bounces & BOUNCE_RANDOM) {
286 		seed = (unsigned int) time(NULL) - bounces;
287 		if (!(bounces & BOUNCE_RACINGFAULTS))
288 			seed += cpu;
289 		bzero(&rand, sizeof(rand));
290 		bzero(&randstate, sizeof(randstate));
291 		if (initstate_r(seed, randstate, sizeof(randstate), &rand))
292 			fprintf(stderr, "srandom_r error\n"), exit(1);
293 	} else {
294 		page_nr = -bounces;
295 		if (!(bounces & BOUNCE_RACINGFAULTS))
296 			page_nr += cpu * nr_pages_per_cpu;
297 	}
298 
299 	while (!finished) {
300 		if (bounces & BOUNCE_RANDOM) {
301 			if (random_r(&rand, &rand_nr))
302 				fprintf(stderr, "random_r 1 error\n"), exit(1);
303 			page_nr = rand_nr;
304 			if (sizeof(page_nr) > sizeof(rand_nr)) {
305 				if (random_r(&rand, &rand_nr))
306 					fprintf(stderr, "random_r 2 error\n"), exit(1);
307 				page_nr |= (((unsigned long) rand_nr) << 16) <<
308 					   16;
309 			}
310 		} else
311 			page_nr += 1;
312 		page_nr %= nr_pages;
313 
314 		start = time(NULL);
315 		if (bounces & BOUNCE_VERIFY) {
316 			count = *area_count(area_dst, page_nr);
317 			if (!count)
318 				fprintf(stderr,
319 					"page_nr %lu wrong count %Lu %Lu\n",
320 					page_nr, count,
321 					count_verify[page_nr]), exit(1);
322 
323 
324 			/*
325 			 * We can't use bcmp (or memcmp) because that
326 			 * returns 0 erroneously if the memory is
327 			 * changing under it (even if the end of the
328 			 * page is never changing and always
329 			 * different).
330 			 */
331 #if 1
332 			if (!my_bcmp(area_dst + page_nr * page_size, zeropage,
333 				     page_size))
334 				fprintf(stderr,
335 					"my_bcmp page_nr %lu wrong count %Lu %Lu\n",
336 					page_nr, count,
337 					count_verify[page_nr]), exit(1);
338 #else
339 			unsigned long loops;
340 
341 			loops = 0;
342 			/* uncomment the below line to test with mutex */
343 			/* pthread_mutex_lock(area_mutex(area_dst, page_nr)); */
344 			while (!bcmp(area_dst + page_nr * page_size, zeropage,
345 				     page_size)) {
346 				loops += 1;
347 				if (loops > 10)
348 					break;
349 			}
350 			/* uncomment below line to test with mutex */
351 			/* pthread_mutex_unlock(area_mutex(area_dst, page_nr)); */
352 			if (loops) {
353 				fprintf(stderr,
354 					"page_nr %lu all zero thread %lu %p %lu\n",
355 					page_nr, cpu, area_dst + page_nr * page_size,
356 					loops);
357 				if (loops > 10)
358 					exit(1);
359 			}
360 #endif
361 		}
362 
363 		pthread_mutex_lock(area_mutex(area_dst, page_nr));
364 		count = *area_count(area_dst, page_nr);
365 		if (count != count_verify[page_nr]) {
366 			fprintf(stderr,
367 				"page_nr %lu memory corruption %Lu %Lu\n",
368 				page_nr, count,
369 				count_verify[page_nr]), exit(1);
370 		}
371 		count++;
372 		*area_count(area_dst, page_nr) = count_verify[page_nr] = count;
373 		pthread_mutex_unlock(area_mutex(area_dst, page_nr));
374 
375 		if (time(NULL) - start > 1)
376 			fprintf(stderr,
377 				"userfault too slow %ld "
378 				"possible false positive with overcommit\n",
379 				time(NULL) - start);
380 	}
381 
382 	return NULL;
383 }
384 
retry_copy_page(int ufd,struct uffdio_copy * uffdio_copy,unsigned long offset)385 static void retry_copy_page(int ufd, struct uffdio_copy *uffdio_copy,
386 			    unsigned long offset)
387 {
388 	uffd_test_ops->alias_mapping(&uffdio_copy->dst,
389 				     uffdio_copy->len,
390 				     offset);
391 	if (ioctl(ufd, UFFDIO_COPY, uffdio_copy)) {
392 		/* real retval in ufdio_copy.copy */
393 		if (uffdio_copy->copy != -EEXIST)
394 			fprintf(stderr, "UFFDIO_COPY retry error %Ld\n",
395 				uffdio_copy->copy), exit(1);
396 	} else {
397 		fprintf(stderr,	"UFFDIO_COPY retry unexpected %Ld\n",
398 			uffdio_copy->copy), exit(1);
399 	}
400 }
401 
__copy_page(int ufd,unsigned long offset,bool retry)402 static int __copy_page(int ufd, unsigned long offset, bool retry)
403 {
404 	struct uffdio_copy uffdio_copy;
405 
406 	if (offset >= nr_pages * page_size)
407 		fprintf(stderr, "unexpected offset %lu\n",
408 			offset), exit(1);
409 	uffdio_copy.dst = (unsigned long) area_dst + offset;
410 	uffdio_copy.src = (unsigned long) area_src + offset;
411 	uffdio_copy.len = page_size;
412 	uffdio_copy.mode = 0;
413 	uffdio_copy.copy = 0;
414 	if (ioctl(ufd, UFFDIO_COPY, &uffdio_copy)) {
415 		/* real retval in ufdio_copy.copy */
416 		if (uffdio_copy.copy != -EEXIST)
417 			fprintf(stderr, "UFFDIO_COPY error %Ld\n",
418 				uffdio_copy.copy), exit(1);
419 	} else if (uffdio_copy.copy != page_size) {
420 		fprintf(stderr, "UFFDIO_COPY unexpected copy %Ld\n",
421 			uffdio_copy.copy), exit(1);
422 	} else {
423 		if (test_uffdio_copy_eexist && retry) {
424 			test_uffdio_copy_eexist = false;
425 			retry_copy_page(ufd, &uffdio_copy, offset);
426 		}
427 		return 1;
428 	}
429 	return 0;
430 }
431 
copy_page_retry(int ufd,unsigned long offset)432 static int copy_page_retry(int ufd, unsigned long offset)
433 {
434 	return __copy_page(ufd, offset, true);
435 }
436 
copy_page(int ufd,unsigned long offset)437 static int copy_page(int ufd, unsigned long offset)
438 {
439 	return __copy_page(ufd, offset, false);
440 }
441 
uffd_poll_thread(void * arg)442 static void *uffd_poll_thread(void *arg)
443 {
444 	unsigned long cpu = (unsigned long) arg;
445 	struct pollfd pollfd[2];
446 	struct uffd_msg msg;
447 	struct uffdio_register uffd_reg;
448 	int ret;
449 	unsigned long offset;
450 	char tmp_chr;
451 	unsigned long userfaults = 0;
452 
453 	pollfd[0].fd = uffd;
454 	pollfd[0].events = POLLIN;
455 	pollfd[1].fd = pipefd[cpu*2];
456 	pollfd[1].events = POLLIN;
457 
458 	for (;;) {
459 		ret = poll(pollfd, 2, -1);
460 		if (!ret)
461 			fprintf(stderr, "poll error %d\n", ret), exit(1);
462 		if (ret < 0)
463 			perror("poll"), exit(1);
464 		if (pollfd[1].revents & POLLIN) {
465 			if (read(pollfd[1].fd, &tmp_chr, 1) != 1)
466 				fprintf(stderr, "read pipefd error\n"),
467 					exit(1);
468 			break;
469 		}
470 		if (!(pollfd[0].revents & POLLIN))
471 			fprintf(stderr, "pollfd[0].revents %d\n",
472 				pollfd[0].revents), exit(1);
473 		ret = read(uffd, &msg, sizeof(msg));
474 		if (ret < 0) {
475 			if (errno == EAGAIN)
476 				continue;
477 			perror("nonblocking read error"), exit(1);
478 		}
479 		switch (msg.event) {
480 		default:
481 			fprintf(stderr, "unexpected msg event %u\n",
482 				msg.event), exit(1);
483 			break;
484 		case UFFD_EVENT_PAGEFAULT:
485 			if (msg.arg.pagefault.flags & UFFD_PAGEFAULT_FLAG_WRITE)
486 				fprintf(stderr, "unexpected write fault\n"), exit(1);
487 			offset = (char *)(unsigned long)msg.arg.pagefault.address -
488 				area_dst;
489 			offset &= ~(page_size-1);
490 			if (copy_page(uffd, offset))
491 				userfaults++;
492 			break;
493 		case UFFD_EVENT_FORK:
494 			close(uffd);
495 			uffd = msg.arg.fork.ufd;
496 			pollfd[0].fd = uffd;
497 			break;
498 		case UFFD_EVENT_REMOVE:
499 			uffd_reg.range.start = msg.arg.remove.start;
500 			uffd_reg.range.len = msg.arg.remove.end -
501 				msg.arg.remove.start;
502 			if (ioctl(uffd, UFFDIO_UNREGISTER, &uffd_reg.range))
503 				fprintf(stderr, "remove failure\n"), exit(1);
504 			break;
505 		case UFFD_EVENT_REMAP:
506 			area_dst = (char *)(unsigned long)msg.arg.remap.to;
507 			break;
508 		}
509 	}
510 	return (void *)userfaults;
511 }
512 
513 pthread_mutex_t uffd_read_mutex = PTHREAD_MUTEX_INITIALIZER;
514 
uffd_read_thread(void * arg)515 static void *uffd_read_thread(void *arg)
516 {
517 	unsigned long *this_cpu_userfaults;
518 	struct uffd_msg msg;
519 	unsigned long offset;
520 	int ret;
521 
522 	this_cpu_userfaults = (unsigned long *) arg;
523 	*this_cpu_userfaults = 0;
524 
525 	pthread_mutex_unlock(&uffd_read_mutex);
526 	/* from here cancellation is ok */
527 
528 	for (;;) {
529 		ret = read(uffd, &msg, sizeof(msg));
530 		if (ret != sizeof(msg)) {
531 			if (ret < 0)
532 				perror("blocking read error"), exit(1);
533 			else
534 				fprintf(stderr, "short read\n"), exit(1);
535 		}
536 		if (msg.event != UFFD_EVENT_PAGEFAULT)
537 			fprintf(stderr, "unexpected msg event %u\n",
538 				msg.event), exit(1);
539 		if (bounces & BOUNCE_VERIFY &&
540 		    msg.arg.pagefault.flags & UFFD_PAGEFAULT_FLAG_WRITE)
541 			fprintf(stderr, "unexpected write fault\n"), exit(1);
542 		offset = (char *)(unsigned long)msg.arg.pagefault.address -
543 			 area_dst;
544 		offset &= ~(page_size-1);
545 		if (copy_page(uffd, offset))
546 			(*this_cpu_userfaults)++;
547 	}
548 	return (void *)NULL;
549 }
550 
background_thread(void * arg)551 static void *background_thread(void *arg)
552 {
553 	unsigned long cpu = (unsigned long) arg;
554 	unsigned long page_nr;
555 
556 	for (page_nr = cpu * nr_pages_per_cpu;
557 	     page_nr < (cpu+1) * nr_pages_per_cpu;
558 	     page_nr++)
559 		copy_page_retry(uffd, page_nr * page_size);
560 
561 	return NULL;
562 }
563 
stress(unsigned long * userfaults)564 static int stress(unsigned long *userfaults)
565 {
566 	unsigned long cpu;
567 	pthread_t locking_threads[nr_cpus];
568 	pthread_t uffd_threads[nr_cpus];
569 	pthread_t background_threads[nr_cpus];
570 	void **_userfaults = (void **) userfaults;
571 
572 	finished = 0;
573 	for (cpu = 0; cpu < nr_cpus; cpu++) {
574 		if (pthread_create(&locking_threads[cpu], &attr,
575 				   locking_thread, (void *)cpu))
576 			return 1;
577 		if (bounces & BOUNCE_POLL) {
578 			if (pthread_create(&uffd_threads[cpu], &attr,
579 					   uffd_poll_thread, (void *)cpu))
580 				return 1;
581 		} else {
582 			if (pthread_create(&uffd_threads[cpu], &attr,
583 					   uffd_read_thread,
584 					   &_userfaults[cpu]))
585 				return 1;
586 			pthread_mutex_lock(&uffd_read_mutex);
587 		}
588 		if (pthread_create(&background_threads[cpu], &attr,
589 				   background_thread, (void *)cpu))
590 			return 1;
591 	}
592 	for (cpu = 0; cpu < nr_cpus; cpu++)
593 		if (pthread_join(background_threads[cpu], NULL))
594 			return 1;
595 
596 	/*
597 	 * Be strict and immediately zap area_src, the whole area has
598 	 * been transferred already by the background treads. The
599 	 * area_src could then be faulted in in a racy way by still
600 	 * running uffdio_threads reading zeropages after we zapped
601 	 * area_src (but they're guaranteed to get -EEXIST from
602 	 * UFFDIO_COPY without writing zero pages into area_dst
603 	 * because the background threads already completed).
604 	 */
605 	if (uffd_test_ops->release_pages(area_src))
606 		return 1;
607 
608 	for (cpu = 0; cpu < nr_cpus; cpu++) {
609 		char c;
610 		if (bounces & BOUNCE_POLL) {
611 			if (write(pipefd[cpu*2+1], &c, 1) != 1) {
612 				fprintf(stderr, "pipefd write error\n");
613 				return 1;
614 			}
615 			if (pthread_join(uffd_threads[cpu], &_userfaults[cpu]))
616 				return 1;
617 		} else {
618 			if (pthread_cancel(uffd_threads[cpu]))
619 				return 1;
620 			if (pthread_join(uffd_threads[cpu], NULL))
621 				return 1;
622 		}
623 	}
624 
625 	finished = 1;
626 	for (cpu = 0; cpu < nr_cpus; cpu++)
627 		if (pthread_join(locking_threads[cpu], NULL))
628 			return 1;
629 
630 	return 0;
631 }
632 
userfaultfd_open(int features)633 static int userfaultfd_open(int features)
634 {
635 	struct uffdio_api uffdio_api;
636 
637 	uffd = syscall(__NR_userfaultfd, O_CLOEXEC | O_NONBLOCK);
638 	if (uffd < 0) {
639 		fprintf(stderr,
640 			"userfaultfd syscall not available in this kernel\n");
641 		return 1;
642 	}
643 	uffd_flags = fcntl(uffd, F_GETFD, NULL);
644 
645 	uffdio_api.api = UFFD_API;
646 	uffdio_api.features = features;
647 	if (ioctl(uffd, UFFDIO_API, &uffdio_api)) {
648 		fprintf(stderr, "UFFDIO_API\n");
649 		return 1;
650 	}
651 	if (uffdio_api.api != UFFD_API) {
652 		fprintf(stderr, "UFFDIO_API error %Lu\n", uffdio_api.api);
653 		return 1;
654 	}
655 
656 	return 0;
657 }
658 
659 sigjmp_buf jbuf, *sigbuf;
660 
sighndl(int sig,siginfo_t * siginfo,void * ptr)661 static void sighndl(int sig, siginfo_t *siginfo, void *ptr)
662 {
663 	if (sig == SIGBUS) {
664 		if (sigbuf)
665 			siglongjmp(*sigbuf, 1);
666 		abort();
667 	}
668 }
669 
670 /*
671  * For non-cooperative userfaultfd test we fork() a process that will
672  * generate pagefaults, will mremap the area monitored by the
673  * userfaultfd and at last this process will release the monitored
674  * area.
675  * For the anonymous and shared memory the area is divided into two
676  * parts, the first part is accessed before mremap, and the second
677  * part is accessed after mremap. Since hugetlbfs does not support
678  * mremap, the entire monitored area is accessed in a single pass for
679  * HUGETLB_TEST.
680  * The release of the pages currently generates event for shmem and
681  * anonymous memory (UFFD_EVENT_REMOVE), hence it is not checked
682  * for hugetlb.
683  * For signal test(UFFD_FEATURE_SIGBUS), signal_test = 1, we register
684  * monitored area, generate pagefaults and test that signal is delivered.
685  * Use UFFDIO_COPY to allocate missing page and retry. For signal_test = 2
686  * test robustness use case - we release monitored area, fork a process
687  * that will generate pagefaults and verify signal is generated.
688  * This also tests UFFD_FEATURE_EVENT_FORK event along with the signal
689  * feature. Using monitor thread, verify no userfault events are generated.
690  */
faulting_process(int signal_test)691 static int faulting_process(int signal_test)
692 {
693 	unsigned long nr;
694 	unsigned long long count;
695 	unsigned long split_nr_pages;
696 	unsigned long lastnr;
697 	struct sigaction act;
698 	unsigned long signalled = 0;
699 
700 	if (test_type != TEST_HUGETLB)
701 		split_nr_pages = (nr_pages + 1) / 2;
702 	else
703 		split_nr_pages = nr_pages;
704 
705 	if (signal_test) {
706 		sigbuf = &jbuf;
707 		memset(&act, 0, sizeof(act));
708 		act.sa_sigaction = sighndl;
709 		act.sa_flags = SA_SIGINFO;
710 		if (sigaction(SIGBUS, &act, 0)) {
711 			perror("sigaction");
712 			return 1;
713 		}
714 		lastnr = (unsigned long)-1;
715 	}
716 
717 	for (nr = 0; nr < split_nr_pages; nr++) {
718 		if (signal_test) {
719 			if (sigsetjmp(*sigbuf, 1) != 0) {
720 				if (nr == lastnr) {
721 					fprintf(stderr, "Signal repeated\n");
722 					return 1;
723 				}
724 
725 				lastnr = nr;
726 				if (signal_test == 1) {
727 					if (copy_page(uffd, nr * page_size))
728 						signalled++;
729 				} else {
730 					signalled++;
731 					continue;
732 				}
733 			}
734 		}
735 
736 		count = *area_count(area_dst, nr);
737 		if (count != count_verify[nr]) {
738 			fprintf(stderr,
739 				"nr %lu memory corruption %Lu %Lu\n",
740 				nr, count,
741 				count_verify[nr]), exit(1);
742 		}
743 	}
744 
745 	if (signal_test)
746 		return signalled != split_nr_pages;
747 
748 	if (test_type == TEST_HUGETLB)
749 		return 0;
750 
751 	area_dst = mremap(area_dst, nr_pages * page_size,  nr_pages * page_size,
752 			  MREMAP_MAYMOVE | MREMAP_FIXED, area_src);
753 	if (area_dst == MAP_FAILED)
754 		perror("mremap"), exit(1);
755 
756 	for (; nr < nr_pages; nr++) {
757 		count = *area_count(area_dst, nr);
758 		if (count != count_verify[nr]) {
759 			fprintf(stderr,
760 				"nr %lu memory corruption %Lu %Lu\n",
761 				nr, count,
762 				count_verify[nr]), exit(1);
763 		}
764 	}
765 
766 	if (uffd_test_ops->release_pages(area_dst))
767 		return 1;
768 
769 	for (nr = 0; nr < nr_pages; nr++) {
770 		if (my_bcmp(area_dst + nr * page_size, zeropage, page_size))
771 			fprintf(stderr, "nr %lu is not zero\n", nr), exit(1);
772 	}
773 
774 	return 0;
775 }
776 
retry_uffdio_zeropage(int ufd,struct uffdio_zeropage * uffdio_zeropage,unsigned long offset)777 static void retry_uffdio_zeropage(int ufd,
778 				  struct uffdio_zeropage *uffdio_zeropage,
779 				  unsigned long offset)
780 {
781 	uffd_test_ops->alias_mapping(&uffdio_zeropage->range.start,
782 				     uffdio_zeropage->range.len,
783 				     offset);
784 	if (ioctl(ufd, UFFDIO_ZEROPAGE, uffdio_zeropage)) {
785 		if (uffdio_zeropage->zeropage != -EEXIST)
786 			fprintf(stderr, "UFFDIO_ZEROPAGE retry error %Ld\n",
787 				uffdio_zeropage->zeropage), exit(1);
788 	} else {
789 		fprintf(stderr, "UFFDIO_ZEROPAGE retry unexpected %Ld\n",
790 			uffdio_zeropage->zeropage), exit(1);
791 	}
792 }
793 
__uffdio_zeropage(int ufd,unsigned long offset,bool retry)794 static int __uffdio_zeropage(int ufd, unsigned long offset, bool retry)
795 {
796 	struct uffdio_zeropage uffdio_zeropage;
797 	int ret;
798 	unsigned long has_zeropage;
799 
800 	has_zeropage = uffd_test_ops->expected_ioctls & (1 << _UFFDIO_ZEROPAGE);
801 
802 	if (offset >= nr_pages * page_size)
803 		fprintf(stderr, "unexpected offset %lu\n",
804 			offset), exit(1);
805 	uffdio_zeropage.range.start = (unsigned long) area_dst + offset;
806 	uffdio_zeropage.range.len = page_size;
807 	uffdio_zeropage.mode = 0;
808 	ret = ioctl(ufd, UFFDIO_ZEROPAGE, &uffdio_zeropage);
809 	if (ret) {
810 		/* real retval in ufdio_zeropage.zeropage */
811 		if (has_zeropage) {
812 			if (uffdio_zeropage.zeropage == -EEXIST)
813 				fprintf(stderr, "UFFDIO_ZEROPAGE -EEXIST\n"),
814 					exit(1);
815 			else
816 				fprintf(stderr, "UFFDIO_ZEROPAGE error %Ld\n",
817 					uffdio_zeropage.zeropage), exit(1);
818 		} else {
819 			if (uffdio_zeropage.zeropage != -EINVAL)
820 				fprintf(stderr,
821 					"UFFDIO_ZEROPAGE not -EINVAL %Ld\n",
822 					uffdio_zeropage.zeropage), exit(1);
823 		}
824 	} else if (has_zeropage) {
825 		if (uffdio_zeropage.zeropage != page_size) {
826 			fprintf(stderr, "UFFDIO_ZEROPAGE unexpected %Ld\n",
827 				uffdio_zeropage.zeropage), exit(1);
828 		} else {
829 			if (test_uffdio_zeropage_eexist && retry) {
830 				test_uffdio_zeropage_eexist = false;
831 				retry_uffdio_zeropage(ufd, &uffdio_zeropage,
832 						      offset);
833 			}
834 			return 1;
835 		}
836 	} else {
837 		fprintf(stderr,
838 			"UFFDIO_ZEROPAGE succeeded %Ld\n",
839 			uffdio_zeropage.zeropage), exit(1);
840 	}
841 
842 	return 0;
843 }
844 
uffdio_zeropage(int ufd,unsigned long offset)845 static int uffdio_zeropage(int ufd, unsigned long offset)
846 {
847 	return __uffdio_zeropage(ufd, offset, false);
848 }
849 
850 /* exercise UFFDIO_ZEROPAGE */
userfaultfd_zeropage_test(void)851 static int userfaultfd_zeropage_test(void)
852 {
853 	struct uffdio_register uffdio_register;
854 	unsigned long expected_ioctls;
855 
856 	printf("testing UFFDIO_ZEROPAGE: ");
857 	fflush(stdout);
858 
859 	if (uffd_test_ops->release_pages(area_dst))
860 		return 1;
861 
862 	if (userfaultfd_open(0) < 0)
863 		return 1;
864 	uffdio_register.range.start = (unsigned long) area_dst;
865 	uffdio_register.range.len = nr_pages * page_size;
866 	uffdio_register.mode = UFFDIO_REGISTER_MODE_MISSING;
867 	if (ioctl(uffd, UFFDIO_REGISTER, &uffdio_register))
868 		fprintf(stderr, "register failure\n"), exit(1);
869 
870 	expected_ioctls = uffd_test_ops->expected_ioctls;
871 	if ((uffdio_register.ioctls & expected_ioctls) !=
872 	    expected_ioctls)
873 		fprintf(stderr,
874 			"unexpected missing ioctl for anon memory\n"),
875 			exit(1);
876 
877 	if (uffdio_zeropage(uffd, 0)) {
878 		if (my_bcmp(area_dst, zeropage, page_size))
879 			fprintf(stderr, "zeropage is not zero\n"), exit(1);
880 	}
881 
882 	close(uffd);
883 	printf("done.\n");
884 	return 0;
885 }
886 
userfaultfd_events_test(void)887 static int userfaultfd_events_test(void)
888 {
889 	struct uffdio_register uffdio_register;
890 	unsigned long expected_ioctls;
891 	unsigned long userfaults;
892 	pthread_t uffd_mon;
893 	int err, features;
894 	pid_t pid;
895 	char c;
896 
897 	printf("testing events (fork, remap, remove): ");
898 	fflush(stdout);
899 
900 	if (uffd_test_ops->release_pages(area_dst))
901 		return 1;
902 
903 	features = UFFD_FEATURE_EVENT_FORK | UFFD_FEATURE_EVENT_REMAP |
904 		UFFD_FEATURE_EVENT_REMOVE;
905 	if (userfaultfd_open(features) < 0)
906 		return 1;
907 	fcntl(uffd, F_SETFL, uffd_flags | O_NONBLOCK);
908 
909 	uffdio_register.range.start = (unsigned long) area_dst;
910 	uffdio_register.range.len = nr_pages * page_size;
911 	uffdio_register.mode = UFFDIO_REGISTER_MODE_MISSING;
912 	if (ioctl(uffd, UFFDIO_REGISTER, &uffdio_register))
913 		fprintf(stderr, "register failure\n"), exit(1);
914 
915 	expected_ioctls = uffd_test_ops->expected_ioctls;
916 	if ((uffdio_register.ioctls & expected_ioctls) !=
917 	    expected_ioctls)
918 		fprintf(stderr,
919 			"unexpected missing ioctl for anon memory\n"),
920 			exit(1);
921 
922 	if (pthread_create(&uffd_mon, &attr, uffd_poll_thread, NULL))
923 		perror("uffd_poll_thread create"), exit(1);
924 
925 	pid = fork();
926 	if (pid < 0)
927 		perror("fork"), exit(1);
928 
929 	if (!pid)
930 		return faulting_process(0);
931 
932 	waitpid(pid, &err, 0);
933 	if (err)
934 		fprintf(stderr, "faulting process failed\n"), exit(1);
935 
936 	if (write(pipefd[1], &c, sizeof(c)) != sizeof(c))
937 		perror("pipe write"), exit(1);
938 	if (pthread_join(uffd_mon, (void **)&userfaults))
939 		return 1;
940 
941 	close(uffd);
942 	printf("userfaults: %ld\n", userfaults);
943 
944 	return userfaults != nr_pages;
945 }
946 
userfaultfd_sig_test(void)947 static int userfaultfd_sig_test(void)
948 {
949 	struct uffdio_register uffdio_register;
950 	unsigned long expected_ioctls;
951 	unsigned long userfaults;
952 	pthread_t uffd_mon;
953 	int err, features;
954 	pid_t pid;
955 	char c;
956 
957 	printf("testing signal delivery: ");
958 	fflush(stdout);
959 
960 	if (uffd_test_ops->release_pages(area_dst))
961 		return 1;
962 
963 	features = UFFD_FEATURE_EVENT_FORK|UFFD_FEATURE_SIGBUS;
964 	if (userfaultfd_open(features) < 0)
965 		return 1;
966 	fcntl(uffd, F_SETFL, uffd_flags | O_NONBLOCK);
967 
968 	uffdio_register.range.start = (unsigned long) area_dst;
969 	uffdio_register.range.len = nr_pages * page_size;
970 	uffdio_register.mode = UFFDIO_REGISTER_MODE_MISSING;
971 	if (ioctl(uffd, UFFDIO_REGISTER, &uffdio_register))
972 		fprintf(stderr, "register failure\n"), exit(1);
973 
974 	expected_ioctls = uffd_test_ops->expected_ioctls;
975 	if ((uffdio_register.ioctls & expected_ioctls) !=
976 	    expected_ioctls)
977 		fprintf(stderr,
978 			"unexpected missing ioctl for anon memory\n"),
979 			exit(1);
980 
981 	if (faulting_process(1))
982 		fprintf(stderr, "faulting process failed\n"), exit(1);
983 
984 	if (uffd_test_ops->release_pages(area_dst))
985 		return 1;
986 
987 	if (pthread_create(&uffd_mon, &attr, uffd_poll_thread, NULL))
988 		perror("uffd_poll_thread create"), exit(1);
989 
990 	pid = fork();
991 	if (pid < 0)
992 		perror("fork"), exit(1);
993 
994 	if (!pid)
995 		exit(faulting_process(2));
996 
997 	waitpid(pid, &err, 0);
998 	if (err)
999 		fprintf(stderr, "faulting process failed\n"), exit(1);
1000 
1001 	if (write(pipefd[1], &c, sizeof(c)) != sizeof(c))
1002 		perror("pipe write"), exit(1);
1003 	if (pthread_join(uffd_mon, (void **)&userfaults))
1004 		return 1;
1005 
1006 	printf("done.\n");
1007 	if (userfaults)
1008 		fprintf(stderr, "Signal test failed, userfaults: %ld\n",
1009 			userfaults);
1010 	close(uffd);
1011 	return userfaults != 0;
1012 }
userfaultfd_stress(void)1013 static int userfaultfd_stress(void)
1014 {
1015 	void *area;
1016 	char *tmp_area;
1017 	unsigned long nr;
1018 	struct uffdio_register uffdio_register;
1019 	unsigned long cpu;
1020 	int err;
1021 	unsigned long userfaults[nr_cpus];
1022 
1023 	uffd_test_ops->allocate_area((void **)&area_src);
1024 	if (!area_src)
1025 		return 1;
1026 	uffd_test_ops->allocate_area((void **)&area_dst);
1027 	if (!area_dst)
1028 		return 1;
1029 
1030 	if (userfaultfd_open(0) < 0)
1031 		return 1;
1032 
1033 	count_verify = malloc(nr_pages * sizeof(unsigned long long));
1034 	if (!count_verify) {
1035 		perror("count_verify");
1036 		return 1;
1037 	}
1038 
1039 	for (nr = 0; nr < nr_pages; nr++) {
1040 		*area_mutex(area_src, nr) = (pthread_mutex_t)
1041 			PTHREAD_MUTEX_INITIALIZER;
1042 		count_verify[nr] = *area_count(area_src, nr) = 1;
1043 		/*
1044 		 * In the transition between 255 to 256, powerpc will
1045 		 * read out of order in my_bcmp and see both bytes as
1046 		 * zero, so leave a placeholder below always non-zero
1047 		 * after the count, to avoid my_bcmp to trigger false
1048 		 * positives.
1049 		 */
1050 		*(area_count(area_src, nr) + 1) = 1;
1051 	}
1052 
1053 	pipefd = malloc(sizeof(int) * nr_cpus * 2);
1054 	if (!pipefd) {
1055 		perror("pipefd");
1056 		return 1;
1057 	}
1058 	for (cpu = 0; cpu < nr_cpus; cpu++) {
1059 		if (pipe2(&pipefd[cpu*2], O_CLOEXEC | O_NONBLOCK)) {
1060 			perror("pipe");
1061 			return 1;
1062 		}
1063 	}
1064 
1065 	if (posix_memalign(&area, page_size, page_size)) {
1066 		fprintf(stderr, "out of memory\n");
1067 		return 1;
1068 	}
1069 	zeropage = area;
1070 	bzero(zeropage, page_size);
1071 
1072 	pthread_mutex_lock(&uffd_read_mutex);
1073 
1074 	pthread_attr_init(&attr);
1075 	pthread_attr_setstacksize(&attr, 16*1024*1024);
1076 
1077 	err = 0;
1078 	while (bounces--) {
1079 		unsigned long expected_ioctls;
1080 
1081 		printf("bounces: %d, mode:", bounces);
1082 		if (bounces & BOUNCE_RANDOM)
1083 			printf(" rnd");
1084 		if (bounces & BOUNCE_RACINGFAULTS)
1085 			printf(" racing");
1086 		if (bounces & BOUNCE_VERIFY)
1087 			printf(" ver");
1088 		if (bounces & BOUNCE_POLL)
1089 			printf(" poll");
1090 		printf(", ");
1091 		fflush(stdout);
1092 
1093 		if (bounces & BOUNCE_POLL)
1094 			fcntl(uffd, F_SETFL, uffd_flags | O_NONBLOCK);
1095 		else
1096 			fcntl(uffd, F_SETFL, uffd_flags & ~O_NONBLOCK);
1097 
1098 		/* register */
1099 		uffdio_register.range.start = (unsigned long) area_dst;
1100 		uffdio_register.range.len = nr_pages * page_size;
1101 		uffdio_register.mode = UFFDIO_REGISTER_MODE_MISSING;
1102 		if (ioctl(uffd, UFFDIO_REGISTER, &uffdio_register)) {
1103 			fprintf(stderr, "register failure\n");
1104 			return 1;
1105 		}
1106 		expected_ioctls = uffd_test_ops->expected_ioctls;
1107 		if ((uffdio_register.ioctls & expected_ioctls) !=
1108 		    expected_ioctls) {
1109 			fprintf(stderr,
1110 				"unexpected missing ioctl for anon memory\n");
1111 			return 1;
1112 		}
1113 
1114 		if (area_dst_alias) {
1115 			uffdio_register.range.start = (unsigned long)
1116 				area_dst_alias;
1117 			if (ioctl(uffd, UFFDIO_REGISTER, &uffdio_register)) {
1118 				fprintf(stderr, "register failure alias\n");
1119 				return 1;
1120 			}
1121 		}
1122 
1123 		/*
1124 		 * The madvise done previously isn't enough: some
1125 		 * uffd_thread could have read userfaults (one of
1126 		 * those already resolved by the background thread)
1127 		 * and it may be in the process of calling
1128 		 * UFFDIO_COPY. UFFDIO_COPY will read the zapped
1129 		 * area_src and it would map a zero page in it (of
1130 		 * course such a UFFDIO_COPY is perfectly safe as it'd
1131 		 * return -EEXIST). The problem comes at the next
1132 		 * bounce though: that racing UFFDIO_COPY would
1133 		 * generate zeropages in the area_src, so invalidating
1134 		 * the previous MADV_DONTNEED. Without this additional
1135 		 * MADV_DONTNEED those zeropages leftovers in the
1136 		 * area_src would lead to -EEXIST failure during the
1137 		 * next bounce, effectively leaving a zeropage in the
1138 		 * area_dst.
1139 		 *
1140 		 * Try to comment this out madvise to see the memory
1141 		 * corruption being caught pretty quick.
1142 		 *
1143 		 * khugepaged is also inhibited to collapse THP after
1144 		 * MADV_DONTNEED only after the UFFDIO_REGISTER, so it's
1145 		 * required to MADV_DONTNEED here.
1146 		 */
1147 		if (uffd_test_ops->release_pages(area_dst))
1148 			return 1;
1149 
1150 		/* bounce pass */
1151 		if (stress(userfaults))
1152 			return 1;
1153 
1154 		/* unregister */
1155 		if (ioctl(uffd, UFFDIO_UNREGISTER, &uffdio_register.range)) {
1156 			fprintf(stderr, "unregister failure\n");
1157 			return 1;
1158 		}
1159 		if (area_dst_alias) {
1160 			uffdio_register.range.start = (unsigned long) area_dst;
1161 			if (ioctl(uffd, UFFDIO_UNREGISTER,
1162 				  &uffdio_register.range)) {
1163 				fprintf(stderr, "unregister failure alias\n");
1164 				return 1;
1165 			}
1166 		}
1167 
1168 		/* verification */
1169 		if (bounces & BOUNCE_VERIFY) {
1170 			for (nr = 0; nr < nr_pages; nr++) {
1171 				if (*area_count(area_dst, nr) != count_verify[nr]) {
1172 					fprintf(stderr,
1173 						"error area_count %Lu %Lu %lu\n",
1174 						*area_count(area_src, nr),
1175 						count_verify[nr],
1176 						nr);
1177 					err = 1;
1178 					bounces = 0;
1179 				}
1180 			}
1181 		}
1182 
1183 		/* prepare next bounce */
1184 		tmp_area = area_src;
1185 		area_src = area_dst;
1186 		area_dst = tmp_area;
1187 
1188 		tmp_area = area_src_alias;
1189 		area_src_alias = area_dst_alias;
1190 		area_dst_alias = tmp_area;
1191 
1192 		printf("userfaults:");
1193 		for (cpu = 0; cpu < nr_cpus; cpu++)
1194 			printf(" %lu", userfaults[cpu]);
1195 		printf("\n");
1196 	}
1197 
1198 	if (err)
1199 		return err;
1200 
1201 	close(uffd);
1202 	return userfaultfd_zeropage_test() || userfaultfd_sig_test()
1203 		|| userfaultfd_events_test();
1204 }
1205 
1206 /*
1207  * Copied from mlock2-tests.c
1208  */
default_huge_page_size(void)1209 unsigned long default_huge_page_size(void)
1210 {
1211 	unsigned long hps = 0;
1212 	char *line = NULL;
1213 	size_t linelen = 0;
1214 	FILE *f = fopen("/proc/meminfo", "r");
1215 
1216 	if (!f)
1217 		return 0;
1218 	while (getline(&line, &linelen, f) > 0) {
1219 		if (sscanf(line, "Hugepagesize:       %lu kB", &hps) == 1) {
1220 			hps <<= 10;
1221 			break;
1222 		}
1223 	}
1224 
1225 	free(line);
1226 	fclose(f);
1227 	return hps;
1228 }
1229 
set_test_type(const char * type)1230 static void set_test_type(const char *type)
1231 {
1232 	if (!strcmp(type, "anon")) {
1233 		test_type = TEST_ANON;
1234 		uffd_test_ops = &anon_uffd_test_ops;
1235 	} else if (!strcmp(type, "hugetlb")) {
1236 		test_type = TEST_HUGETLB;
1237 		uffd_test_ops = &hugetlb_uffd_test_ops;
1238 	} else if (!strcmp(type, "hugetlb_shared")) {
1239 		map_shared = true;
1240 		test_type = TEST_HUGETLB;
1241 		uffd_test_ops = &hugetlb_uffd_test_ops;
1242 	} else if (!strcmp(type, "shmem")) {
1243 		map_shared = true;
1244 		test_type = TEST_SHMEM;
1245 		uffd_test_ops = &shmem_uffd_test_ops;
1246 	} else {
1247 		fprintf(stderr, "Unknown test type: %s\n", type), exit(1);
1248 	}
1249 
1250 	if (test_type == TEST_HUGETLB)
1251 		page_size = default_huge_page_size();
1252 	else
1253 		page_size = sysconf(_SC_PAGE_SIZE);
1254 
1255 	if (!page_size)
1256 		fprintf(stderr, "Unable to determine page size\n"),
1257 				exit(2);
1258 	if ((unsigned long) area_count(NULL, 0) + sizeof(unsigned long long) * 2
1259 	    > page_size)
1260 		fprintf(stderr, "Impossible to run this test\n"), exit(2);
1261 }
1262 
sigalrm(int sig)1263 static void sigalrm(int sig)
1264 {
1265 	if (sig != SIGALRM)
1266 		abort();
1267 	test_uffdio_copy_eexist = true;
1268 	test_uffdio_zeropage_eexist = true;
1269 	alarm(ALARM_INTERVAL_SECS);
1270 }
1271 
main(int argc,char ** argv)1272 int main(int argc, char **argv)
1273 {
1274 	if (argc < 4)
1275 		fprintf(stderr, "Usage: <test type> <MiB> <bounces> [hugetlbfs_file]\n"),
1276 				exit(1);
1277 
1278 	if (signal(SIGALRM, sigalrm) == SIG_ERR)
1279 		fprintf(stderr, "failed to arm SIGALRM"), exit(1);
1280 	alarm(ALARM_INTERVAL_SECS);
1281 
1282 	set_test_type(argv[1]);
1283 
1284 	nr_cpus = sysconf(_SC_NPROCESSORS_ONLN);
1285 	nr_pages_per_cpu = atol(argv[2]) * 1024*1024 / page_size /
1286 		nr_cpus;
1287 	if (!nr_pages_per_cpu) {
1288 		fprintf(stderr, "invalid MiB\n");
1289 		fprintf(stderr, "Usage: <MiB> <bounces>\n"), exit(1);
1290 	}
1291 
1292 	bounces = atoi(argv[3]);
1293 	if (bounces <= 0) {
1294 		fprintf(stderr, "invalid bounces\n");
1295 		fprintf(stderr, "Usage: <MiB> <bounces>\n"), exit(1);
1296 	}
1297 	nr_pages = nr_pages_per_cpu * nr_cpus;
1298 
1299 	if (test_type == TEST_HUGETLB) {
1300 		if (argc < 5)
1301 			fprintf(stderr, "Usage: hugetlb <MiB> <bounces> <hugetlbfs_file>\n"),
1302 				exit(1);
1303 		huge_fd = open(argv[4], O_CREAT | O_RDWR, 0755);
1304 		if (huge_fd < 0) {
1305 			fprintf(stderr, "Open of %s failed", argv[3]);
1306 			perror("open");
1307 			exit(1);
1308 		}
1309 		if (ftruncate(huge_fd, 0)) {
1310 			fprintf(stderr, "ftruncate %s to size 0 failed", argv[3]);
1311 			perror("ftruncate");
1312 			exit(1);
1313 		}
1314 	}
1315 	printf("nr_pages: %lu, nr_pages_per_cpu: %lu\n",
1316 	       nr_pages, nr_pages_per_cpu);
1317 	return userfaultfd_stress();
1318 }
1319 
1320 #else /* __NR_userfaultfd */
1321 
1322 #warning "missing __NR_userfaultfd definition"
1323 
main(void)1324 int main(void)
1325 {
1326 	printf("skip: Skipping userfaultfd test (missing __NR_userfaultfd)\n");
1327 	return KSFT_SKIP;
1328 }
1329 
1330 #endif /* __NR_userfaultfd */
1331