1// SPDX-License-Identifier: LGPL-2.1-or-later 2/* 3 * Copyright (C) 2009 IBM Corporation. 4 * Author: David Gibson 5 */ 6 7/*\ 8 * [Description] 9 * 10 * Test Description: The kernel has bug for mremap() on some architecture. 11 * mremap() can cause crashes on architectures with holes in the address 12 * space (like ia64) and on powerpc with it's distinct page size "slices". 13 * 14 * This test get the huge mapping address and mremap() normal mapping 15 * near to this huge mapping. 16 */ 17 18#define _GNU_SOURCE 19#include "hugetlb.h" 20 21#define MNTPOINT "hugetlbfs/" 22 23static int fd = -1; 24static long hpage_size, page_size; 25 26static int do_remap(void *target) 27{ 28 void *a, *b; 29 int ret; 30 31 a = SAFE_MMAP(NULL, page_size, PROT_READ|PROT_WRITE, 32 MAP_SHARED|MAP_ANONYMOUS, -1, 0); 33 34 ret = do_readback(a, page_size, "base normal"); 35 if (ret) 36 goto cleanup; 37 38 b = mremap(a, page_size, page_size, MREMAP_MAYMOVE | MREMAP_FIXED, 39 target); 40 41 if (b != MAP_FAILED) { 42 do_readback(b, page_size, "remapped"); 43 a = b; 44 } else { 45 tst_res(TINFO|TERRNO, "mremap(MAYMOVE|FIXED) disallowed"); 46 } 47 48cleanup: 49 SAFE_MUNMAP(a, page_size); 50 return ret; 51} 52 53static void run_test(void) 54{ 55 void *p; 56 int ret; 57 58 fd = tst_creat_unlinked(MNTPOINT, 0); 59 p = SAFE_MMAP(NULL, 3*hpage_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); 60 61 SAFE_MUNMAP(p, hpage_size); 62 63 SAFE_MUNMAP(p + 2*hpage_size, hpage_size); 64 65 p = p + hpage_size; 66 67 tst_res(TINFO, "Hugepage mapping at %p", p); 68 69 ret = do_readback(p, hpage_size, "base hugepage"); 70 if (ret) 71 goto cleanup; 72 73 ret = do_remap(p - page_size); 74 if (ret) 75 goto cleanup; 76 77 ret = do_remap(p + hpage_size); 78 if (ret == 0) 79 tst_res(TPASS, "Successfully tested mremap normal near hpage mapping"); 80 81cleanup: 82 SAFE_MUNMAP(p, hpage_size); 83 SAFE_CLOSE(fd); 84} 85 86static void setup(void) 87{ 88 hpage_size = tst_get_hugepage_size(); 89 page_size = getpagesize(); 90} 91 92static void cleanup(void) 93{ 94 if (fd >= 0) 95 SAFE_CLOSE(fd); 96} 97 98static struct tst_test test = { 99 .needs_root = 1, 100 .mntpoint = MNTPOINT, 101 .needs_hugetlbfs = 1, 102 .needs_tmpdir = 1, 103 .setup = setup, 104 .cleanup = cleanup, 105 .test_all = run_test, 106 .hugepages = {3, TST_NEEDS}, 107}; 108