xref: /aosp_15_r20/external/ltp/testcases/kernel/syscalls/memfd_create/memfd_create04.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /*
4  * Copyright (c) Zilogic Systems Pvt. Ltd. <[email protected]>, 2018
5  * Copyright (c) Linux Test Project, 2019-2023
6  */
7 
8 /*\
9  * [Description]
10  *
11  * Validating memfd_create() with MFD_HUGETLB and MFD_HUGE_x flags.
12  *
13  * Attempt to create files in the hugetlbfs filesystem using different huge page
14  * sizes.
15  *
16  * [Algorithm]
17  *
18  * memfd_create() should return non-negative value (fd) if the system supports
19  * that particular huge page size.
20  * On success, fd is returned. On failure, -1 is returned with ENODEV error.
21  */
22 
23 #define _GNU_SOURCE
24 
25 #include "tst_test.h"
26 #include "memfd_create_common.h"
27 
28 #include <errno.h>
29 #include <stdio.h>
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");
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",
82 		tflag.h_size);
83 
84 	SAFE_CLOSE(fd);
85 }
86 
setup(void)87 static void setup(void)
88 {
89 	if (access(PATH_HUGEPAGES, F_OK))
90 		tst_brk(TCONF, "Huge page is not supported");
91 }
92 
93 static struct tst_test test = {
94 	.setup = setup,
95 	.test = memfd_huge_x_controller,
96 	.tcnt = ARRAY_SIZE(test_flags),
97 	.min_kver = "4.14",
98 };
99