1 // SPDX-License-Identifier: GPL-2.0-or-later
2 // SPDX-License-Identifier: GPL-2.0-or-later
3
4 /*
5 * Copyright (c) Zilogic Systems Pvt. Ltd., 2018
6 * Email: code@zilogic.com
7 */
8
9 /*
10 * Test: Validating memfd_create() with MFD_HUGETLB and MFD_HUGE_x flags.
11 *
12 * Test cases: Attempt to create files in the hugetlbfs filesystem using
13 * different huge page sizes.
14 *
15 * Test logic: memfd_create() should return non-negative value (fd)
16 * if the system supports that particular huge page size.
17 * On success, fd is returned.
18 * On failure, -1 is returned with ENODEV error.
19 */
20
21 #define _GNU_SOURCE
22
23 #include "tst_test.h"
24 #include "memfd_create_common.h"
25
26 #include <errno.h>
27 #include <stdio.h>
28
29 #define PATH_HUGEPAGES "/sys/kernel/mm/hugepages"
30
31 static struct test_flag {
32 int flag;
33 char *h_size;
34 int exp_err;
35 } test_flags[] = {
36 {.flag = MFD_HUGE_64KB, .h_size = "64kB"},
37 {.flag = MFD_HUGE_512KB, .h_size = "512kB"},
38 {.flag = MFD_HUGE_2MB, .h_size = "2048kB"},
39 {.flag = MFD_HUGE_8MB, .h_size = "8192kB"},
40 {.flag = MFD_HUGE_16MB, .h_size = "16384kB"},
41 {.flag = MFD_HUGE_256MB, .h_size = "262144kB"},
42 {.flag = MFD_HUGE_1GB, .h_size = "1048576kB"},
43 {.flag = MFD_HUGE_2GB, .h_size = "2097152kB"},
44 {.flag = MFD_HUGE_16GB, .h_size = "16777216kB"},
45 };
46
check_hugepage_support(struct test_flag * test_flags)47 static void check_hugepage_support(struct test_flag *test_flags)
48 {
49 char pattern[64];
50
51 sprintf(pattern, PATH_HUGEPAGES);
52 strcat(pattern, "/hugepages-");
53 strcat(pattern, test_flags->h_size);
54
55 if (access(pattern, F_OK))
56 test_flags->exp_err = ENODEV;
57 }
58
memfd_huge_x_controller(unsigned int n)59 static void memfd_huge_x_controller(unsigned int n)
60 {
61 int fd;
62 struct test_flag tflag;
63
64 tflag = test_flags[n];
65 check_hugepage_support(&tflag);
66 tst_res(TINFO,
67 "Attempt to create file using %s huge page size",
68 tflag.h_size);
69
70 fd = sys_memfd_create("tfile", MFD_HUGETLB | tflag.flag);
71 if (fd < 0) {
72 if (errno == tflag.exp_err)
73 tst_res(TPASS, "Test failed as expected\n");
74 else
75 tst_brk(TFAIL | TERRNO,
76 "memfd_create() failed unexpectedly");
77 return;
78 }
79
80 tst_res(TPASS,
81 "memfd_create succeeded for %s page size\n",
82 tflag.h_size);
83 }
84
setup(void)85 static void setup(void)
86 {
87 if (access(PATH_HUGEPAGES, F_OK))
88 tst_brk(TCONF, "Huge page is not supported");
89 }
90
91 static struct tst_test test = {
92 .setup = setup,
93 .test = memfd_huge_x_controller,
94 .tcnt = ARRAY_SIZE(test_flags),
95 .min_kver = "4.14",
96 };
97