treewide: remove redundant IS_ERR() before error code check
[linux/fpc-iii.git] / tools / testing / selftests / vm / va_128TBswitch.c
blob83acdff26a13520f6c4b0055e3b2116979d85630
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
4 * Authors: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
5 * Authors: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
6 */
8 #include <stdio.h>
9 #include <sys/mman.h>
10 #include <string.h>
12 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
14 #ifdef __powerpc64__
15 #define PAGE_SIZE (64 << 10)
17 * This will work with 16M and 2M hugepage size
19 #define HUGETLB_SIZE (16 << 20)
20 #else
21 #define PAGE_SIZE (4 << 10)
22 #define HUGETLB_SIZE (2 << 20)
23 #endif
26 * >= 128TB is the hint addr value we used to select
27 * large address space.
29 #define ADDR_SWITCH_HINT (1UL << 47)
30 #define LOW_ADDR ((void *) (1UL << 30))
31 #define HIGH_ADDR ((void *) (1UL << 48))
33 struct testcase {
34 void *addr;
35 unsigned long size;
36 unsigned long flags;
37 const char *msg;
38 unsigned int low_addr_required:1;
39 unsigned int keep_mapped:1;
42 static struct testcase testcases[] = {
45 * If stack is moved, we could possibly allocate
46 * this at the requested address.
48 .addr = ((void *)(ADDR_SWITCH_HINT - PAGE_SIZE)),
49 .size = PAGE_SIZE,
50 .flags = MAP_PRIVATE | MAP_ANONYMOUS,
51 .msg = "mmap(ADDR_SWITCH_HINT - PAGE_SIZE, PAGE_SIZE)",
52 .low_addr_required = 1,
56 * We should never allocate at the requested address or above it
57 * The len cross the 128TB boundary. Without MAP_FIXED
58 * we will always search in the lower address space.
60 .addr = ((void *)(ADDR_SWITCH_HINT - PAGE_SIZE)),
61 .size = 2 * PAGE_SIZE,
62 .flags = MAP_PRIVATE | MAP_ANONYMOUS,
63 .msg = "mmap(ADDR_SWITCH_HINT - PAGE_SIZE, (2 * PAGE_SIZE))",
64 .low_addr_required = 1,
68 * Exact mapping at 128TB, the area is free we should get that
69 * even without MAP_FIXED.
71 .addr = ((void *)(ADDR_SWITCH_HINT)),
72 .size = PAGE_SIZE,
73 .flags = MAP_PRIVATE | MAP_ANONYMOUS,
74 .msg = "mmap(ADDR_SWITCH_HINT, PAGE_SIZE)",
75 .keep_mapped = 1,
78 .addr = (void *)(ADDR_SWITCH_HINT),
79 .size = 2 * PAGE_SIZE,
80 .flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
81 .msg = "mmap(ADDR_SWITCH_HINT, 2 * PAGE_SIZE, MAP_FIXED)",
84 .addr = NULL,
85 .size = 2 * PAGE_SIZE,
86 .flags = MAP_PRIVATE | MAP_ANONYMOUS,
87 .msg = "mmap(NULL)",
88 .low_addr_required = 1,
91 .addr = LOW_ADDR,
92 .size = 2 * PAGE_SIZE,
93 .flags = MAP_PRIVATE | MAP_ANONYMOUS,
94 .msg = "mmap(LOW_ADDR)",
95 .low_addr_required = 1,
98 .addr = HIGH_ADDR,
99 .size = 2 * PAGE_SIZE,
100 .flags = MAP_PRIVATE | MAP_ANONYMOUS,
101 .msg = "mmap(HIGH_ADDR)",
102 .keep_mapped = 1,
105 .addr = HIGH_ADDR,
106 .size = 2 * PAGE_SIZE,
107 .flags = MAP_PRIVATE | MAP_ANONYMOUS,
108 .msg = "mmap(HIGH_ADDR) again",
109 .keep_mapped = 1,
112 .addr = HIGH_ADDR,
113 .size = 2 * PAGE_SIZE,
114 .flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
115 .msg = "mmap(HIGH_ADDR, MAP_FIXED)",
118 .addr = (void *) -1,
119 .size = 2 * PAGE_SIZE,
120 .flags = MAP_PRIVATE | MAP_ANONYMOUS,
121 .msg = "mmap(-1)",
122 .keep_mapped = 1,
125 .addr = (void *) -1,
126 .size = 2 * PAGE_SIZE,
127 .flags = MAP_PRIVATE | MAP_ANONYMOUS,
128 .msg = "mmap(-1) again",
131 .addr = ((void *)(ADDR_SWITCH_HINT - PAGE_SIZE)),
132 .size = PAGE_SIZE,
133 .flags = MAP_PRIVATE | MAP_ANONYMOUS,
134 .msg = "mmap(ADDR_SWITCH_HINT - PAGE_SIZE, PAGE_SIZE)",
135 .low_addr_required = 1,
138 .addr = (void *)(ADDR_SWITCH_HINT - PAGE_SIZE),
139 .size = 2 * PAGE_SIZE,
140 .flags = MAP_PRIVATE | MAP_ANONYMOUS,
141 .msg = "mmap(ADDR_SWITCH_HINT - PAGE_SIZE, 2 * PAGE_SIZE)",
142 .low_addr_required = 1,
143 .keep_mapped = 1,
146 .addr = (void *)(ADDR_SWITCH_HINT - PAGE_SIZE / 2),
147 .size = 2 * PAGE_SIZE,
148 .flags = MAP_PRIVATE | MAP_ANONYMOUS,
149 .msg = "mmap(ADDR_SWITCH_HINT - PAGE_SIZE/2 , 2 * PAGE_SIZE)",
150 .low_addr_required = 1,
151 .keep_mapped = 1,
154 .addr = ((void *)(ADDR_SWITCH_HINT)),
155 .size = PAGE_SIZE,
156 .flags = MAP_PRIVATE | MAP_ANONYMOUS,
157 .msg = "mmap(ADDR_SWITCH_HINT, PAGE_SIZE)",
160 .addr = (void *)(ADDR_SWITCH_HINT),
161 .size = 2 * PAGE_SIZE,
162 .flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
163 .msg = "mmap(ADDR_SWITCH_HINT, 2 * PAGE_SIZE, MAP_FIXED)",
167 static struct testcase hugetlb_testcases[] = {
169 .addr = NULL,
170 .size = HUGETLB_SIZE,
171 .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
172 .msg = "mmap(NULL, MAP_HUGETLB)",
173 .low_addr_required = 1,
176 .addr = LOW_ADDR,
177 .size = HUGETLB_SIZE,
178 .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
179 .msg = "mmap(LOW_ADDR, MAP_HUGETLB)",
180 .low_addr_required = 1,
183 .addr = HIGH_ADDR,
184 .size = HUGETLB_SIZE,
185 .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
186 .msg = "mmap(HIGH_ADDR, MAP_HUGETLB)",
187 .keep_mapped = 1,
190 .addr = HIGH_ADDR,
191 .size = HUGETLB_SIZE,
192 .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
193 .msg = "mmap(HIGH_ADDR, MAP_HUGETLB) again",
194 .keep_mapped = 1,
197 .addr = HIGH_ADDR,
198 .size = HUGETLB_SIZE,
199 .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
200 .msg = "mmap(HIGH_ADDR, MAP_FIXED | MAP_HUGETLB)",
203 .addr = (void *) -1,
204 .size = HUGETLB_SIZE,
205 .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
206 .msg = "mmap(-1, MAP_HUGETLB)",
207 .keep_mapped = 1,
210 .addr = (void *) -1,
211 .size = HUGETLB_SIZE,
212 .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
213 .msg = "mmap(-1, MAP_HUGETLB) again",
216 .addr = (void *)(ADDR_SWITCH_HINT - PAGE_SIZE),
217 .size = 2 * HUGETLB_SIZE,
218 .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
219 .msg = "mmap(ADDR_SWITCH_HINT - PAGE_SIZE, 2*HUGETLB_SIZE, MAP_HUGETLB)",
220 .low_addr_required = 1,
221 .keep_mapped = 1,
224 .addr = (void *)(ADDR_SWITCH_HINT),
225 .size = 2 * HUGETLB_SIZE,
226 .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
227 .msg = "mmap(ADDR_SWITCH_HINT , 2*HUGETLB_SIZE, MAP_FIXED | MAP_HUGETLB)",
231 static int run_test(struct testcase *test, int count)
233 void *p;
234 int i, ret = 0;
236 for (i = 0; i < count; i++) {
237 struct testcase *t = test + i;
239 p = mmap(t->addr, t->size, PROT_READ | PROT_WRITE, t->flags, -1, 0);
241 printf("%s: %p - ", t->msg, p);
243 if (p == MAP_FAILED) {
244 printf("FAILED\n");
245 ret = 1;
246 continue;
249 if (t->low_addr_required && p >= (void *)(ADDR_SWITCH_HINT)) {
250 printf("FAILED\n");
251 ret = 1;
252 } else {
254 * Do a dereference of the address returned so that we catch
255 * bugs in page fault handling
257 memset(p, 0, t->size);
258 printf("OK\n");
260 if (!t->keep_mapped)
261 munmap(p, t->size);
264 return ret;
267 static int supported_arch(void)
269 #if defined(__powerpc64__)
270 return 1;
271 #elif defined(__x86_64__)
272 return 1;
273 #else
274 return 0;
275 #endif
278 int main(int argc, char **argv)
280 int ret;
282 if (!supported_arch())
283 return 0;
285 ret = run_test(testcases, ARRAY_SIZE(testcases));
286 if (argc == 2 && !strcmp(argv[1], "--run-hugetlb"))
287 ret = run_test(hugetlb_testcases, ARRAY_SIZE(hugetlb_testcases));
288 return ret;