xtensa: fix high memory/reserved memory collision
[cris-mirror.git] / tools / testing / selftests / vm / va_128TBswitch.c
blobe7fe734c374f16fd5653846ab1939865ddf03ff6
1 /*
3 * Authors: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
4 * Authors: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License, version 2, as
8 * published by the Free Software Foundation.
10 * This program is distributed in the hope that it would be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 #include <stdio.h>
17 #include <sys/mman.h>
18 #include <string.h>
20 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
22 #ifdef __powerpc64__
23 #define PAGE_SIZE (64 << 10)
25 * This will work with 16M and 2M hugepage size
27 #define HUGETLB_SIZE (16 << 20)
28 #else
29 #define PAGE_SIZE (4 << 10)
30 #define HUGETLB_SIZE (2 << 20)
31 #endif
34 * >= 128TB is the hint addr value we used to select
35 * large address space.
37 #define ADDR_SWITCH_HINT (1UL << 47)
38 #define LOW_ADDR ((void *) (1UL << 30))
39 #define HIGH_ADDR ((void *) (1UL << 48))
41 struct testcase {
42 void *addr;
43 unsigned long size;
44 unsigned long flags;
45 const char *msg;
46 unsigned int low_addr_required:1;
47 unsigned int keep_mapped:1;
50 static struct testcase testcases[] = {
53 * If stack is moved, we could possibly allocate
54 * this at the requested address.
56 .addr = ((void *)(ADDR_SWITCH_HINT - PAGE_SIZE)),
57 .size = PAGE_SIZE,
58 .flags = MAP_PRIVATE | MAP_ANONYMOUS,
59 .msg = "mmap(ADDR_SWITCH_HINT - PAGE_SIZE, PAGE_SIZE)",
60 .low_addr_required = 1,
64 * We should never allocate at the requested address or above it
65 * The len cross the 128TB boundary. Without MAP_FIXED
66 * we will always search in the lower address space.
68 .addr = ((void *)(ADDR_SWITCH_HINT - PAGE_SIZE)),
69 .size = 2 * PAGE_SIZE,
70 .flags = MAP_PRIVATE | MAP_ANONYMOUS,
71 .msg = "mmap(ADDR_SWITCH_HINT - PAGE_SIZE, (2 * PAGE_SIZE))",
72 .low_addr_required = 1,
76 * Exact mapping at 128TB, the area is free we should get that
77 * even without MAP_FIXED.
79 .addr = ((void *)(ADDR_SWITCH_HINT)),
80 .size = PAGE_SIZE,
81 .flags = MAP_PRIVATE | MAP_ANONYMOUS,
82 .msg = "mmap(ADDR_SWITCH_HINT, PAGE_SIZE)",
83 .keep_mapped = 1,
86 .addr = (void *)(ADDR_SWITCH_HINT),
87 .size = 2 * PAGE_SIZE,
88 .flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
89 .msg = "mmap(ADDR_SWITCH_HINT, 2 * PAGE_SIZE, MAP_FIXED)",
92 .addr = NULL,
93 .size = 2 * PAGE_SIZE,
94 .flags = MAP_PRIVATE | MAP_ANONYMOUS,
95 .msg = "mmap(NULL)",
96 .low_addr_required = 1,
99 .addr = LOW_ADDR,
100 .size = 2 * PAGE_SIZE,
101 .flags = MAP_PRIVATE | MAP_ANONYMOUS,
102 .msg = "mmap(LOW_ADDR)",
103 .low_addr_required = 1,
106 .addr = HIGH_ADDR,
107 .size = 2 * PAGE_SIZE,
108 .flags = MAP_PRIVATE | MAP_ANONYMOUS,
109 .msg = "mmap(HIGH_ADDR)",
110 .keep_mapped = 1,
113 .addr = HIGH_ADDR,
114 .size = 2 * PAGE_SIZE,
115 .flags = MAP_PRIVATE | MAP_ANONYMOUS,
116 .msg = "mmap(HIGH_ADDR) again",
117 .keep_mapped = 1,
120 .addr = HIGH_ADDR,
121 .size = 2 * PAGE_SIZE,
122 .flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
123 .msg = "mmap(HIGH_ADDR, MAP_FIXED)",
126 .addr = (void *) -1,
127 .size = 2 * PAGE_SIZE,
128 .flags = MAP_PRIVATE | MAP_ANONYMOUS,
129 .msg = "mmap(-1)",
130 .keep_mapped = 1,
133 .addr = (void *) -1,
134 .size = 2 * PAGE_SIZE,
135 .flags = MAP_PRIVATE | MAP_ANONYMOUS,
136 .msg = "mmap(-1) again",
139 .addr = ((void *)(ADDR_SWITCH_HINT - PAGE_SIZE)),
140 .size = PAGE_SIZE,
141 .flags = MAP_PRIVATE | MAP_ANONYMOUS,
142 .msg = "mmap(ADDR_SWITCH_HINT - PAGE_SIZE, PAGE_SIZE)",
143 .low_addr_required = 1,
146 .addr = (void *)(ADDR_SWITCH_HINT - PAGE_SIZE),
147 .size = 2 * PAGE_SIZE,
148 .flags = MAP_PRIVATE | MAP_ANONYMOUS,
149 .msg = "mmap(ADDR_SWITCH_HINT - PAGE_SIZE, 2 * PAGE_SIZE)",
150 .low_addr_required = 1,
151 .keep_mapped = 1,
154 .addr = (void *)(ADDR_SWITCH_HINT - PAGE_SIZE / 2),
155 .size = 2 * PAGE_SIZE,
156 .flags = MAP_PRIVATE | MAP_ANONYMOUS,
157 .msg = "mmap(ADDR_SWITCH_HINT - PAGE_SIZE/2 , 2 * PAGE_SIZE)",
158 .low_addr_required = 1,
159 .keep_mapped = 1,
162 .addr = ((void *)(ADDR_SWITCH_HINT)),
163 .size = PAGE_SIZE,
164 .flags = MAP_PRIVATE | MAP_ANONYMOUS,
165 .msg = "mmap(ADDR_SWITCH_HINT, PAGE_SIZE)",
168 .addr = (void *)(ADDR_SWITCH_HINT),
169 .size = 2 * PAGE_SIZE,
170 .flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
171 .msg = "mmap(ADDR_SWITCH_HINT, 2 * PAGE_SIZE, MAP_FIXED)",
175 static struct testcase hugetlb_testcases[] = {
177 .addr = NULL,
178 .size = HUGETLB_SIZE,
179 .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
180 .msg = "mmap(NULL, MAP_HUGETLB)",
181 .low_addr_required = 1,
184 .addr = LOW_ADDR,
185 .size = HUGETLB_SIZE,
186 .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
187 .msg = "mmap(LOW_ADDR, MAP_HUGETLB)",
188 .low_addr_required = 1,
191 .addr = HIGH_ADDR,
192 .size = HUGETLB_SIZE,
193 .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
194 .msg = "mmap(HIGH_ADDR, MAP_HUGETLB)",
195 .keep_mapped = 1,
198 .addr = HIGH_ADDR,
199 .size = HUGETLB_SIZE,
200 .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
201 .msg = "mmap(HIGH_ADDR, MAP_HUGETLB) again",
202 .keep_mapped = 1,
205 .addr = HIGH_ADDR,
206 .size = HUGETLB_SIZE,
207 .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
208 .msg = "mmap(HIGH_ADDR, MAP_FIXED | MAP_HUGETLB)",
211 .addr = (void *) -1,
212 .size = HUGETLB_SIZE,
213 .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
214 .msg = "mmap(-1, MAP_HUGETLB)",
215 .keep_mapped = 1,
218 .addr = (void *) -1,
219 .size = HUGETLB_SIZE,
220 .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
221 .msg = "mmap(-1, MAP_HUGETLB) again",
224 .addr = (void *)(ADDR_SWITCH_HINT - PAGE_SIZE),
225 .size = 2 * HUGETLB_SIZE,
226 .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
227 .msg = "mmap(ADDR_SWITCH_HINT - PAGE_SIZE, 2*HUGETLB_SIZE, MAP_HUGETLB)",
228 .low_addr_required = 1,
229 .keep_mapped = 1,
232 .addr = (void *)(ADDR_SWITCH_HINT),
233 .size = 2 * HUGETLB_SIZE,
234 .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
235 .msg = "mmap(ADDR_SWITCH_HINT , 2*HUGETLB_SIZE, MAP_FIXED | MAP_HUGETLB)",
239 static int run_test(struct testcase *test, int count)
241 void *p;
242 int i, ret = 0;
244 for (i = 0; i < count; i++) {
245 struct testcase *t = test + i;
247 p = mmap(t->addr, t->size, PROT_READ | PROT_WRITE, t->flags, -1, 0);
249 printf("%s: %p - ", t->msg, p);
251 if (p == MAP_FAILED) {
252 printf("FAILED\n");
253 ret = 1;
254 continue;
257 if (t->low_addr_required && p >= (void *)(ADDR_SWITCH_HINT)) {
258 printf("FAILED\n");
259 ret = 1;
260 } else {
262 * Do a dereference of the address returned so that we catch
263 * bugs in page fault handling
265 memset(p, 0, t->size);
266 printf("OK\n");
268 if (!t->keep_mapped)
269 munmap(p, t->size);
272 return ret;
275 static int supported_arch(void)
277 #if defined(__powerpc64__)
278 return 1;
279 #elif defined(__x86_64__)
280 return 1;
281 #else
282 return 0;
283 #endif
286 int main(int argc, char **argv)
288 int ret;
290 if (!supported_arch())
291 return 0;
293 ret = run_test(testcases, ARRAY_SIZE(testcases));
294 if (argc == 2 && !strcmp(argv[1], "--run-hugetlb"))
295 ret = run_test(hugetlb_testcases, ARRAY_SIZE(hugetlb_testcases));
296 return ret;