Message ID | 20230804014517.6361-11-richard.henderson@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | linux-user: brk fixes | expand |
On 2023/08/04 10:45, Richard Henderson wrote: > Copy each guest kernel's default value, then bound it > against reserved_va or the host address space. > > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> > --- > linux-user/aarch64/target_mman.h | 3 +++ > linux-user/alpha/target_mman.h | 3 +++ > linux-user/arm/target_mman.h | 3 +++ > linux-user/cris/target_mman.h | 3 +++ > linux-user/hexagon/target_mman.h | 3 +++ > linux-user/hppa/target_mman.h | 3 +++ > linux-user/i386/target_mman.h | 3 +++ > linux-user/loongarch64/target_mman.h | 3 +++ > linux-user/m68k/target_mman.h | 2 ++ > linux-user/microblaze/target_mman.h | 3 +++ > linux-user/mips/target_mman.h | 3 +++ > linux-user/nios2/target_mman.h | 3 +++ > linux-user/openrisc/target_mman.h | 3 +++ > linux-user/ppc/target_mman.h | 7 +++++++ > linux-user/riscv/target_mman.h | 3 +++ > linux-user/s390x/target_mman.h | 10 ++++++++++ > linux-user/sh4/target_mman.h | 3 +++ > linux-user/sparc/target_mman.h | 11 +++++++++++ > linux-user/user-mmap.h | 1 + > linux-user/x86_64/target_mman.h | 3 +++ > linux-user/xtensa/target_mman.h | 4 ++++ > linux-user/main.c | 15 +++++++++++++++ > linux-user/mmap.c | 1 + > 23 files changed, 96 insertions(+) > > diff --git a/linux-user/aarch64/target_mman.h b/linux-user/aarch64/target_mman.h > index 4d3eecfb26..69ec5d5739 100644 > --- a/linux-user/aarch64/target_mman.h > +++ b/linux-user/aarch64/target_mman.h > @@ -14,6 +14,9 @@ > */ > #define TASK_UNMAPPED_BASE (1ull << (48 - 2)) > > +/* arch/arm64/include/asm/elf.h */ > +#define ELF_ET_DYN_BASE TARGET_PAGE_ALIGN((1ull << 48) / 3 * 2) > + > #include "../generic/target_mman.h" > > #endif > diff --git a/linux-user/alpha/target_mman.h b/linux-user/alpha/target_mman.h > index c90b493711..8edfe2b88c 100644 > --- a/linux-user/alpha/target_mman.h > +++ b/linux-user/alpha/target_mman.h > @@ -28,6 +28,9 @@ > */ > #define TASK_UNMAPPED_BASE 0x20000000000ull > > +/* arch/alpha/include/asm/elf.h */ > +#define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000) > + > #include "../generic/target_mman.h" > > #endif > diff --git a/linux-user/arm/target_mman.h b/linux-user/arm/target_mman.h > index 76275b2c7e..51005da869 100644 > --- a/linux-user/arm/target_mman.h > +++ b/linux-user/arm/target_mman.h > @@ -6,4 +6,7 @@ > */ > #define TASK_UNMAPPED_BASE 0x40000000 > > +/* arch/arm/include/asm/elf.h */ > +#define ELF_ET_DYN_BASE 0x00400000 > + > #include "../generic/target_mman.h" > diff --git a/linux-user/cris/target_mman.h b/linux-user/cris/target_mman.h > index 9df7b1eda5..9ace8ac292 100644 > --- a/linux-user/cris/target_mman.h > +++ b/linux-user/cris/target_mman.h > @@ -7,4 +7,7 @@ > */ > #define TASK_UNMAPPED_BASE TARGET_PAGE_ALIGN(0xb0000000 / 3) > > +/* arch/cris/include/uapi/asm/elf.h */ > +#define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE * 2) > + > #include "../generic/target_mman.h" > diff --git a/linux-user/hexagon/target_mman.h b/linux-user/hexagon/target_mman.h > index c5ae336e07..e6b5e2ca36 100644 > --- a/linux-user/hexagon/target_mman.h > +++ b/linux-user/hexagon/target_mman.h > @@ -8,4 +8,7 @@ > */ > #define TASK_UNMAPPED_BASE 0x40000000 > > +/* arch/hexagon/include/asm/elf.h */ > +#define ELF_ET_DYN_BASE 0x08000000 > + > #include "../generic/target_mman.h" > diff --git a/linux-user/hppa/target_mman.h b/linux-user/hppa/target_mman.h > index 6459e7dbdd..ccda46e842 100644 > --- a/linux-user/hppa/target_mman.h > +++ b/linux-user/hppa/target_mman.h > @@ -27,6 +27,9 @@ > /* arch/parisc/include/asm/processor.h: DEFAULT_MAP_BASE32 */ > #define TASK_UNMAPPED_BASE 0x40000000 > > +/* arch/parisc/include/asm/elf.h */ > +#define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x01000000) > + > #include "../generic/target_mman.h" > > #endif > diff --git a/linux-user/i386/target_mman.h b/linux-user/i386/target_mman.h > index cc3382007f..e3b8e1eaa6 100644 > --- a/linux-user/i386/target_mman.h > +++ b/linux-user/i386/target_mman.h > @@ -11,4 +11,7 @@ > */ > #define TASK_UNMAPPED_BASE 0x40000000 > > +/* arch/x86/include/asm/elf.h */ > +#define ELF_ET_DYN_BASE 0x00400000 > + > #include "../generic/target_mman.h" > diff --git a/linux-user/loongarch64/target_mman.h b/linux-user/loongarch64/target_mman.h > index d70e44d44c..8c2a3d5596 100644 > --- a/linux-user/loongarch64/target_mman.h > +++ b/linux-user/loongarch64/target_mman.h > @@ -6,4 +6,7 @@ > #define TASK_UNMAPPED_BASE \ > TARGET_PAGE_ALIGN((1ull << TARGET_VIRT_ADDR_SPACE_BITS) / 3) > > +/* arch/loongarch/include/asm/elf.h */ > +#define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE * 2) > + > #include "../generic/target_mman.h" > diff --git a/linux-user/m68k/target_mman.h b/linux-user/m68k/target_mman.h > index d3eceb663b..20cfe750c5 100644 > --- a/linux-user/m68k/target_mman.h > +++ b/linux-user/m68k/target_mman.h > @@ -1,4 +1,6 @@ > /* arch/m68k/include/asm/processor.h */ > #define TASK_UNMAPPED_BASE 0xC0000000 > +/* arch/m68k/include/asm/elf.h */ > +#define ELF_ET_DYN_BASE 0xD0000000 > > #include "../generic/target_mman.h" > diff --git a/linux-user/microblaze/target_mman.h b/linux-user/microblaze/target_mman.h > index ffee869db4..6b3dd54f89 100644 > --- a/linux-user/microblaze/target_mman.h > +++ b/linux-user/microblaze/target_mman.h > @@ -6,4 +6,7 @@ > */ > #define TASK_UNMAPPED_BASE 0x48000000 > > +/* arch/microblaze/include/uapi/asm/elf.h */ > +#define ELF_ET_DYN_BASE 0x08000000 > + > #include "../generic/target_mman.h" > diff --git a/linux-user/mips/target_mman.h b/linux-user/mips/target_mman.h > index fe1eec2d0b..b84fe1e8a8 100644 > --- a/linux-user/mips/target_mman.h > +++ b/linux-user/mips/target_mman.h > @@ -21,6 +21,9 @@ > #define TASK_UNMAPPED_BASE \ > TARGET_PAGE_ALIGN((1ull << TARGET_VIRT_ADDR_SPACE_BITS) / 3) > > +/* arch/mips/include/asm/elf.h */ > +#define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE * 2) > + > #include "../generic/target_mman.h" > > #endif > diff --git a/linux-user/nios2/target_mman.h b/linux-user/nios2/target_mman.h > index ce18f4f871..ab16ad4f03 100644 > --- a/linux-user/nios2/target_mman.h > +++ b/linux-user/nios2/target_mman.h > @@ -5,4 +5,7 @@ > */ > #define TASK_UNMAPPED_BASE TARGET_PAGE_ALIGN(0x7FFF0000 / 3) > > +/* arch/nios2/include/asm/elf.h */ > +#define ELF_ET_DYN_BASE 0xD0000000 > + > #include "../generic/target_mman.h" > diff --git a/linux-user/openrisc/target_mman.h b/linux-user/openrisc/target_mman.h > index f1aaad809d..243c1d5f26 100644 > --- a/linux-user/openrisc/target_mman.h > +++ b/linux-user/openrisc/target_mman.h > @@ -5,4 +5,7 @@ > */ > #define TASK_UNMAPPED_BASE 0x30000000 > > +/* arch/openrisc/include/asm/elf.h */ > +#define ELF_ET_DYN_BASE 0x08000000 > + > #include "../generic/target_mman.h" > diff --git a/linux-user/ppc/target_mman.h b/linux-user/ppc/target_mman.h > index 04f99c6077..646d1ccae7 100644 > --- a/linux-user/ppc/target_mman.h > +++ b/linux-user/ppc/target_mman.h > @@ -17,6 +17,13 @@ > #define TASK_UNMAPPED_BASE 0x40000000 > #endif > > +/* arch/powerpc/include/asm/elf.h */ > +#ifdef TARGET_PPC64 > +#define ELF_ET_DYN_BASE 0x100000000ull > +#else > +#define ELF_ET_DYN_BASE 0x000400000 > +#endif > + > #include "../generic/target_mman.h" > > #endif > diff --git a/linux-user/riscv/target_mman.h b/linux-user/riscv/target_mman.h > index 0f06dadbd4..3049bcc67d 100644 > --- a/linux-user/riscv/target_mman.h > +++ b/linux-user/riscv/target_mman.h > @@ -5,4 +5,7 @@ > #define TASK_UNMAPPED_BASE \ > TARGET_PAGE_ALIGN((1ull << (TARGET_VIRT_ADDR_SPACE_BITS - 1)) / 3) > > +/* arch/riscv/include/asm/elf.h */ > +#define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE * 2) > + > #include "../generic/target_mman.h" > diff --git a/linux-user/s390x/target_mman.h b/linux-user/s390x/target_mman.h > index 40d149b329..c82435e381 100644 > --- a/linux-user/s390x/target_mman.h > +++ b/linux-user/s390x/target_mman.h > @@ -8,4 +8,14 @@ > */ > #define TASK_UNMAPPED_BASE (1ull << 41) > > +/* > + * arch/s390/include/asm/elf.h: > + * ELF_ET_DYN_BASE (STACK_TOP / 3 * 2) & ~((1UL << 32) - 1) > + * > + * arch/s390/include/asm/processor.h: > + * STACK_TOP VDSO_LIMIT - VDSO_SIZE - PAGE_SIZE > + * VDSO_LIMIT _REGION2_SIZE > + */ > +#define ELF_ET_DYN_BASE (((1ull << 42) / 3 * 2) & ~0xffffffffull) > + > #include "../generic/target_mman.h" > diff --git a/linux-user/sh4/target_mman.h b/linux-user/sh4/target_mman.h > index bbbc223398..dd9016081e 100644 > --- a/linux-user/sh4/target_mman.h > +++ b/linux-user/sh4/target_mman.h > @@ -2,4 +2,7 @@ > #define TASK_UNMAPPED_BASE \ > TARGET_PAGE_ALIGN((1u << TARGET_VIRT_ADDR_SPACE_BITS) / 3) > > +/* arch/sh/include/asm/elf.h */ > +#define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE * 2) > + > #include "../generic/target_mman.h" > diff --git a/linux-user/sparc/target_mman.h b/linux-user/sparc/target_mman.h > index 692ebf9dd7..696ca73fe4 100644 > --- a/linux-user/sparc/target_mman.h > +++ b/linux-user/sparc/target_mman.h > @@ -19,6 +19,17 @@ > #define TASK_UNMAPPED_BASE (1ull << (TARGET_VIRT_ADDR_SPACE_BITS - 2)) > #endif > > +/* > + * arch/sparc/include/asm/elf_64.h > + * Except that COMPAT_ELF_ET_DYN_BASE exactly matches TASK_UNMAPPED_BASE, > + * so move it up a bit. > + */ > +#ifdef TARGET_ABI32 > +#define ELF_ET_DYN_BASE 0x78000000 > +#else > +#define ELF_ET_DYN_BASE 0x0000010000000000ull > +#endif > + > #include "../generic/target_mman.h" > > #endif > diff --git a/linux-user/user-mmap.h b/linux-user/user-mmap.h > index bae49059e0..5dd48a458d 100644 > --- a/linux-user/user-mmap.h > +++ b/linux-user/user-mmap.h > @@ -20,6 +20,7 @@ > > extern abi_ulong task_unmapped_base; > extern abi_ulong mmap_next_start; > +extern abi_ulong elf_et_dyn_base; > > int target_mprotect(abi_ulong start, abi_ulong len, int prot); > abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, > diff --git a/linux-user/x86_64/target_mman.h b/linux-user/x86_64/target_mman.h > index f9ff652b37..48fbf20b42 100644 > --- a/linux-user/x86_64/target_mman.h > +++ b/linux-user/x86_64/target_mman.h > @@ -10,4 +10,7 @@ > #define TASK_UNMAPPED_BASE \ > TARGET_PAGE_ALIGN((1ull << TARGET_VIRT_ADDR_SPACE_BITS) / 3) > > +/* arch/x86/include/asm/elf.h */ > +#define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE * 2) > + > #include "../generic/target_mman.h" > diff --git a/linux-user/xtensa/target_mman.h b/linux-user/xtensa/target_mman.h > index c4f671adb7..8fa6337a97 100644 > --- a/linux-user/xtensa/target_mman.h > +++ b/linux-user/xtensa/target_mman.h > @@ -20,6 +20,10 @@ > */ > #define TASK_UNMAPPED_BASE (1u << (TARGET_VIRT_ADDR_SPACE_BITS - 1)) > > +/* arch/xtensa/include/asm/elf.h */ > +#define ELF_ET_DYN_BASE \ > + TARGET_PAGE_ALIGN((1u << TARGET_VIRT_ADDR_SPACE_BITS) / 3) > + > #include "../generic/target_mman.h" > > #endif > diff --git a/linux-user/main.c b/linux-user/main.c > index 52809c260a..e089123cfa 100644 > --- a/linux-user/main.c > +++ b/linux-user/main.c > @@ -839,6 +839,21 @@ int main(int argc, char **argv, char **envp) > } > mmap_next_start = task_unmapped_base; > > + /* Similarly for elf_et_dyn_base. */ > + if (reserved_va) { > + if (ELF_ET_DYN_BASE < reserved_va) { > + elf_et_dyn_base = ELF_ET_DYN_BASE; > + } else { > + /* The most common default formula is TASK_SIZE / 3 * 2. */ > + task_unmapped_base = TARGET_PAGE_ALIGN(reserved_va / 3) * 2; This assigns a value to task_unmapped_base and that does not seem correct. > + } > + } else if (ELF_ET_DYN_BASE < UINTPTR_MAX) { > + elf_et_dyn_base = ELF_ET_DYN_BASE; > + } else { > + /* 32-bit host: pick something medium size. */ > + task_unmapped_base = 0x18000000; > + } > + > { > Error *err = NULL; > if (seed_optarg != NULL) { > diff --git a/linux-user/mmap.c b/linux-user/mmap.c > index 84436d45c8..949c4090f3 100644 > --- a/linux-user/mmap.c > +++ b/linux-user/mmap.c > @@ -301,6 +301,7 @@ static bool mmap_frag(abi_ulong real_start, abi_ulong start, abi_ulong last, > > abi_ulong task_unmapped_base; > abi_ulong mmap_next_start; > +abi_ulong elf_et_dyn_base; > > /* > * Subroutine of mmap_find_vma, used when we have pre-allocated
On 8/4/23 03:45, Richard Henderson wrote: > Copy each guest kernel's default value, then bound it > against reserved_va or the host address space. > > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> > --- > linux-user/aarch64/target_mman.h | 3 +++ > linux-user/alpha/target_mman.h | 3 +++ > ... I've successfully tested the whole series on the following chroots (on x86 host): alpha, arm64, armhf, hppa, m68k, mips64el, mipsel powerpc, ppc64, ppc64el, s390x, sh4, sparc64. Both static and dynamically linked programs work as expected. It's a big step forward compared to qemu v8.0, so feel free to add to the whole series: Tested-by: Helge Deller <deller@gmx.de> For this patch: Reviewed-by: Helge Deller <deller@gmx.de> One thing to mention here is, that those values (ELF_ET_DYN_BASE) reflects the legacy (standard) memory layout of the kernel only. The process personality defines which layout should be used, ADDR_COMPAT_LAYOUT means to use the legacy (standard) memory layout. The Linux kernel on 390, parisc, sparc and x86 doesn't use by default the legacy memory model, but instead allocates new mappings from top downwards. This leaves much more space for heap. Search for mmap_is_legacy() in the kernel sources. That said, we should implement the top-downwards allocation after qemu 8.1. In this regard, could you please include my latest patch titled: linux-user: Show heap address in /proc/pid/maps in your patch series? I sent an updated version today to the mailing list, which applies to your series. . If applied, the "[heap]" entry is visible in /proc/cpuinfo output, and it's much easier to see potential future memory isses, e.g. armhf-chroot: -> heap is limited in region 21000 to 00400000. -> 00421000 to 40000000 would give much more space for heap. -> arm32 doesn't seem to support non-legacy memory model yet... Linux p100 6.4.6-200.fc38.x86_64 #1 SMP PREEMPT_DYNAMIC Mon Jul 24 20:51:12 UTC 2023 armv7l GNU/Linux 00021000-00042000 rw-p 00000000 00:00 0 [heap] 00400000-00406000 r-xp 00000000 fd:00 675877 /usr/bin/cat 00406000-0041f000 ---p 00000000 00:00 0 0041f000-00420000 r--p 0000f000 fd:00 675877 /usr/bin/cat 00420000-00421000 rw-p 00010000 fd:00 675877 /usr/bin/cat 40000000-40001000 ---p 00000000 00:00 0 40001000-40801000 rw-p 00000000 00:00 0 [stack] 40801000-4081d000 r-xp 00000000 fd:00 682674 /usr/lib/arm-linux-gnueabihf/ld-linux-armhf.so.3 4081d000-4081e000 r--p 0001c000 fd:00 682674 /usr/lib/arm-linux-gnueabihf/ld-linux-armhf.so.3 4081e000-4081f000 rw-p 0001d000 fd:00 682674 /usr/lib/arm-linux-gnueabihf/ld-linux-armhf.so.3 4081f000-40820000 r-xp 00000000 00:00 0 40820000-40822000 rw-p 00000000 00:00 0 40822000-4092b000 r-xp 00000000 fd:00 682677 /usr/lib/arm-linux-gnueabihf/libc.so.6 4092b000-4092d000 r--p 00108000 fd:00 682677 /usr/lib/arm-linux-gnueabihf/libc.so.6 4092d000-4092e000 rw-p 0010a000 fd:00 682677 /usr/lib/arm-linux-gnueabihf/libc.so.6 4092e000-40938000 rw-p 00000000 00:00 0 ffff0000-ffff1000 r-xp 00000000 00:00 0 mipsel-chroot -> heap is locked in from 00021000 to 2aaab000 Linux p100 6.4.6-200.fc38.x86_64 #1 SMP PREEMPT_DYNAMIC Mon Jul 24 20:51:12 UTC 2023 mips GNU/Linux 00021000-00042000 rw-p 00000000 00:00 0 [heap] 2aaab000-2aaac000 ---p 00000000 00:00 0 2aaac000-2b2ac000 rwxp 00000000 00:00 0 [stack] 2b2ac000-2b2d8000 r-xp 00000000 fd:00 816208 /usr/lib/mipsel-linux-gnu/ld.so.1 2b2d8000-2b2eb000 ---p 00000000 00:00 0 2b2eb000-2b2ec000 r--p 0002f000 fd:00 816208 /usr/lib/mipsel-linux-gnu/ld.so.1 2b2ec000-2b2ed000 rw-p 00030000 fd:00 816208 /usr/lib/mipsel-linux-gnu/ld.so.1 2b2ed000-2b2ee000 r-xp 00000000 00:00 0 2b2ee000-2b2f0000 rw-p 00000000 00:00 0 2b2f0000-2b4ae000 r-xp 00000000 fd:00 816216 /usr/lib/mipsel-linux-gnu/libc.so.6 2b4ae000-2b4bd000 ---p 001be000 fd:00 816216 /usr/lib/mipsel-linux-gnu/libc.so.6 2b4bd000-2b4c0000 r--p 001bd000 fd:00 816216 /usr/lib/mipsel-linux-gnu/libc.so.6 2b4c0000-2b4c3000 rw-p 001c0000 fd:00 816216 /usr/lib/mipsel-linux-gnu/libc.so.6 2b4c3000-2b4cd000 rw-p 00000000 00:00 0 55550000-55559000 r-xp 00000000 fd:00 818831 /usr/bin/cat 55559000-5556f000 ---p 00000000 00:00 0 5556f000-55570000 r--p 0000f000 fd:00 818831 /usr/bin/cat 55570000-55571000 rw-p 00010000 fd:00 818831 /usr/bin/cat hppa-chroot -> heap & stack is ok. -> heap could greatly benefit if qemu later supports top-down mmap allocation, because then the shared libs will be mapped >fa000000 and heap&stack can grow from 0001a000 up to fa000000. Linux p100 6.4.6-200.fc38.x86_64 #1 SMP PREEMPT_DYNAMIC Mon Jul 24 20:51:12 UTC 2023 parisc GNU/Linux 00000000-00001000 --xp 00000000 00:00 0 00010000-00019000 r-xp 00000000 fd:00 1061893 /usr/bin/cat 00019000-0001a000 rwxp 00009000 fd:00 1061893 /usr/bin/cat 0001a000-0003b000 rw-p 00000000 00:00 0 [heap] 40000000-45000000 rwxp 00000000 00:00 0 [stack] 45000000-4502f000 r-xp 00000000 fd:00 1069300 /usr/lib/hppa-linux-gnu/ld.so.1 4502f000-45030000 r--p 0002f000 fd:00 1069300 /usr/lib/hppa-linux-gnu/ld.so.1 45030000-45034000 rwxp 00030000 fd:00 1069300 /usr/lib/hppa-linux-gnu/ld.so.1 45034000-45035000 r-xp 00000000 00:00 0 45037000-45039000 rw-p 00000000 00:00 0 45039000-451f5000 r-xp 00000000 fd:00 1069303 /usr/lib/hppa-linux-gnu/libc.so.6 451f5000-451f7000 r--p 001bc000 fd:00 1069303 /usr/lib/hppa-linux-gnu/libc.so.6 451f7000-451fc000 rwxp 001be000 fd:00 1069303 /usr/lib/hppa-linux-gnu/libc.so.6 Thanks! Helge
On 8/4/23 02:50, Helge Deller wrote: > In this regard, could you please include my latest patch titled: > > linux-user: Show heap address in /proc/pid/maps > > in your patch series? No, as it's not a bug fix. It can wait for 8.2. > If applied, the "[heap]" entry is visible in /proc/cpuinfo output, and > it's much easier to see potential future memory isses, e.g. Anyway, changing the guest /proc/cpuinfo output seems much less useful than improving -d page (which misses out on logging lots of the PAGE_* bits). r~
On 8/3/23 22:20, Akihiko Odaki wrote: >> + if (reserved_va) { >> + if (ELF_ET_DYN_BASE < reserved_va) { >> + elf_et_dyn_base = ELF_ET_DYN_BASE; >> + } else { >> + /* The most common default formula is TASK_SIZE / 3 * 2. */ >> + task_unmapped_base = TARGET_PAGE_ALIGN(reserved_va / 3) * 2; > > This assigns a value to task_unmapped_base and that does not seem correct. > Gah, I fixed this on a different copy of my branch, then lost it. r~
diff --git a/linux-user/aarch64/target_mman.h b/linux-user/aarch64/target_mman.h index 4d3eecfb26..69ec5d5739 100644 --- a/linux-user/aarch64/target_mman.h +++ b/linux-user/aarch64/target_mman.h @@ -14,6 +14,9 @@ */ #define TASK_UNMAPPED_BASE (1ull << (48 - 2)) +/* arch/arm64/include/asm/elf.h */ +#define ELF_ET_DYN_BASE TARGET_PAGE_ALIGN((1ull << 48) / 3 * 2) + #include "../generic/target_mman.h" #endif diff --git a/linux-user/alpha/target_mman.h b/linux-user/alpha/target_mman.h index c90b493711..8edfe2b88c 100644 --- a/linux-user/alpha/target_mman.h +++ b/linux-user/alpha/target_mman.h @@ -28,6 +28,9 @@ */ #define TASK_UNMAPPED_BASE 0x20000000000ull +/* arch/alpha/include/asm/elf.h */ +#define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000) + #include "../generic/target_mman.h" #endif diff --git a/linux-user/arm/target_mman.h b/linux-user/arm/target_mman.h index 76275b2c7e..51005da869 100644 --- a/linux-user/arm/target_mman.h +++ b/linux-user/arm/target_mman.h @@ -6,4 +6,7 @@ */ #define TASK_UNMAPPED_BASE 0x40000000 +/* arch/arm/include/asm/elf.h */ +#define ELF_ET_DYN_BASE 0x00400000 + #include "../generic/target_mman.h" diff --git a/linux-user/cris/target_mman.h b/linux-user/cris/target_mman.h index 9df7b1eda5..9ace8ac292 100644 --- a/linux-user/cris/target_mman.h +++ b/linux-user/cris/target_mman.h @@ -7,4 +7,7 @@ */ #define TASK_UNMAPPED_BASE TARGET_PAGE_ALIGN(0xb0000000 / 3) +/* arch/cris/include/uapi/asm/elf.h */ +#define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE * 2) + #include "../generic/target_mman.h" diff --git a/linux-user/hexagon/target_mman.h b/linux-user/hexagon/target_mman.h index c5ae336e07..e6b5e2ca36 100644 --- a/linux-user/hexagon/target_mman.h +++ b/linux-user/hexagon/target_mman.h @@ -8,4 +8,7 @@ */ #define TASK_UNMAPPED_BASE 0x40000000 +/* arch/hexagon/include/asm/elf.h */ +#define ELF_ET_DYN_BASE 0x08000000 + #include "../generic/target_mman.h" diff --git a/linux-user/hppa/target_mman.h b/linux-user/hppa/target_mman.h index 6459e7dbdd..ccda46e842 100644 --- a/linux-user/hppa/target_mman.h +++ b/linux-user/hppa/target_mman.h @@ -27,6 +27,9 @@ /* arch/parisc/include/asm/processor.h: DEFAULT_MAP_BASE32 */ #define TASK_UNMAPPED_BASE 0x40000000 +/* arch/parisc/include/asm/elf.h */ +#define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x01000000) + #include "../generic/target_mman.h" #endif diff --git a/linux-user/i386/target_mman.h b/linux-user/i386/target_mman.h index cc3382007f..e3b8e1eaa6 100644 --- a/linux-user/i386/target_mman.h +++ b/linux-user/i386/target_mman.h @@ -11,4 +11,7 @@ */ #define TASK_UNMAPPED_BASE 0x40000000 +/* arch/x86/include/asm/elf.h */ +#define ELF_ET_DYN_BASE 0x00400000 + #include "../generic/target_mman.h" diff --git a/linux-user/loongarch64/target_mman.h b/linux-user/loongarch64/target_mman.h index d70e44d44c..8c2a3d5596 100644 --- a/linux-user/loongarch64/target_mman.h +++ b/linux-user/loongarch64/target_mman.h @@ -6,4 +6,7 @@ #define TASK_UNMAPPED_BASE \ TARGET_PAGE_ALIGN((1ull << TARGET_VIRT_ADDR_SPACE_BITS) / 3) +/* arch/loongarch/include/asm/elf.h */ +#define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE * 2) + #include "../generic/target_mman.h" diff --git a/linux-user/m68k/target_mman.h b/linux-user/m68k/target_mman.h index d3eceb663b..20cfe750c5 100644 --- a/linux-user/m68k/target_mman.h +++ b/linux-user/m68k/target_mman.h @@ -1,4 +1,6 @@ /* arch/m68k/include/asm/processor.h */ #define TASK_UNMAPPED_BASE 0xC0000000 +/* arch/m68k/include/asm/elf.h */ +#define ELF_ET_DYN_BASE 0xD0000000 #include "../generic/target_mman.h" diff --git a/linux-user/microblaze/target_mman.h b/linux-user/microblaze/target_mman.h index ffee869db4..6b3dd54f89 100644 --- a/linux-user/microblaze/target_mman.h +++ b/linux-user/microblaze/target_mman.h @@ -6,4 +6,7 @@ */ #define TASK_UNMAPPED_BASE 0x48000000 +/* arch/microblaze/include/uapi/asm/elf.h */ +#define ELF_ET_DYN_BASE 0x08000000 + #include "../generic/target_mman.h" diff --git a/linux-user/mips/target_mman.h b/linux-user/mips/target_mman.h index fe1eec2d0b..b84fe1e8a8 100644 --- a/linux-user/mips/target_mman.h +++ b/linux-user/mips/target_mman.h @@ -21,6 +21,9 @@ #define TASK_UNMAPPED_BASE \ TARGET_PAGE_ALIGN((1ull << TARGET_VIRT_ADDR_SPACE_BITS) / 3) +/* arch/mips/include/asm/elf.h */ +#define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE * 2) + #include "../generic/target_mman.h" #endif diff --git a/linux-user/nios2/target_mman.h b/linux-user/nios2/target_mman.h index ce18f4f871..ab16ad4f03 100644 --- a/linux-user/nios2/target_mman.h +++ b/linux-user/nios2/target_mman.h @@ -5,4 +5,7 @@ */ #define TASK_UNMAPPED_BASE TARGET_PAGE_ALIGN(0x7FFF0000 / 3) +/* arch/nios2/include/asm/elf.h */ +#define ELF_ET_DYN_BASE 0xD0000000 + #include "../generic/target_mman.h" diff --git a/linux-user/openrisc/target_mman.h b/linux-user/openrisc/target_mman.h index f1aaad809d..243c1d5f26 100644 --- a/linux-user/openrisc/target_mman.h +++ b/linux-user/openrisc/target_mman.h @@ -5,4 +5,7 @@ */ #define TASK_UNMAPPED_BASE 0x30000000 +/* arch/openrisc/include/asm/elf.h */ +#define ELF_ET_DYN_BASE 0x08000000 + #include "../generic/target_mman.h" diff --git a/linux-user/ppc/target_mman.h b/linux-user/ppc/target_mman.h index 04f99c6077..646d1ccae7 100644 --- a/linux-user/ppc/target_mman.h +++ b/linux-user/ppc/target_mman.h @@ -17,6 +17,13 @@ #define TASK_UNMAPPED_BASE 0x40000000 #endif +/* arch/powerpc/include/asm/elf.h */ +#ifdef TARGET_PPC64 +#define ELF_ET_DYN_BASE 0x100000000ull +#else +#define ELF_ET_DYN_BASE 0x000400000 +#endif + #include "../generic/target_mman.h" #endif diff --git a/linux-user/riscv/target_mman.h b/linux-user/riscv/target_mman.h index 0f06dadbd4..3049bcc67d 100644 --- a/linux-user/riscv/target_mman.h +++ b/linux-user/riscv/target_mman.h @@ -5,4 +5,7 @@ #define TASK_UNMAPPED_BASE \ TARGET_PAGE_ALIGN((1ull << (TARGET_VIRT_ADDR_SPACE_BITS - 1)) / 3) +/* arch/riscv/include/asm/elf.h */ +#define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE * 2) + #include "../generic/target_mman.h" diff --git a/linux-user/s390x/target_mman.h b/linux-user/s390x/target_mman.h index 40d149b329..c82435e381 100644 --- a/linux-user/s390x/target_mman.h +++ b/linux-user/s390x/target_mman.h @@ -8,4 +8,14 @@ */ #define TASK_UNMAPPED_BASE (1ull << 41) +/* + * arch/s390/include/asm/elf.h: + * ELF_ET_DYN_BASE (STACK_TOP / 3 * 2) & ~((1UL << 32) - 1) + * + * arch/s390/include/asm/processor.h: + * STACK_TOP VDSO_LIMIT - VDSO_SIZE - PAGE_SIZE + * VDSO_LIMIT _REGION2_SIZE + */ +#define ELF_ET_DYN_BASE (((1ull << 42) / 3 * 2) & ~0xffffffffull) + #include "../generic/target_mman.h" diff --git a/linux-user/sh4/target_mman.h b/linux-user/sh4/target_mman.h index bbbc223398..dd9016081e 100644 --- a/linux-user/sh4/target_mman.h +++ b/linux-user/sh4/target_mman.h @@ -2,4 +2,7 @@ #define TASK_UNMAPPED_BASE \ TARGET_PAGE_ALIGN((1u << TARGET_VIRT_ADDR_SPACE_BITS) / 3) +/* arch/sh/include/asm/elf.h */ +#define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE * 2) + #include "../generic/target_mman.h" diff --git a/linux-user/sparc/target_mman.h b/linux-user/sparc/target_mman.h index 692ebf9dd7..696ca73fe4 100644 --- a/linux-user/sparc/target_mman.h +++ b/linux-user/sparc/target_mman.h @@ -19,6 +19,17 @@ #define TASK_UNMAPPED_BASE (1ull << (TARGET_VIRT_ADDR_SPACE_BITS - 2)) #endif +/* + * arch/sparc/include/asm/elf_64.h + * Except that COMPAT_ELF_ET_DYN_BASE exactly matches TASK_UNMAPPED_BASE, + * so move it up a bit. + */ +#ifdef TARGET_ABI32 +#define ELF_ET_DYN_BASE 0x78000000 +#else +#define ELF_ET_DYN_BASE 0x0000010000000000ull +#endif + #include "../generic/target_mman.h" #endif diff --git a/linux-user/user-mmap.h b/linux-user/user-mmap.h index bae49059e0..5dd48a458d 100644 --- a/linux-user/user-mmap.h +++ b/linux-user/user-mmap.h @@ -20,6 +20,7 @@ extern abi_ulong task_unmapped_base; extern abi_ulong mmap_next_start; +extern abi_ulong elf_et_dyn_base; int target_mprotect(abi_ulong start, abi_ulong len, int prot); abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, diff --git a/linux-user/x86_64/target_mman.h b/linux-user/x86_64/target_mman.h index f9ff652b37..48fbf20b42 100644 --- a/linux-user/x86_64/target_mman.h +++ b/linux-user/x86_64/target_mman.h @@ -10,4 +10,7 @@ #define TASK_UNMAPPED_BASE \ TARGET_PAGE_ALIGN((1ull << TARGET_VIRT_ADDR_SPACE_BITS) / 3) +/* arch/x86/include/asm/elf.h */ +#define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE * 2) + #include "../generic/target_mman.h" diff --git a/linux-user/xtensa/target_mman.h b/linux-user/xtensa/target_mman.h index c4f671adb7..8fa6337a97 100644 --- a/linux-user/xtensa/target_mman.h +++ b/linux-user/xtensa/target_mman.h @@ -20,6 +20,10 @@ */ #define TASK_UNMAPPED_BASE (1u << (TARGET_VIRT_ADDR_SPACE_BITS - 1)) +/* arch/xtensa/include/asm/elf.h */ +#define ELF_ET_DYN_BASE \ + TARGET_PAGE_ALIGN((1u << TARGET_VIRT_ADDR_SPACE_BITS) / 3) + #include "../generic/target_mman.h" #endif diff --git a/linux-user/main.c b/linux-user/main.c index 52809c260a..e089123cfa 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -839,6 +839,21 @@ int main(int argc, char **argv, char **envp) } mmap_next_start = task_unmapped_base; + /* Similarly for elf_et_dyn_base. */ + if (reserved_va) { + if (ELF_ET_DYN_BASE < reserved_va) { + elf_et_dyn_base = ELF_ET_DYN_BASE; + } else { + /* The most common default formula is TASK_SIZE / 3 * 2. */ + task_unmapped_base = TARGET_PAGE_ALIGN(reserved_va / 3) * 2; + } + } else if (ELF_ET_DYN_BASE < UINTPTR_MAX) { + elf_et_dyn_base = ELF_ET_DYN_BASE; + } else { + /* 32-bit host: pick something medium size. */ + task_unmapped_base = 0x18000000; + } + { Error *err = NULL; if (seed_optarg != NULL) { diff --git a/linux-user/mmap.c b/linux-user/mmap.c index 84436d45c8..949c4090f3 100644 --- a/linux-user/mmap.c +++ b/linux-user/mmap.c @@ -301,6 +301,7 @@ static bool mmap_frag(abi_ulong real_start, abi_ulong start, abi_ulong last, abi_ulong task_unmapped_base; abi_ulong mmap_next_start; +abi_ulong elf_et_dyn_base; /* * Subroutine of mmap_find_vma, used when we have pre-allocated
Copy each guest kernel's default value, then bound it against reserved_va or the host address space. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- linux-user/aarch64/target_mman.h | 3 +++ linux-user/alpha/target_mman.h | 3 +++ linux-user/arm/target_mman.h | 3 +++ linux-user/cris/target_mman.h | 3 +++ linux-user/hexagon/target_mman.h | 3 +++ linux-user/hppa/target_mman.h | 3 +++ linux-user/i386/target_mman.h | 3 +++ linux-user/loongarch64/target_mman.h | 3 +++ linux-user/m68k/target_mman.h | 2 ++ linux-user/microblaze/target_mman.h | 3 +++ linux-user/mips/target_mman.h | 3 +++ linux-user/nios2/target_mman.h | 3 +++ linux-user/openrisc/target_mman.h | 3 +++ linux-user/ppc/target_mman.h | 7 +++++++ linux-user/riscv/target_mman.h | 3 +++ linux-user/s390x/target_mman.h | 10 ++++++++++ linux-user/sh4/target_mman.h | 3 +++ linux-user/sparc/target_mman.h | 11 +++++++++++ linux-user/user-mmap.h | 1 + linux-user/x86_64/target_mman.h | 3 +++ linux-user/xtensa/target_mman.h | 4 ++++ linux-user/main.c | 15 +++++++++++++++ linux-user/mmap.c | 1 + 23 files changed, 96 insertions(+)