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