On Sat, May 30, 2026 at 3:12 PM Richard Henderson < [email protected]> wrote:
> Introduce user/mmap-min-addr.h. Initialize the variable > from a constructor instead of main. > > Signed-off-by: Richard Henderson <[email protected]> > --- > include/user/mmap-min-addr.h | 12 ++++++++++++ > linux-user/user-internals.h | 1 - > common-user/mmap-min-addr.c | 37 ++++++++++++++++++++++++++++++++++++ > linux-user/elfload.c | 1 + > linux-user/main.c | 33 +++----------------------------- > linux-user/mmap.c | 1 + > common-user/meson.build | 1 + > 7 files changed, 55 insertions(+), 31 deletions(-) > create mode 100644 include/user/mmap-min-addr.h > create mode 100644 common-user/mmap-min-addr.c > Reviewed-by: Warner Losh <[email protected]> > 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/user-internals.h b/linux-user/user-internals.h > index 3f41d3f33c..bc6b9f44e6 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; > > 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/linux-user/elfload.c b/linux-user/elfload.c > index 5a30cebcc3..93ab2661e3 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 b4b7b3e5cc..f81417182e 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/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', > )) > -- > 2.43.0 > >
