aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Kravetz <mike.kravetz@oracle.com>2017-09-06 19:24:19 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-09-06 20:27:29 -0400
commit1f522a4856600ac579765b729178f2b3b6a69129 (patch)
treea06e7cebb8c2c5047d5729c86db783f200185c82
parent749df87bd7bee5a79cef073f5d032ddb2b211de8 (diff)
selftests/memfd: add memfd_create hugetlbfs selftest
With the addition of hugetlbfs support in memfd_create, the memfd selftests should verify correct functionality with hugetlbfs. Instead of writing a separate memfd hugetlbfs test, modify the memfd_test program to take an optional argument 'hugetlbfs'. If the hugetlbfs argument is specified, basic memfd_create functionality will be exercised on hugetlbfs. If hugetlbfs is not specified, the current functionality of the test is unchanged. Note that many of the tests in memfd_test test file sealing operations. hugetlbfs does not support file sealing, therefore for hugetlbfs all sealing related tests are skipped. In order to test on hugetlbfs, there needs to be preallocated huge pages. A new script (run_tests) is added. This script will first run the existing memfd_create tests. It will then, attempt to allocate the required number of huge pages before running the hugetlbfs test. At the end of testing, it will release any huge pages allocated for testing purposes. Link: http://lkml.kernel.org/r/1502495772-24736-3-git-send-email-mike.kravetz@oracle.com Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com> Cc: Michal Hocko <mhocko@suse.com> Cc: Hugh Dickins <hughd@google.com> Cc: Andrea Arcangeli <aarcange@redhat.com> Cc: "Kirill A . Shutemov" <kirill.shutemov@linux.intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--tools/testing/selftests/memfd/Makefile2
-rw-r--r--tools/testing/selftests/memfd/memfd_test.c372
-rw-r--r--tools/testing/selftests/memfd/run_tests.sh69
3 files changed, 357 insertions, 86 deletions
diff --git a/tools/testing/selftests/memfd/Makefile b/tools/testing/selftests/memfd/Makefile
index ad8a0897e47f..bc9d02d615da 100644
--- a/tools/testing/selftests/memfd/Makefile
+++ b/tools/testing/selftests/memfd/Makefile
@@ -3,7 +3,7 @@ CFLAGS += -I../../../../include/uapi/
3CFLAGS += -I../../../../include/ 3CFLAGS += -I../../../../include/
4CFLAGS += -I../../../../usr/include/ 4CFLAGS += -I../../../../usr/include/
5 5
6TEST_PROGS := run_fuse_test.sh 6TEST_PROGS := run_tests.sh
7TEST_GEN_FILES := memfd_test fuse_mnt fuse_test 7TEST_GEN_FILES := memfd_test fuse_mnt fuse_test
8 8
9fuse_mnt.o: CFLAGS += $(shell pkg-config fuse --cflags) 9fuse_mnt.o: CFLAGS += $(shell pkg-config fuse --cflags)
diff --git a/tools/testing/selftests/memfd/memfd_test.c b/tools/testing/selftests/memfd/memfd_test.c
index 26546892cd54..f94c6d1fb46f 100644
--- a/tools/testing/selftests/memfd/memfd_test.c
+++ b/tools/testing/selftests/memfd/memfd_test.c
@@ -18,12 +18,48 @@
18#include <sys/wait.h> 18#include <sys/wait.h>
19#include <unistd.h> 19#include <unistd.h>
20 20
21#define MEMFD_STR "memfd:"
22#define SHARED_FT_STR "(shared file-table)"
23
21#define MFD_DEF_SIZE 8192 24#define MFD_DEF_SIZE 8192
22#define STACK_SIZE 65536 25#define STACK_SIZE 65536
23 26
27/*
28 * Default is not to test hugetlbfs
29 */
30static int hugetlbfs_test;
31static size_t mfd_def_size = MFD_DEF_SIZE;
32
33/*
34 * Copied from mlock2-tests.c
35 */
36static unsigned long default_huge_page_size(void)
37{
38 unsigned long hps = 0;
39 char *line = NULL;
40 size_t linelen = 0;
41 FILE *f = fopen("/proc/meminfo", "r");
42
43 if (!f)
44 return 0;
45 while (getline(&line, &linelen, f) > 0) {
46 if (sscanf(line, "Hugepagesize: %lu kB", &hps) == 1) {
47 hps <<= 10;
48 break;
49 }
50 }
51
52 free(line);
53 fclose(f);
54 return hps;
55}
56
24static int sys_memfd_create(const char *name, 57static int sys_memfd_create(const char *name,
25 unsigned int flags) 58 unsigned int flags)
26{ 59{
60 if (hugetlbfs_test)
61 flags |= MFD_HUGETLB;
62
27 return syscall(__NR_memfd_create, name, flags); 63 return syscall(__NR_memfd_create, name, flags);
28} 64}
29 65
@@ -150,7 +186,7 @@ static void *mfd_assert_mmap_shared(int fd)
150 void *p; 186 void *p;
151 187
152 p = mmap(NULL, 188 p = mmap(NULL,
153 MFD_DEF_SIZE, 189 mfd_def_size,
154 PROT_READ | PROT_WRITE, 190 PROT_READ | PROT_WRITE,
155 MAP_SHARED, 191 MAP_SHARED,
156 fd, 192 fd,
@@ -168,7 +204,7 @@ static void *mfd_assert_mmap_private(int fd)
168 void *p; 204 void *p;
169 205
170 p = mmap(NULL, 206 p = mmap(NULL,
171 MFD_DEF_SIZE, 207 mfd_def_size,
172 PROT_READ, 208 PROT_READ,
173 MAP_PRIVATE, 209 MAP_PRIVATE,
174 fd, 210 fd,
@@ -223,7 +259,7 @@ static void mfd_assert_read(int fd)
223 259
224 /* verify PROT_READ *is* allowed */ 260 /* verify PROT_READ *is* allowed */
225 p = mmap(NULL, 261 p = mmap(NULL,
226 MFD_DEF_SIZE, 262 mfd_def_size,
227 PROT_READ, 263 PROT_READ,
228 MAP_PRIVATE, 264 MAP_PRIVATE,
229 fd, 265 fd,
@@ -232,11 +268,11 @@ static void mfd_assert_read(int fd)
232 printf("mmap() failed: %m\n"); 268 printf("mmap() failed: %m\n");
233 abort(); 269 abort();
234 } 270 }
235 munmap(p, MFD_DEF_SIZE); 271 munmap(p, mfd_def_size);
236 272
237 /* verify MAP_PRIVATE is *always* allowed (even writable) */ 273 /* verify MAP_PRIVATE is *always* allowed (even writable) */
238 p = mmap(NULL, 274 p = mmap(NULL,
239 MFD_DEF_SIZE, 275 mfd_def_size,
240 PROT_READ | PROT_WRITE, 276 PROT_READ | PROT_WRITE,
241 MAP_PRIVATE, 277 MAP_PRIVATE,
242 fd, 278 fd,
@@ -245,7 +281,7 @@ static void mfd_assert_read(int fd)
245 printf("mmap() failed: %m\n"); 281 printf("mmap() failed: %m\n");
246 abort(); 282 abort();
247 } 283 }
248 munmap(p, MFD_DEF_SIZE); 284 munmap(p, mfd_def_size);
249} 285}
250 286
251static void mfd_assert_write(int fd) 287static void mfd_assert_write(int fd)
@@ -254,16 +290,22 @@ static void mfd_assert_write(int fd)
254 void *p; 290 void *p;
255 int r; 291 int r;
256 292
257 /* verify write() succeeds */ 293 /*
258 l = write(fd, "\0\0\0\0", 4); 294 * huegtlbfs does not support write, but we want to
259 if (l != 4) { 295 * verify everything else here.
260 printf("write() failed: %m\n"); 296 */
261 abort(); 297 if (!hugetlbfs_test) {
298 /* verify write() succeeds */
299 l = write(fd, "\0\0\0\0", 4);
300 if (l != 4) {
301 printf("write() failed: %m\n");
302 abort();
303 }
262 } 304 }
263 305
264 /* verify PROT_READ | PROT_WRITE is allowed */ 306 /* verify PROT_READ | PROT_WRITE is allowed */
265 p = mmap(NULL, 307 p = mmap(NULL,
266 MFD_DEF_SIZE, 308 mfd_def_size,
267 PROT_READ | PROT_WRITE, 309 PROT_READ | PROT_WRITE,
268 MAP_SHARED, 310 MAP_SHARED,
269 fd, 311 fd,
@@ -273,11 +315,11 @@ static void mfd_assert_write(int fd)
273 abort(); 315 abort();
274 } 316 }
275 *(char *)p = 0; 317 *(char *)p = 0;
276 munmap(p, MFD_DEF_SIZE); 318 munmap(p, mfd_def_size);
277 319
278 /* verify PROT_WRITE is allowed */ 320 /* verify PROT_WRITE is allowed */
279 p = mmap(NULL, 321 p = mmap(NULL,
280 MFD_DEF_SIZE, 322 mfd_def_size,
281 PROT_WRITE, 323 PROT_WRITE,
282 MAP_SHARED, 324 MAP_SHARED,
283 fd, 325 fd,
@@ -287,12 +329,12 @@ static void mfd_assert_write(int fd)
287 abort(); 329 abort();
288 } 330 }
289 *(char *)p = 0; 331 *(char *)p = 0;
290 munmap(p, MFD_DEF_SIZE); 332 munmap(p, mfd_def_size);
291 333
292 /* verify PROT_READ with MAP_SHARED is allowed and a following 334 /* verify PROT_READ with MAP_SHARED is allowed and a following
293 * mprotect(PROT_WRITE) allows writing */ 335 * mprotect(PROT_WRITE) allows writing */
294 p = mmap(NULL, 336 p = mmap(NULL,
295 MFD_DEF_SIZE, 337 mfd_def_size,
296 PROT_READ, 338 PROT_READ,
297 MAP_SHARED, 339 MAP_SHARED,
298 fd, 340 fd,
@@ -302,20 +344,20 @@ static void mfd_assert_write(int fd)
302 abort(); 344 abort();
303 } 345 }
304 346
305 r = mprotect(p, MFD_DEF_SIZE, PROT_READ | PROT_WRITE); 347 r = mprotect(p, mfd_def_size, PROT_READ | PROT_WRITE);
306 if (r < 0) { 348 if (r < 0) {
307 printf("mprotect() failed: %m\n"); 349 printf("mprotect() failed: %m\n");
308 abort(); 350 abort();
309 } 351 }
310 352
311 *(char *)p = 0; 353 *(char *)p = 0;
312 munmap(p, MFD_DEF_SIZE); 354 munmap(p, mfd_def_size);
313 355
314 /* verify PUNCH_HOLE works */ 356 /* verify PUNCH_HOLE works */
315 r = fallocate(fd, 357 r = fallocate(fd,
316 FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, 358 FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
317 0, 359 0,
318 MFD_DEF_SIZE); 360 mfd_def_size);
319 if (r < 0) { 361 if (r < 0) {
320 printf("fallocate(PUNCH_HOLE) failed: %m\n"); 362 printf("fallocate(PUNCH_HOLE) failed: %m\n");
321 abort(); 363 abort();
@@ -337,7 +379,7 @@ static void mfd_fail_write(int fd)
337 379
338 /* verify PROT_READ | PROT_WRITE is not allowed */ 380 /* verify PROT_READ | PROT_WRITE is not allowed */
339 p = mmap(NULL, 381 p = mmap(NULL,
340 MFD_DEF_SIZE, 382 mfd_def_size,
341 PROT_READ | PROT_WRITE, 383 PROT_READ | PROT_WRITE,
342 MAP_SHARED, 384 MAP_SHARED,
343 fd, 385 fd,
@@ -349,7 +391,7 @@ static void mfd_fail_write(int fd)
349 391
350 /* verify PROT_WRITE is not allowed */ 392 /* verify PROT_WRITE is not allowed */
351 p = mmap(NULL, 393 p = mmap(NULL,
352 MFD_DEF_SIZE, 394 mfd_def_size,
353 PROT_WRITE, 395 PROT_WRITE,
354 MAP_SHARED, 396 MAP_SHARED,
355 fd, 397 fd,
@@ -362,13 +404,13 @@ static void mfd_fail_write(int fd)
362 /* Verify PROT_READ with MAP_SHARED with a following mprotect is not 404 /* Verify PROT_READ with MAP_SHARED with a following mprotect is not
363 * allowed. Note that for r/w the kernel already prevents the mmap. */ 405 * allowed. Note that for r/w the kernel already prevents the mmap. */
364 p = mmap(NULL, 406 p = mmap(NULL,
365 MFD_DEF_SIZE, 407 mfd_def_size,
366 PROT_READ, 408 PROT_READ,
367 MAP_SHARED, 409 MAP_SHARED,
368 fd, 410 fd,
369 0); 411 0);
370 if (p != MAP_FAILED) { 412 if (p != MAP_FAILED) {
371 r = mprotect(p, MFD_DEF_SIZE, PROT_READ | PROT_WRITE); 413 r = mprotect(p, mfd_def_size, PROT_READ | PROT_WRITE);
372 if (r >= 0) { 414 if (r >= 0) {
373 printf("mmap()+mprotect() didn't fail as expected\n"); 415 printf("mmap()+mprotect() didn't fail as expected\n");
374 abort(); 416 abort();
@@ -379,7 +421,7 @@ static void mfd_fail_write(int fd)
379 r = fallocate(fd, 421 r = fallocate(fd,
380 FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, 422 FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
381 0, 423 0,
382 MFD_DEF_SIZE); 424 mfd_def_size);
383 if (r >= 0) { 425 if (r >= 0) {
384 printf("fallocate(PUNCH_HOLE) didn't fail as expected\n"); 426 printf("fallocate(PUNCH_HOLE) didn't fail as expected\n");
385 abort(); 427 abort();
@@ -390,13 +432,13 @@ static void mfd_assert_shrink(int fd)
390{ 432{
391 int r, fd2; 433 int r, fd2;
392 434
393 r = ftruncate(fd, MFD_DEF_SIZE / 2); 435 r = ftruncate(fd, mfd_def_size / 2);
394 if (r < 0) { 436 if (r < 0) {
395 printf("ftruncate(SHRINK) failed: %m\n"); 437 printf("ftruncate(SHRINK) failed: %m\n");
396 abort(); 438 abort();
397 } 439 }
398 440
399 mfd_assert_size(fd, MFD_DEF_SIZE / 2); 441 mfd_assert_size(fd, mfd_def_size / 2);
400 442
401 fd2 = mfd_assert_open(fd, 443 fd2 = mfd_assert_open(fd,
402 O_RDWR | O_CREAT | O_TRUNC, 444 O_RDWR | O_CREAT | O_TRUNC,
@@ -410,7 +452,7 @@ static void mfd_fail_shrink(int fd)
410{ 452{
411 int r; 453 int r;
412 454
413 r = ftruncate(fd, MFD_DEF_SIZE / 2); 455 r = ftruncate(fd, mfd_def_size / 2);
414 if (r >= 0) { 456 if (r >= 0) {
415 printf("ftruncate(SHRINK) didn't fail as expected\n"); 457 printf("ftruncate(SHRINK) didn't fail as expected\n");
416 abort(); 458 abort();
@@ -425,31 +467,31 @@ static void mfd_assert_grow(int fd)
425{ 467{
426 int r; 468 int r;
427 469
428 r = ftruncate(fd, MFD_DEF_SIZE * 2); 470 r = ftruncate(fd, mfd_def_size * 2);
429 if (r < 0) { 471 if (r < 0) {
430 printf("ftruncate(GROW) failed: %m\n"); 472 printf("ftruncate(GROW) failed: %m\n");
431 abort(); 473 abort();
432 } 474 }
433 475
434 mfd_assert_size(fd, MFD_DEF_SIZE * 2); 476 mfd_assert_size(fd, mfd_def_size * 2);
435 477
436 r = fallocate(fd, 478 r = fallocate(fd,
437 0, 479 0,
438 0, 480 0,
439 MFD_DEF_SIZE * 4); 481 mfd_def_size * 4);
440 if (r < 0) { 482 if (r < 0) {
441 printf("fallocate(ALLOC) failed: %m\n"); 483 printf("fallocate(ALLOC) failed: %m\n");
442 abort(); 484 abort();
443 } 485 }
444 486
445 mfd_assert_size(fd, MFD_DEF_SIZE * 4); 487 mfd_assert_size(fd, mfd_def_size * 4);
446} 488}
447 489
448static void mfd_fail_grow(int fd) 490static void mfd_fail_grow(int fd)
449{ 491{
450 int r; 492 int r;
451 493
452 r = ftruncate(fd, MFD_DEF_SIZE * 2); 494 r = ftruncate(fd, mfd_def_size * 2);
453 if (r >= 0) { 495 if (r >= 0) {
454 printf("ftruncate(GROW) didn't fail as expected\n"); 496 printf("ftruncate(GROW) didn't fail as expected\n");
455 abort(); 497 abort();
@@ -458,7 +500,7 @@ static void mfd_fail_grow(int fd)
458 r = fallocate(fd, 500 r = fallocate(fd,
459 0, 501 0,
460 0, 502 0,
461 MFD_DEF_SIZE * 4); 503 mfd_def_size * 4);
462 if (r >= 0) { 504 if (r >= 0) {
463 printf("fallocate(ALLOC) didn't fail as expected\n"); 505 printf("fallocate(ALLOC) didn't fail as expected\n");
464 abort(); 506 abort();
@@ -467,25 +509,37 @@ static void mfd_fail_grow(int fd)
467 509
468static void mfd_assert_grow_write(int fd) 510static void mfd_assert_grow_write(int fd)
469{ 511{
470 static char buf[MFD_DEF_SIZE * 8]; 512 static char *buf;
471 ssize_t l; 513 ssize_t l;
472 514
473 l = pwrite(fd, buf, sizeof(buf), 0); 515 buf = malloc(mfd_def_size * 8);
474 if (l != sizeof(buf)) { 516 if (!buf) {
517 printf("malloc(%d) failed: %m\n", mfd_def_size * 8);
518 abort();
519 }
520
521 l = pwrite(fd, buf, mfd_def_size * 8, 0);
522 if (l != (mfd_def_size * 8)) {
475 printf("pwrite() failed: %m\n"); 523 printf("pwrite() failed: %m\n");
476 abort(); 524 abort();
477 } 525 }
478 526
479 mfd_assert_size(fd, MFD_DEF_SIZE * 8); 527 mfd_assert_size(fd, mfd_def_size * 8);
480} 528}
481 529
482static void mfd_fail_grow_write(int fd) 530static void mfd_fail_grow_write(int fd)
483{ 531{
484 static char buf[MFD_DEF_SIZE * 8]; 532 static char *buf;
485 ssize_t l; 533 ssize_t l;
486 534
487 l = pwrite(fd, buf, sizeof(buf), 0); 535 buf = malloc(mfd_def_size * 8);
488 if (l == sizeof(buf)) { 536 if (!buf) {
537 printf("malloc(%d) failed: %m\n", mfd_def_size * 8);
538 abort();
539 }
540
541 l = pwrite(fd, buf, mfd_def_size * 8, 0);
542 if (l == (mfd_def_size * 8)) {
489 printf("pwrite() didn't fail as expected\n"); 543 printf("pwrite() didn't fail as expected\n");
490 abort(); 544 abort();
491 } 545 }
@@ -543,6 +597,8 @@ static void test_create(void)
543 char buf[2048]; 597 char buf[2048];
544 int fd; 598 int fd;
545 599
600 printf("%s CREATE\n", MEMFD_STR);
601
546 /* test NULL name */ 602 /* test NULL name */
547 mfd_fail_new(NULL, 0); 603 mfd_fail_new(NULL, 0);
548 604
@@ -570,13 +626,18 @@ static void test_create(void)
570 fd = mfd_assert_new("", 0, MFD_CLOEXEC); 626 fd = mfd_assert_new("", 0, MFD_CLOEXEC);
571 close(fd); 627 close(fd);
572 628
573 /* verify MFD_ALLOW_SEALING is allowed */ 629 if (!hugetlbfs_test) {
574 fd = mfd_assert_new("", 0, MFD_ALLOW_SEALING); 630 /* verify MFD_ALLOW_SEALING is allowed */
575 close(fd); 631 fd = mfd_assert_new("", 0, MFD_ALLOW_SEALING);
576 632 close(fd);
577 /* verify MFD_ALLOW_SEALING | MFD_CLOEXEC is allowed */ 633
578 fd = mfd_assert_new("", 0, MFD_ALLOW_SEALING | MFD_CLOEXEC); 634 /* verify MFD_ALLOW_SEALING | MFD_CLOEXEC is allowed */
579 close(fd); 635 fd = mfd_assert_new("", 0, MFD_ALLOW_SEALING | MFD_CLOEXEC);
636 close(fd);
637 } else {
638 /* sealing is not supported on hugetlbfs */
639 mfd_fail_new("", MFD_ALLOW_SEALING);
640 }
580} 641}
581 642
582/* 643/*
@@ -587,8 +648,14 @@ static void test_basic(void)
587{ 648{
588 int fd; 649 int fd;
589 650
651 /* hugetlbfs does not contain sealing support */
652 if (hugetlbfs_test)
653 return;
654
655 printf("%s BASIC\n", MEMFD_STR);
656
590 fd = mfd_assert_new("kern_memfd_basic", 657 fd = mfd_assert_new("kern_memfd_basic",
591 MFD_DEF_SIZE, 658 mfd_def_size,
592 MFD_CLOEXEC | MFD_ALLOW_SEALING); 659 MFD_CLOEXEC | MFD_ALLOW_SEALING);
593 660
594 /* add basic seals */ 661 /* add basic seals */
@@ -619,7 +686,7 @@ static void test_basic(void)
619 686
620 /* verify sealing does not work without MFD_ALLOW_SEALING */ 687 /* verify sealing does not work without MFD_ALLOW_SEALING */
621 fd = mfd_assert_new("kern_memfd_basic", 688 fd = mfd_assert_new("kern_memfd_basic",
622 MFD_DEF_SIZE, 689 mfd_def_size,
623 MFD_CLOEXEC); 690 MFD_CLOEXEC);
624 mfd_assert_has_seals(fd, F_SEAL_SEAL); 691 mfd_assert_has_seals(fd, F_SEAL_SEAL);
625 mfd_fail_add_seals(fd, F_SEAL_SHRINK | 692 mfd_fail_add_seals(fd, F_SEAL_SHRINK |
@@ -630,6 +697,28 @@ static void test_basic(void)
630} 697}
631 698
632/* 699/*
700 * hugetlbfs doesn't support seals or write, so just verify grow and shrink
701 * on a hugetlbfs file created via memfd_create.
702 */
703static void test_hugetlbfs_grow_shrink(void)
704{
705 int fd;
706
707 printf("%s HUGETLBFS-GROW-SHRINK\n", MEMFD_STR);
708
709 fd = mfd_assert_new("kern_memfd_seal_write",
710 mfd_def_size,
711 MFD_CLOEXEC);
712
713 mfd_assert_read(fd);
714 mfd_assert_write(fd);
715 mfd_assert_shrink(fd);
716 mfd_assert_grow(fd);
717
718 close(fd);
719}
720
721/*
633 * Test SEAL_WRITE 722 * Test SEAL_WRITE
634 * Test whether SEAL_WRITE actually prevents modifications. 723 * Test whether SEAL_WRITE actually prevents modifications.
635 */ 724 */
@@ -637,8 +726,17 @@ static void test_seal_write(void)
637{ 726{
638 int fd; 727 int fd;
639 728
729 /*
730 * hugetlbfs does not contain sealing or write support. Just test
731 * basic grow and shrink via test_hugetlbfs_grow_shrink.
732 */
733 if (hugetlbfs_test)
734 return test_hugetlbfs_grow_shrink();
735
736 printf("%s SEAL-WRITE\n", MEMFD_STR);
737
640 fd = mfd_assert_new("kern_memfd_seal_write", 738 fd = mfd_assert_new("kern_memfd_seal_write",
641 MFD_DEF_SIZE, 739 mfd_def_size,
642 MFD_CLOEXEC | MFD_ALLOW_SEALING); 740 MFD_CLOEXEC | MFD_ALLOW_SEALING);
643 mfd_assert_has_seals(fd, 0); 741 mfd_assert_has_seals(fd, 0);
644 mfd_assert_add_seals(fd, F_SEAL_WRITE); 742 mfd_assert_add_seals(fd, F_SEAL_WRITE);
@@ -661,8 +759,14 @@ static void test_seal_shrink(void)
661{ 759{
662 int fd; 760 int fd;
663 761
762 /* hugetlbfs does not contain sealing support */
763 if (hugetlbfs_test)
764 return;
765
766 printf("%s SEAL-SHRINK\n", MEMFD_STR);
767
664 fd = mfd_assert_new("kern_memfd_seal_shrink", 768 fd = mfd_assert_new("kern_memfd_seal_shrink",
665 MFD_DEF_SIZE, 769 mfd_def_size,
666 MFD_CLOEXEC | MFD_ALLOW_SEALING); 770 MFD_CLOEXEC | MFD_ALLOW_SEALING);
667 mfd_assert_has_seals(fd, 0); 771 mfd_assert_has_seals(fd, 0);
668 mfd_assert_add_seals(fd, F_SEAL_SHRINK); 772 mfd_assert_add_seals(fd, F_SEAL_SHRINK);
@@ -685,8 +789,14 @@ static void test_seal_grow(void)
685{ 789{
686 int fd; 790 int fd;
687 791
792 /* hugetlbfs does not contain sealing support */
793 if (hugetlbfs_test)
794 return;
795
796 printf("%s SEAL-GROW\n", MEMFD_STR);
797
688 fd = mfd_assert_new("kern_memfd_seal_grow", 798 fd = mfd_assert_new("kern_memfd_seal_grow",
689 MFD_DEF_SIZE, 799 mfd_def_size,
690 MFD_CLOEXEC | MFD_ALLOW_SEALING); 800 MFD_CLOEXEC | MFD_ALLOW_SEALING);
691 mfd_assert_has_seals(fd, 0); 801 mfd_assert_has_seals(fd, 0);
692 mfd_assert_add_seals(fd, F_SEAL_GROW); 802 mfd_assert_add_seals(fd, F_SEAL_GROW);
@@ -709,8 +819,14 @@ static void test_seal_resize(void)
709{ 819{
710 int fd; 820 int fd;
711 821
822 /* hugetlbfs does not contain sealing support */
823 if (hugetlbfs_test)
824 return;
825
826 printf("%s SEAL-RESIZE\n", MEMFD_STR);
827
712 fd = mfd_assert_new("kern_memfd_seal_resize", 828 fd = mfd_assert_new("kern_memfd_seal_resize",
713 MFD_DEF_SIZE, 829 mfd_def_size,
714 MFD_CLOEXEC | MFD_ALLOW_SEALING); 830 MFD_CLOEXEC | MFD_ALLOW_SEALING);
715 mfd_assert_has_seals(fd, 0); 831 mfd_assert_has_seals(fd, 0);
716 mfd_assert_add_seals(fd, F_SEAL_SHRINK | F_SEAL_GROW); 832 mfd_assert_add_seals(fd, F_SEAL_SHRINK | F_SEAL_GROW);
@@ -726,15 +842,52 @@ static void test_seal_resize(void)
726} 842}
727 843
728/* 844/*
845 * hugetlbfs does not support seals. Basic test to dup the memfd created
846 * fd and perform some basic operations on it.
847 */
848static void hugetlbfs_dup(char *b_suffix)
849{
850 int fd, fd2;
851
852 printf("%s HUGETLBFS-DUP %s\n", MEMFD_STR, b_suffix);
853
854 fd = mfd_assert_new("kern_memfd_share_dup",
855 mfd_def_size,
856 MFD_CLOEXEC);
857
858 fd2 = mfd_assert_dup(fd);
859
860 mfd_assert_read(fd);
861 mfd_assert_write(fd);
862
863 mfd_assert_shrink(fd2);
864 mfd_assert_grow(fd2);
865
866 close(fd2);
867 close(fd);
868}
869
870/*
729 * Test sharing via dup() 871 * Test sharing via dup()
730 * Test that seals are shared between dupped FDs and they're all equal. 872 * Test that seals are shared between dupped FDs and they're all equal.
731 */ 873 */
732static void test_share_dup(void) 874static void test_share_dup(char *banner, char *b_suffix)
733{ 875{
734 int fd, fd2; 876 int fd, fd2;
735 877
878 /*
879 * hugetlbfs does not contain sealing support. Perform some
880 * basic testing on dup'ed fd instead via hugetlbfs_dup.
881 */
882 if (hugetlbfs_test) {
883 hugetlbfs_dup(b_suffix);
884 return;
885 }
886
887 printf("%s %s %s\n", MEMFD_STR, banner, b_suffix);
888
736 fd = mfd_assert_new("kern_memfd_share_dup", 889 fd = mfd_assert_new("kern_memfd_share_dup",
737 MFD_DEF_SIZE, 890 mfd_def_size,
738 MFD_CLOEXEC | MFD_ALLOW_SEALING); 891 MFD_CLOEXEC | MFD_ALLOW_SEALING);
739 mfd_assert_has_seals(fd, 0); 892 mfd_assert_has_seals(fd, 0);
740 893
@@ -768,13 +921,19 @@ static void test_share_dup(void)
768 * Test sealing with active mmap()s 921 * Test sealing with active mmap()s
769 * Modifying seals is only allowed if no other mmap() refs exist. 922 * Modifying seals is only allowed if no other mmap() refs exist.
770 */ 923 */
771static void test_share_mmap(void) 924static void test_share_mmap(char *banner, char *b_suffix)
772{ 925{
773 int fd; 926 int fd;
774 void *p; 927 void *p;
775 928
929 /* hugetlbfs does not contain sealing support */
930 if (hugetlbfs_test)
931 return;
932
933 printf("%s %s %s\n", MEMFD_STR, banner, b_suffix);
934
776 fd = mfd_assert_new("kern_memfd_share_mmap", 935 fd = mfd_assert_new("kern_memfd_share_mmap",
777 MFD_DEF_SIZE, 936 mfd_def_size,
778 MFD_CLOEXEC | MFD_ALLOW_SEALING); 937 MFD_CLOEXEC | MFD_ALLOW_SEALING);
779 mfd_assert_has_seals(fd, 0); 938 mfd_assert_has_seals(fd, 0);
780 939
@@ -784,14 +943,40 @@ static void test_share_mmap(void)
784 mfd_assert_has_seals(fd, 0); 943 mfd_assert_has_seals(fd, 0);
785 mfd_assert_add_seals(fd, F_SEAL_SHRINK); 944 mfd_assert_add_seals(fd, F_SEAL_SHRINK);
786 mfd_assert_has_seals(fd, F_SEAL_SHRINK); 945 mfd_assert_has_seals(fd, F_SEAL_SHRINK);
787 munmap(p, MFD_DEF_SIZE); 946 munmap(p, mfd_def_size);
788 947
789 /* readable ref allows sealing */ 948 /* readable ref allows sealing */
790 p = mfd_assert_mmap_private(fd); 949 p = mfd_assert_mmap_private(fd);
791 mfd_assert_add_seals(fd, F_SEAL_WRITE); 950 mfd_assert_add_seals(fd, F_SEAL_WRITE);
792 mfd_assert_has_seals(fd, F_SEAL_WRITE | F_SEAL_SHRINK); 951 mfd_assert_has_seals(fd, F_SEAL_WRITE | F_SEAL_SHRINK);
793 munmap(p, MFD_DEF_SIZE); 952 munmap(p, mfd_def_size);
953
954 close(fd);
955}
956
957/*
958 * Basic test to make sure we can open the hugetlbfs fd via /proc and
959 * perform some simple operations on it.
960 */
961static void hugetlbfs_proc_open(char *b_suffix)
962{
963 int fd, fd2;
964
965 printf("%s HUGETLBFS-PROC-OPEN %s\n", MEMFD_STR, b_suffix);
794 966
967 fd = mfd_assert_new("kern_memfd_share_open",
968 mfd_def_size,
969 MFD_CLOEXEC);
970
971 fd2 = mfd_assert_open(fd, O_RDWR, 0);
972
973 mfd_assert_read(fd);
974 mfd_assert_write(fd);
975
976 mfd_assert_shrink(fd2);
977 mfd_assert_grow(fd2);
978
979 close(fd2);
795 close(fd); 980 close(fd);
796} 981}
797 982
@@ -801,12 +986,23 @@ static void test_share_mmap(void)
801 * This is *not* like dup(), but like a real separate open(). Make sure the 986 * This is *not* like dup(), but like a real separate open(). Make sure the
802 * semantics are as expected and we correctly check for RDONLY / WRONLY / RDWR. 987 * semantics are as expected and we correctly check for RDONLY / WRONLY / RDWR.
803 */ 988 */
804static void test_share_open(void) 989static void test_share_open(char *banner, char *b_suffix)
805{ 990{
806 int fd, fd2; 991 int fd, fd2;
807 992
993 /*
994 * hugetlbfs does not contain sealing support. So test basic
995 * functionality of using /proc fd via hugetlbfs_proc_open
996 */
997 if (hugetlbfs_test) {
998 hugetlbfs_proc_open(b_suffix);
999 return;
1000 }
1001
1002 printf("%s %s %s\n", MEMFD_STR, banner, b_suffix);
1003
808 fd = mfd_assert_new("kern_memfd_share_open", 1004 fd = mfd_assert_new("kern_memfd_share_open",
809 MFD_DEF_SIZE, 1005 mfd_def_size,
810 MFD_CLOEXEC | MFD_ALLOW_SEALING); 1006 MFD_CLOEXEC | MFD_ALLOW_SEALING);
811 mfd_assert_has_seals(fd, 0); 1007 mfd_assert_has_seals(fd, 0);
812 1008
@@ -841,13 +1037,19 @@ static void test_share_open(void)
841 * Test sharing via fork() 1037 * Test sharing via fork()
842 * Test whether seal-modifications work as expected with forked childs. 1038 * Test whether seal-modifications work as expected with forked childs.
843 */ 1039 */
844static void test_share_fork(void) 1040static void test_share_fork(char *banner, char *b_suffix)
845{ 1041{
846 int fd; 1042 int fd;
847 pid_t pid; 1043 pid_t pid;
848 1044
1045 /* hugetlbfs does not contain sealing support */
1046 if (hugetlbfs_test)
1047 return;
1048
1049 printf("%s %s %s\n", MEMFD_STR, banner, b_suffix);
1050
849 fd = mfd_assert_new("kern_memfd_share_fork", 1051 fd = mfd_assert_new("kern_memfd_share_fork",
850 MFD_DEF_SIZE, 1052 mfd_def_size,
851 MFD_CLOEXEC | MFD_ALLOW_SEALING); 1053 MFD_CLOEXEC | MFD_ALLOW_SEALING);
852 mfd_assert_has_seals(fd, 0); 1054 mfd_assert_has_seals(fd, 0);
853 1055
@@ -870,40 +1072,40 @@ int main(int argc, char **argv)
870{ 1072{
871 pid_t pid; 1073 pid_t pid;
872 1074
873 printf("memfd: CREATE\n"); 1075 if (argc == 2) {
1076 if (!strcmp(argv[1], "hugetlbfs")) {
1077 unsigned long hpage_size = default_huge_page_size();
1078
1079 if (!hpage_size) {
1080 printf("Unable to determine huge page size\n");
1081 abort();
1082 }
1083
1084 hugetlbfs_test = 1;
1085 mfd_def_size = hpage_size * 2;
1086 }
1087 }
1088
874 test_create(); 1089 test_create();
875 printf("memfd: BASIC\n");
876 test_basic(); 1090 test_basic();
877 1091
878 printf("memfd: SEAL-WRITE\n");
879 test_seal_write(); 1092 test_seal_write();
880 printf("memfd: SEAL-SHRINK\n");
881 test_seal_shrink(); 1093 test_seal_shrink();
882 printf("memfd: SEAL-GROW\n");
883 test_seal_grow(); 1094 test_seal_grow();
884 printf("memfd: SEAL-RESIZE\n");
885 test_seal_resize(); 1095 test_seal_resize();
886 1096
887 printf("memfd: SHARE-DUP\n"); 1097 test_share_dup("SHARE-DUP", "");
888 test_share_dup(); 1098 test_share_mmap("SHARE-MMAP", "");
889 printf("memfd: SHARE-MMAP\n"); 1099 test_share_open("SHARE-OPEN", "");
890 test_share_mmap(); 1100 test_share_fork("SHARE-FORK", "");
891 printf("memfd: SHARE-OPEN\n");
892 test_share_open();
893 printf("memfd: SHARE-FORK\n");
894 test_share_fork();
895 1101
896 /* Run test-suite in a multi-threaded environment with a shared 1102 /* Run test-suite in a multi-threaded environment with a shared
897 * file-table. */ 1103 * file-table. */
898 pid = spawn_idle_thread(CLONE_FILES | CLONE_FS | CLONE_VM); 1104 pid = spawn_idle_thread(CLONE_FILES | CLONE_FS | CLONE_VM);
899 printf("memfd: SHARE-DUP (shared file-table)\n"); 1105 test_share_dup("SHARE-DUP", SHARED_FT_STR);
900 test_share_dup(); 1106 test_share_mmap("SHARE-MMAP", SHARED_FT_STR);
901 printf("memfd: SHARE-MMAP (shared file-table)\n"); 1107 test_share_open("SHARE-OPEN", SHARED_FT_STR);
902 test_share_mmap(); 1108 test_share_fork("SHARE-FORK", SHARED_FT_STR);
903 printf("memfd: SHARE-OPEN (shared file-table)\n");
904 test_share_open();
905 printf("memfd: SHARE-FORK (shared file-table)\n");
906 test_share_fork();
907 join_idle_thread(pid); 1109 join_idle_thread(pid);
908 1110
909 printf("memfd: DONE\n"); 1111 printf("memfd: DONE\n");
diff --git a/tools/testing/selftests/memfd/run_tests.sh b/tools/testing/selftests/memfd/run_tests.sh
new file mode 100644
index 000000000000..daabb350697c
--- /dev/null
+++ b/tools/testing/selftests/memfd/run_tests.sh
@@ -0,0 +1,69 @@
1#!/bin/bash
2# please run as root
3
4#
5# Normal tests requiring no special resources
6#
7./run_fuse_test.sh
8./memfd_test
9
10#
11# To test memfd_create with hugetlbfs, there needs to be hpages_test
12# huge pages free. Attempt to allocate enough pages to test.
13#
14hpages_test=8
15
16#
17# Get count of free huge pages from /proc/meminfo
18#
19while read name size unit; do
20 if [ "$name" = "HugePages_Free:" ]; then
21 freepgs=$size
22 fi
23done < /proc/meminfo
24
25#
26# If not enough free huge pages for test, attempt to increase
27#
28if [ -n "$freepgs" ] && [ $freepgs -lt $hpages_test ]; then
29 nr_hugepgs=`cat /proc/sys/vm/nr_hugepages`
30 hpages_needed=`expr $hpages_test - $freepgs`
31
32 echo 3 > /proc/sys/vm/drop_caches
33 echo $(( $hpages_needed + $nr_hugepgs )) > /proc/sys/vm/nr_hugepages
34 if [ $? -ne 0 ]; then
35 echo "Please run this test as root"
36 exit 1
37 fi
38 while read name size unit; do
39 if [ "$name" = "HugePages_Free:" ]; then
40 freepgs=$size
41 fi
42 done < /proc/meminfo
43fi
44
45#
46# If still not enough huge pages available, exit. But, give back any huge
47# pages potentially allocated above.
48#
49if [ $freepgs -lt $hpages_test ]; then
50 # nr_hugepgs non-zero only if we attempted to increase
51 if [ -n "$nr_hugepgs" ]; then
52 echo $nr_hugepgs > /proc/sys/vm/nr_hugepages
53 fi
54 printf "Not enough huge pages available (%d < %d)\n" \
55 $freepgs $needpgs
56 exit 1
57fi
58
59#
60# Run the hugetlbfs test
61#
62./memfd_test hugetlbfs
63
64#
65# Give back any huge pages allocated for the test
66#
67if [ -n "$nr_hugepgs" ]; then
68 echo $nr_hugepgs > /proc/sys/vm/nr_hugepages
69fi