1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Example of using hugepage memory in a user application using the mmap 4 * system call with MAP_HUGETLB flag. Before running this program make 5 * sure the administrator has allocated enough default sized huge pages 6 * to cover the 256 MB allocation. 7 */ 8 #include <stdlib.h> 9 #include <stdio.h> 10 #include <unistd.h> 11 #include <sys/mman.h> 12 #include <fcntl.h> 13 #include "vm_util.h" 14 #include "../kselftest.h" 15 16 #define LENGTH (256UL*1024*1024) 17 #define PROTECTION (PROT_READ | PROT_WRITE) 18 19 static void check_bytes(char *addr) 20 { 21 ksft_print_msg("First hex is %x\n", *((unsigned int *)addr)); 22 } 23 24 static void write_bytes(char *addr, size_t length) 25 { 26 unsigned long i; 27 28 for (i = 0; i < length; i++) 29 *(addr + i) = (char)i; 30 } 31 32 static void read_bytes(char *addr, size_t length) 33 { 34 unsigned long i; 35 36 check_bytes(addr); 37 for (i = 0; i < length; i++) 38 if (*(addr + i) != (char)i) 39 ksft_exit_fail_msg("Mismatch at %lu\n", i); 40 41 ksft_test_result_pass("Read correct data\n"); 42 } 43 44 int main(int argc, char **argv) 45 { 46 void *addr; 47 size_t hugepage_size; 48 size_t length = LENGTH; 49 int flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB; 50 int shift = 0; 51 52 hugepage_size = default_huge_page_size(); 53 /* munmap with fail if the length is not page aligned */ 54 if (hugepage_size > length) 55 length = hugepage_size; 56 57 ksft_print_header(); 58 ksft_set_plan(1); 59 60 if (argc > 1) 61 length = atol(argv[1]) << 20; 62 if (argc > 2) { 63 shift = atoi(argv[2]); 64 if (shift) 65 flags |= (shift & MAP_HUGE_MASK) << MAP_HUGE_SHIFT; 66 } 67 68 if (shift) 69 ksft_print_msg("%u kB hugepages\n", 1 << (shift - 10)); 70 else 71 ksft_print_msg("Default size hugepages\n"); 72 ksft_print_msg("Mapping %lu Mbytes\n", (unsigned long)length >> 20); 73 74 addr = mmap(NULL, length, PROTECTION, flags, -1, 0); 75 if (addr == MAP_FAILED) 76 ksft_exit_fail_msg("mmap: %s\n", strerror(errno)); 77 78 ksft_print_msg("Returned address is %p\n", addr); 79 check_bytes(addr); 80 write_bytes(addr, length); 81 read_bytes(addr, length); 82 83 /* munmap() length of MAP_HUGETLB memory must be hugepage aligned */ 84 if (munmap(addr, length)) 85 ksft_exit_fail_msg("munmap: %s\n", strerror(errno)); 86 87 ksft_finished(); 88 } 89