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 } 178