Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/mm/uffd: remove static address usage in shmem_allocate_area()

The current shmem_allocate_area() implementation uses a hardcoded virtual
base address (BASE_PMD_ADDR) as a hint for mmap() when creating
shmem-backed test areas. This approach is fragile and may fail on systems
with ASLR or different virtual memory layouts, where the chosen address is
unavailable.

Replace the static base address with a dynamically reserved address range
obtained via mmap(NULL, ..., PROT_NONE). The memfd-backed areas and their
alias are then mapped into that reserved region using MAP_FIXED,
preserving the original layout and aliasing semantics while avoiding
collisions with unrelated mappings.

This change improves robustness and portability of the test suite without
altering its behavior or coverage.

[mehdi.benhadjkhelifa@gmail.com: make cleanup code more clear, per Mike]
Link: https://lkml.kernel.org/r/20251113142050.108638-1-mehdi.benhadjkhelifa@gmail.com
Link: https://lkml.kernel.org/r/20251111205739.420009-1-mehdi.benhadjkhelifa@gmail.com
Signed-off-by: Mehdi Ben Hadj Khelifa <mehdi.benhadjkhelifa@gmail.com>
Suggested-by: Mike Rapoport <rppt@kernel.org>
Reviewed-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Cc: David Hildenbrand <david@redhat.com>
Cc: David Hunter <david.hunter.linux@gmail.com>
Cc: Liam Howlett <liam.howlett@oracle.com>
Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Peter Xu <peterx@redhat.com>
Cc: Shuah Khan <shuah@kernel.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Mehdi Ben Hadj Khelifa and committed by
Andrew Morton
1ec5d581 603f67eb

+15 -9
+15 -9
tools/testing/selftests/mm/uffd-common.c
··· 10 10 uffd_test_ops_t *uffd_test_ops; 11 11 uffd_test_case_ops_t *uffd_test_case_ops; 12 12 13 - #define BASE_PMD_ADDR ((void *)(1UL << 30)) 14 13 15 14 /* pthread_mutex_t starts at page offset 0 */ 16 15 pthread_mutex_t *area_mutex(char *area, unsigned long nr, uffd_global_test_opts_t *gopts) ··· 141 142 unsigned long offset = is_src ? 0 : bytes; 142 143 char *p = NULL, *p_alias = NULL; 143 144 int mem_fd = uffd_mem_fd_create(bytes * 2, false); 145 + size_t region_size = bytes * 2 + hpage_size; 144 146 145 - /* TODO: clean this up. Use a static addr is ugly */ 146 - p = BASE_PMD_ADDR; 147 - if (!is_src) 148 - /* src map + alias + interleaved hpages */ 149 - p += 2 * (bytes + hpage_size); 147 + void *reserve = mmap(NULL, region_size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, 148 + -1, 0); 149 + if (reserve == MAP_FAILED) { 150 + close(mem_fd); 151 + return -errno; 152 + } 153 + 154 + p = reserve; 150 155 p_alias = p; 151 156 p_alias += bytes; 152 157 p_alias += hpage_size; /* Prevent src/dst VMA merge */ 153 158 154 - *alloc_area = mmap(p, bytes, PROT_READ | PROT_WRITE, MAP_SHARED, 159 + *alloc_area = mmap(p, bytes, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED, 155 160 mem_fd, offset); 156 161 if (*alloc_area == MAP_FAILED) { 157 162 *alloc_area = NULL; 163 + munmap(reserve, region_size); 164 + close(mem_fd); 158 165 return -errno; 159 166 } 160 167 if (*alloc_area != p) 161 168 err("mmap of memfd failed at %p", p); 162 169 163 - area_alias = mmap(p_alias, bytes, PROT_READ | PROT_WRITE, MAP_SHARED, 170 + area_alias = mmap(p_alias, bytes, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED, 164 171 mem_fd, offset); 165 172 if (area_alias == MAP_FAILED) { 166 - munmap(*alloc_area, bytes); 167 173 *alloc_area = NULL; 174 + munmap(reserve, region_size); 175 + close(mem_fd); 168 176 return -errno; 169 177 } 170 178 if (area_alias != p_alias)