• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
23 static int fd = -1;
24 static long hpage_size, page_size;
25 
do_remap(void * target)26 static 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 
48 cleanup:
49 	SAFE_MUNMAP(a, page_size);
50 	return ret;
51 }
52 
run_test(void)53 static 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 
81 cleanup:
82 	SAFE_MUNMAP(p, hpage_size);
83 	SAFE_CLOSE(fd);
84 }
85 
setup(void)86 static void setup(void)
87 {
88 	hpage_size = tst_get_hugepage_size();
89 	page_size = getpagesize();
90 }
91 
cleanup(void)92 static void cleanup(void)
93 {
94 	if (fd >= 0)
95 		SAFE_CLOSE(fd);
96 }
97 
98 static 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