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