1 // SPDX-License-Identifier: GPL-2.0
4 * Test that MAP_FIXED_NOREPLACE works.
6 * Copyright 2018, Jann Horn <jannh@google.com>
7 * Copyright 2018, Michael Ellerman, IBM Corporation.
15 #include "../kselftest.h"
17 static void dump_maps(void)
21 snprintf(cmd
, sizeof(cmd
), "cat /proc/%d/maps", getpid());
25 static unsigned long find_base_addr(unsigned long size
)
30 flags
= MAP_PRIVATE
| MAP_ANONYMOUS
;
31 addr
= mmap(NULL
, size
, PROT_NONE
, flags
, -1, 0);
32 if (addr
== MAP_FAILED
)
33 ksft_exit_fail_msg("Error: couldn't map the space we need for the test\n");
35 if (munmap(addr
, size
) != 0)
36 ksft_exit_fail_msg("Error: munmap failed\n");
38 return (unsigned long)addr
;
43 unsigned long base_addr
;
44 unsigned long flags
, addr
, size
, page_size
;
50 page_size
= sysconf(_SC_PAGE_SIZE
);
52 /* let's find a base addr that is free before we start the tests */
54 base_addr
= find_base_addr(size
);
56 flags
= MAP_PRIVATE
| MAP_ANONYMOUS
| MAP_FIXED_NOREPLACE
;
58 /* Check we can map all the areas we need below */
61 p
= mmap((void *)addr
, size
, PROT_NONE
, flags
, -1, 0);
62 if (p
== MAP_FAILED
) {
64 ksft_exit_fail_msg("Error: couldn't map the space we need for the test\n");
66 if (munmap((void *)addr
, 5 * page_size
) != 0) {
68 ksft_exit_fail_msg("Error: munmap failed!?\n");
70 ksft_print_msg("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr
, addr
+ size
, p
);
71 ksft_test_result_pass("mmap() 5*PAGE_SIZE at base\n");
73 addr
= base_addr
+ page_size
;
75 p
= mmap((void *)addr
, size
, PROT_NONE
, flags
, -1, 0);
76 if (p
== MAP_FAILED
) {
78 ksft_exit_fail_msg("Error: first mmap() failed unexpectedly\n");
80 ksft_print_msg("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr
, addr
+ size
, p
);
81 ksft_test_result_pass("mmap() 3*PAGE_SIZE at base+PAGE_SIZE\n");
84 * Exact same mapping again:
93 p
= mmap((void *)addr
, size
, PROT_NONE
, flags
, -1, 0);
94 if (p
!= MAP_FAILED
) {
96 ksft_exit_fail_msg("Error:1: mmap() succeeded when it shouldn't have\n");
98 ksft_print_msg("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr
, addr
+ size
, p
);
99 ksft_test_result_pass("mmap() 5*PAGE_SIZE at base\n");
102 * Second mapping contained within first:
110 addr
= base_addr
+ (2 * page_size
);
112 p
= mmap((void *)addr
, size
, PROT_NONE
, flags
, -1, 0);
113 if (p
!= MAP_FAILED
) {
115 ksft_exit_fail_msg("Error:2: mmap() succeeded when it shouldn't have\n");
117 ksft_print_msg("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr
, addr
+ size
, p
);
118 ksft_test_result_pass("mmap() 2*PAGE_SIZE at base+PAGE_SIZE\n");
121 * Overlap end of existing mapping:
128 addr
= base_addr
+ (3 * page_size
);
129 size
= 2 * page_size
;
130 p
= mmap((void *)addr
, size
, PROT_NONE
, flags
, -1, 0);
131 if (p
!= MAP_FAILED
) {
133 ksft_exit_fail_msg("Error:3: mmap() succeeded when it shouldn't have\n");
135 ksft_print_msg("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr
, addr
+ size
, p
);
136 ksft_test_result_pass("mmap() 2*PAGE_SIZE at base+(3*PAGE_SIZE)\n");
139 * Overlap start of existing mapping:
147 size
= 2 * page_size
;
148 p
= mmap((void *)addr
, size
, PROT_NONE
, flags
, -1, 0);
149 if (p
!= MAP_FAILED
) {
151 ksft_exit_fail_msg("Error:4: mmap() succeeded when it shouldn't have\n");
153 ksft_print_msg("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr
, addr
+ size
, p
);
154 ksft_test_result_pass("mmap() 2*PAGE_SIZE bytes at base\n");
157 * Adjacent to start of existing mapping:
166 p
= mmap((void *)addr
, size
, PROT_NONE
, flags
, -1, 0);
167 if (p
== MAP_FAILED
) {
169 ksft_exit_fail_msg("Error:5: mmap() failed when it shouldn't have\n");
171 ksft_print_msg("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr
, addr
+ size
, p
);
172 ksft_test_result_pass("mmap() PAGE_SIZE at base\n");
175 * Adjacent to end of existing mapping:
182 addr
= base_addr
+ (4 * page_size
);
184 p
= mmap((void *)addr
, size
, PROT_NONE
, flags
, -1, 0);
185 if (p
== MAP_FAILED
) {
187 ksft_exit_fail_msg("Error:6: mmap() failed when it shouldn't have\n");
189 ksft_print_msg("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr
, addr
+ size
, p
);
190 ksft_test_result_pass("mmap() PAGE_SIZE at base+(4*PAGE_SIZE)\n");
193 size
= 5 * page_size
;
194 if (munmap((void *)addr
, size
) != 0) {
196 ksft_exit_fail_msg("Error: munmap failed!?\n");
198 ksft_test_result_pass("Base Address unmap() successful\n");