Commit c56da35d5d for qemu.org
commit c56da35d5d963d338158bf7e061cc96c67fafd7f
Author: Richard Henderson <richard.henderson@linaro.org>
Date: Fri May 29 18:12:25 2026 -0700
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>
diff --git a/common-user/meson.build b/common-user/meson.build
index ac9de5b9e3..f9e2e83f9a 100644
--- a/common-user/meson.build
+++ b/common-user/meson.build
@@ -5,6 +5,7 @@ endif
common_user_inc += include_directories('host/' / host_arch)
user_ss.add(files(
+ 'mmap-min-addr.c',
'safe-syscall.S',
'safe-syscall-error.c',
))
diff --git a/common-user/mmap-min-addr.c b/common-user/mmap-min-addr.c
new file mode 100644
index 0000000000..b2b3762386
--- /dev/null
+++ b/common-user/mmap-min-addr.c
@@ -0,0 +1,37 @@
+/*
+ * Utility function to get the minimum mmap address.
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "user/mmap-min-addr.h"
+
+uintptr_t mmap_min_addr;
+
+static void __attribute__((constructor)) init(void)
+{
+#ifdef __linux__
+ /*
+ * We prefer to not make NULL pointers accessible to QEMU.
+ * If something goes wrong below, fall back to 1 page.
+ */
+ size_t min_addr = qemu_real_host_page_size();
+ /*
+ * Read in mmap_min_addr kernel parameter. This value is used
+ * When loading the ELF image to determine whether guest_base
+ * is needed. It is also used in mmap_find_vma.
+ */
+ FILE *fp = fopen("/proc/sys/vm/mmap_min_addr", "r");
+
+ if (fp) {
+ unsigned long tmp;
+ if (fscanf(fp, "%lu", &tmp) == 1 && tmp != 0) {
+ min_addr = MAX(min_addr, tmp);
+ }
+ fclose(fp);
+ }
+ mmap_min_addr = min_addr;
+#else
+# error
+#endif
+}
diff --git a/include/user/mmap-min-addr.h b/include/user/mmap-min-addr.h
new file mode 100644
index 0000000000..ded0b6909d
--- /dev/null
+++ b/include/user/mmap-min-addr.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#ifndef USER_MMAP_MIN_ADDR_H
+#define USER_MMAP_MIN_ADDR_H
+
+#ifndef CONFIG_USER_ONLY
+#error Cannot include this header from system emulation
+#endif
+
+extern uintptr_t mmap_min_addr;
+
+#endif
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 557ed20dbf..0671aba537 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -14,6 +14,7 @@
#include "exec/translation-block.h"
#include "exec/tswap.h"
#include "user/guest-base.h"
+#include "user/mmap-min-addr.h"
#include "user-internals.h"
#include "signal-common.h"
#include "loader.h"
diff --git a/linux-user/main.c b/linux-user/main.c
index c08c73fd80..01cf5bf079 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -39,6 +39,7 @@
#include "qemu/module.h"
#include "qemu/plugin.h"
#include "user/guest-base.h"
+#include "user/mmap-min-addr.h"
#include "user/page-protection.h"
#include "exec/gdbstub.h"
#include "gdbstub/user.h"
@@ -78,7 +79,6 @@ static envlist_t *envlist;
static const char *cpu_model;
static const char *cpu_type;
static const char *seed_optarg;
-unsigned long mmap_min_addr;
uintptr_t guest_base;
bool have_guest_base;
@@ -914,35 +914,8 @@ int main(int argc, char **argv, char **envp)
target_environ = envlist_to_environ(envlist, NULL);
envlist_free(envlist);
- /*
- * Read in mmap_min_addr kernel parameter. This value is used
- * When loading the ELF image to determine whether guest_base
- * is needed. It is also used in mmap_find_vma.
- */
- {
- FILE *fp;
-
- if ((fp = fopen("/proc/sys/vm/mmap_min_addr", "r")) != NULL) {
- unsigned long tmp;
- if (fscanf(fp, "%lu", &tmp) == 1 && tmp != 0) {
- mmap_min_addr = MAX(tmp, host_page_size);
- qemu_log_mask(CPU_LOG_PAGE, "host mmap_min_addr=0x%lx\n",
- mmap_min_addr);
- }
- fclose(fp);
- }
- }
-
- /*
- * We prefer to not make NULL pointers accessible to QEMU.
- * If we're in a chroot with no /proc, fall back to 1 page.
- */
- if (mmap_min_addr == 0) {
- mmap_min_addr = host_page_size;
- qemu_log_mask(CPU_LOG_PAGE,
- "host mmap_min_addr=0x%lx (fallback)\n",
- mmap_min_addr);
- }
+ qemu_log_mask(CPU_LOG_PAGE, "host mmap_min_addr=0x%" PRIxPTR "\n",
+ mmap_min_addr);
/*
* Prepare copy of argv vector for target.
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index 55277f7c3e..cc0c2ee6c2 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -24,6 +24,7 @@
#include "exec/mmap-lock.h"
#include "qemu.h"
#include "user/page-protection.h"
+#include "user/mmap-min-addr.h"
#include "user-internals.h"
#include "user-mmap.h"
#include "target_mman.h"
diff --git a/linux-user/user-internals.h b/linux-user/user-internals.h
index d7f346b0d0..74d8eaabbe 100644
--- a/linux-user/user-internals.h
+++ b/linux-user/user-internals.h
@@ -29,7 +29,6 @@ void init_task_state(TaskState *ts);
void task_settid(TaskState *);
void stop_all_tasks(void);
extern const char *qemu_uname_release;
-extern unsigned long mmap_min_addr;
typedef struct IOCTLEntry IOCTLEntry;