master
c 50 lines 1.31 KB
Raw
1 /*
2 * Utility function to get the minimum mmap address.
3 * SPDX-License-Identifier: GPL-2.0-or-later
4 */
5
6 #include "qemu/osdep.h"
7 #include "user/mmap-min-addr.h"
8 #ifdef __FreeBSD__
9 #include <sys/sysctl.h>
10 #include <sys/user.h>
11 #endif
12
13 uintptr_t mmap_min_addr;
14
15 static void __attribute__((constructor)) init(void)
16 {
17 #ifdef __linux__
18 /*
19 * We prefer to not make NULL pointers accessible to QEMU.
20 * If something goes wrong below, fall back to 1 page.
21 */
22 size_t min_addr = qemu_real_host_page_size();
23 /*
24 * Read in mmap_min_addr kernel parameter. This value is used
25 * When loading the ELF image to determine whether guest_base
26 * is needed. It is also used in mmap_find_vma.
27 */
28 FILE *fp = fopen("/proc/sys/vm/mmap_min_addr", "r");
29
30 if (fp) {
31 unsigned long tmp;
32 if (fscanf(fp, "%lu", &tmp) == 1 && tmp != 0) {
33 min_addr = MAX(min_addr, tmp);
34 }
35 fclose(fp);
36 }
37 mmap_min_addr = min_addr;
38 #elif defined(__FreeBSD__)
39 int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_VM_LAYOUT, getpid() };
40 struct kinfo_vm_layout info;
41 size_t info_len = sizeof(info);
42
43 mmap_min_addr =
44 (sysctl(mib, ARRAY_SIZE(mib), &info, &info_len, NULL, 0) < 0
45 ? qemu_real_host_page_size()
46 : info.kvm_min_user_addr);
47 #else
48 # error
49 #endif
50 }