Commit | Line | Data |
---|---|---|
97f404ad KS |
1 | #include <stdio.h> |
2 | #include <sys/mman.h> | |
3 | ||
4 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) | |
5 | ||
6 | #define PAGE_SIZE 4096 | |
7 | #define LOW_ADDR ((void *) (1UL << 30)) | |
8 | #define HIGH_ADDR ((void *) (1UL << 50)) | |
9 | ||
10 | struct testcase { | |
11 | void *addr; | |
12 | unsigned long size; | |
13 | unsigned long flags; | |
14 | const char *msg; | |
15 | unsigned int low_addr_required:1; | |
16 | unsigned int keep_mapped:1; | |
17 | }; | |
18 | ||
19 | static struct testcase testcases[] = { | |
20 | { | |
21 | .addr = NULL, | |
22 | .size = 2 * PAGE_SIZE, | |
23 | .flags = MAP_PRIVATE | MAP_ANONYMOUS, | |
24 | .msg = "mmap(NULL)", | |
25 | .low_addr_required = 1, | |
26 | }, | |
27 | { | |
28 | .addr = LOW_ADDR, | |
29 | .size = 2 * PAGE_SIZE, | |
30 | .flags = MAP_PRIVATE | MAP_ANONYMOUS, | |
31 | .msg = "mmap(LOW_ADDR)", | |
32 | .low_addr_required = 1, | |
33 | }, | |
34 | { | |
35 | .addr = HIGH_ADDR, | |
36 | .size = 2 * PAGE_SIZE, | |
37 | .flags = MAP_PRIVATE | MAP_ANONYMOUS, | |
38 | .msg = "mmap(HIGH_ADDR)", | |
39 | .keep_mapped = 1, | |
40 | }, | |
41 | { | |
42 | .addr = HIGH_ADDR, | |
43 | .size = 2 * PAGE_SIZE, | |
44 | .flags = MAP_PRIVATE | MAP_ANONYMOUS, | |
45 | .msg = "mmap(HIGH_ADDR) again", | |
46 | .keep_mapped = 1, | |
47 | }, | |
48 | { | |
49 | .addr = HIGH_ADDR, | |
50 | .size = 2 * PAGE_SIZE, | |
51 | .flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, | |
52 | .msg = "mmap(HIGH_ADDR, MAP_FIXED)", | |
53 | }, | |
54 | { | |
55 | .addr = (void*) -1, | |
56 | .size = 2 * PAGE_SIZE, | |
57 | .flags = MAP_PRIVATE | MAP_ANONYMOUS, | |
58 | .msg = "mmap(-1)", | |
59 | .keep_mapped = 1, | |
60 | }, | |
61 | { | |
62 | .addr = (void*) -1, | |
63 | .size = 2 * PAGE_SIZE, | |
64 | .flags = MAP_PRIVATE | MAP_ANONYMOUS, | |
65 | .msg = "mmap(-1) again", | |
66 | }, | |
67 | { | |
68 | .addr = (void *)((1UL << 47) - PAGE_SIZE), | |
69 | .size = 2 * PAGE_SIZE, | |
70 | .flags = MAP_PRIVATE | MAP_ANONYMOUS, | |
71 | .msg = "mmap((1UL << 47), 2 * PAGE_SIZE)", | |
72 | .low_addr_required = 1, | |
73 | .keep_mapped = 1, | |
74 | }, | |
75 | { | |
76 | .addr = (void *)((1UL << 47) - PAGE_SIZE / 2), | |
77 | .size = 2 * PAGE_SIZE, | |
78 | .flags = MAP_PRIVATE | MAP_ANONYMOUS, | |
79 | .msg = "mmap((1UL << 47), 2 * PAGE_SIZE / 2)", | |
80 | .low_addr_required = 1, | |
81 | .keep_mapped = 1, | |
82 | }, | |
83 | { | |
84 | .addr = (void *)((1UL << 47) - PAGE_SIZE), | |
85 | .size = 2 * PAGE_SIZE, | |
86 | .flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, | |
87 | .msg = "mmap((1UL << 47) - PAGE_SIZE, 2 * PAGE_SIZE, MAP_FIXED)", | |
88 | }, | |
89 | { | |
90 | .addr = NULL, | |
91 | .size = 2UL << 20, | |
92 | .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS, | |
93 | .msg = "mmap(NULL, MAP_HUGETLB)", | |
94 | .low_addr_required = 1, | |
95 | }, | |
96 | { | |
97 | .addr = LOW_ADDR, | |
98 | .size = 2UL << 20, | |
99 | .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS, | |
100 | .msg = "mmap(LOW_ADDR, MAP_HUGETLB)", | |
101 | .low_addr_required = 1, | |
102 | }, | |
103 | { | |
104 | .addr = HIGH_ADDR, | |
105 | .size = 2UL << 20, | |
106 | .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS, | |
107 | .msg = "mmap(HIGH_ADDR, MAP_HUGETLB)", | |
108 | .keep_mapped = 1, | |
109 | }, | |
110 | { | |
111 | .addr = HIGH_ADDR, | |
112 | .size = 2UL << 20, | |
113 | .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS, | |
114 | .msg = "mmap(HIGH_ADDR, MAP_HUGETLB) again", | |
115 | .keep_mapped = 1, | |
116 | }, | |
117 | { | |
118 | .addr = HIGH_ADDR, | |
119 | .size = 2UL << 20, | |
120 | .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, | |
121 | .msg = "mmap(HIGH_ADDR, MAP_FIXED | MAP_HUGETLB)", | |
122 | }, | |
123 | { | |
124 | .addr = (void*) -1, | |
125 | .size = 2UL << 20, | |
126 | .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS, | |
127 | .msg = "mmap(-1, MAP_HUGETLB)", | |
128 | .keep_mapped = 1, | |
129 | }, | |
130 | { | |
131 | .addr = (void*) -1, | |
132 | .size = 2UL << 20, | |
133 | .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS, | |
134 | .msg = "mmap(-1, MAP_HUGETLB) again", | |
135 | }, | |
136 | { | |
137 | .addr = (void *)((1UL << 47) - PAGE_SIZE), | |
138 | .size = 4UL << 20, | |
139 | .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS, | |
140 | .msg = "mmap((1UL << 47), 4UL << 20, MAP_HUGETLB)", | |
141 | .low_addr_required = 1, | |
142 | .keep_mapped = 1, | |
143 | }, | |
144 | { | |
145 | .addr = (void *)((1UL << 47) - (2UL << 20)), | |
146 | .size = 4UL << 20, | |
147 | .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, | |
148 | .msg = "mmap((1UL << 47) - (2UL << 20), 4UL << 20, MAP_FIXED | MAP_HUGETLB)", | |
149 | }, | |
150 | }; | |
151 | ||
152 | int main(int argc, char **argv) | |
153 | { | |
154 | int i; | |
155 | void *p; | |
156 | ||
157 | for (i = 0; i < ARRAY_SIZE(testcases); i++) { | |
158 | struct testcase *t = testcases + i; | |
159 | ||
160 | p = mmap(t->addr, t->size, PROT_NONE, t->flags, -1, 0); | |
161 | ||
162 | printf("%s: %p - ", t->msg, p); | |
163 | ||
164 | if (p == MAP_FAILED) { | |
165 | printf("FAILED\n"); | |
166 | continue; | |
167 | } | |
168 | ||
169 | if (t->low_addr_required && p >= (void *)(1UL << 47)) | |
170 | printf("FAILED\n"); | |
171 | else | |
172 | printf("OK\n"); | |
173 | if (!t->keep_mapped) | |
174 | munmap(p, t->size); | |
175 | } | |
176 | return 0; | |
177 | } |