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