@samitouri / QOSamiQemu / commits / c56da35d5d

common-user: Move mmap_min_addr from linux-user

Introduce user/mmap-min-addr.h. Initialize the variable from a constructor instead of main. Reviewed-by: Helge Deller <deller@gmx.de> Reviewed-by: Warner Losh <imp@bsdimp.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Richard Henderson committed May 29, 2026 at 18:12 UTC c56da35d5d963d338158bf7e061cc96c67fafd7f
7 files changed +55 -31
common-user/meson.build
+1
@@ -5,6 +5,7 @@ endif
5 common_user_inc += include_directories('host/' / host_arch)
6
7 user_ss.add(files(
8 + 'mmap-min-addr.c',
9 'safe-syscall.S',
10 'safe-syscall-error.c',
11 ))
common-user/mmap-min-addr.c new
+37
@@ -0,0 +1,37 @@
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 +
9 +uintptr_t mmap_min_addr;
10 +
11 +static void __attribute__((constructor)) init(void)
12 +{
13 +#ifdef __linux__
14 + /*
15 + * We prefer to not make NULL pointers accessible to QEMU.
16 + * If something goes wrong below, fall back to 1 page.
17 + */
18 + size_t min_addr = qemu_real_host_page_size();
19 + /*
20 + * Read in mmap_min_addr kernel parameter. This value is used
21 + * When loading the ELF image to determine whether guest_base
22 + * is needed. It is also used in mmap_find_vma.
23 + */
24 + FILE *fp = fopen("/proc/sys/vm/mmap_min_addr", "r");
25 +
26 + if (fp) {
27 + unsigned long tmp;
28 + if (fscanf(fp, "%lu", &tmp) == 1 && tmp != 0) {
29 + min_addr = MAX(min_addr, tmp);
30 + }
31 + fclose(fp);
32 + }
33 + mmap_min_addr = min_addr;
34 +#else
35 +# error
36 +#endif
37 +}
include/user/mmap-min-addr.h new
+12
@@ -0,0 +1,12 @@
1 +/* SPDX-License-Identifier: GPL-2.0-or-later */
2 +
3 +#ifndef USER_MMAP_MIN_ADDR_H
4 +#define USER_MMAP_MIN_ADDR_H
5 +
6 +#ifndef CONFIG_USER_ONLY
7 +#error Cannot include this header from system emulation
8 +#endif
9 +
10 +extern uintptr_t mmap_min_addr;
11 +
12 +#endif
linux-user/elfload.c
+1
@@ -14,6 +14,7 @@
14 #include "exec/translation-block.h"
15 #include "exec/tswap.h"
16 #include "user/guest-base.h"
17 +#include "user/mmap-min-addr.h"
18 #include "user-internals.h"
19 #include "signal-common.h"
20 #include "loader.h"
linux-user/main.c
+3 -30
@@ -39,6 +39,7 @@
39 #include "qemu/module.h"
40 #include "qemu/plugin.h"
41 #include "user/guest-base.h"
42 +#include "user/mmap-min-addr.h"
43 #include "user/page-protection.h"
44 #include "exec/gdbstub.h"
45 #include "gdbstub/user.h"
@@ -78,7 +79,6 @@ static envlist_t *envlist;
79 static const char *cpu_model;
80 static const char *cpu_type;
81 static const char *seed_optarg;
81 -unsigned long mmap_min_addr;
82 uintptr_t guest_base;
83 bool have_guest_base;
84
@@ -914,35 +914,8 @@ int main(int argc, char **argv, char **envp)
914 target_environ = envlist_to_environ(envlist, NULL);
915 envlist_free(envlist);
916
917 - /*
918 - * Read in mmap_min_addr kernel parameter. This value is used
919 - * When loading the ELF image to determine whether guest_base
920 - * is needed. It is also used in mmap_find_vma.
921 - */
922 - {
923 - FILE *fp;
924 -
925 - if ((fp = fopen("/proc/sys/vm/mmap_min_addr", "r")) != NULL) {
926 - unsigned long tmp;
927 - if (fscanf(fp, "%lu", &tmp) == 1 && tmp != 0) {
928 - mmap_min_addr = MAX(tmp, host_page_size);
929 - qemu_log_mask(CPU_LOG_PAGE, "host mmap_min_addr=0x%lx\n",
930 - mmap_min_addr);
931 - }
932 - fclose(fp);
933 - }
934 - }
935 -
936 - /*
937 - * We prefer to not make NULL pointers accessible to QEMU.
938 - * If we're in a chroot with no /proc, fall back to 1 page.
939 - */
940 - if (mmap_min_addr == 0) {
941 - mmap_min_addr = host_page_size;
942 - qemu_log_mask(CPU_LOG_PAGE,
943 - "host mmap_min_addr=0x%lx (fallback)\n",
944 - mmap_min_addr);
945 - }
917 + qemu_log_mask(CPU_LOG_PAGE, "host mmap_min_addr=0x%" PRIxPTR "\n",
918 + mmap_min_addr);
919
920 /*
921 * Prepare copy of argv vector for target.
linux-user/mmap.c
+1
@@ -24,6 +24,7 @@
24 #include "exec/mmap-lock.h"
25 #include "qemu.h"
26 #include "user/page-protection.h"
27 +#include "user/mmap-min-addr.h"
28 #include "user-internals.h"
29 #include "user-mmap.h"
30 #include "target_mman.h"
linux-user/user-internals.h
-1
@@ -29,7 +29,6 @@ void init_task_state(TaskState *ts);
29 void task_settid(TaskState *);
30 void stop_all_tasks(void);
31 extern const char *qemu_uname_release;
32 -extern unsigned long mmap_min_addr;
32
33 typedef struct IOCTLEntry IOCTLEntry;
34