diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2023-08-02 14:25:27 -0700 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2023-08-08 13:24:21 -0700 |
commit | c8fb5cf97da11af11def1e910920c9ead03c304a (patch) | |
tree | 1f3d2d484741d48ac99d0adb6740e878d102cf54 | |
parent | 0450cf08976f9036feaded438031b4cba94f6452 (diff) |
linux-user: Adjust task_unmapped_base for reserved_va
Ensure that the chosen values for mmap_next_start and
task_unmapped_base are within the guest address space.
Tested-by: Helge Deller <deller@gmx.de>
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
-rw-r--r-- | linux-user/main.c | 28 | ||||
-rw-r--r-- | linux-user/mmap.c | 18 | ||||
-rw-r--r-- | linux-user/user-mmap.h | 34 |
3 files changed, 64 insertions, 16 deletions
diff --git a/linux-user/main.c b/linux-user/main.c index 556956c363..be621dc792 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -821,6 +821,34 @@ int main(int argc, char **argv, char **envp) reserved_va = max_reserved_va; } + /* + * Temporarily disable + * "comparison is always false due to limited range of data type" + * due to comparison between (possible) uint64_t and uintptr_t. + */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wtype-limits" + + /* + * Select an initial value for task_unmapped_base that is in range. + */ + if (reserved_va) { + if (TASK_UNMAPPED_BASE < reserved_va) { + task_unmapped_base = TASK_UNMAPPED_BASE; + } else { + /* The most common default formula is TASK_SIZE / 3. */ + task_unmapped_base = TARGET_PAGE_ALIGN(reserved_va / 3); + } + } else if (TASK_UNMAPPED_BASE < UINTPTR_MAX) { + task_unmapped_base = TASK_UNMAPPED_BASE; + } else { + /* 32-bit host: pick something medium size. */ + task_unmapped_base = 0x10000000; + } + mmap_next_start = task_unmapped_base; + +#pragma GCC diagnostic pop + { Error *err = NULL; if (seed_optarg != NULL) { diff --git a/linux-user/mmap.c b/linux-user/mmap.c index eb04fab8ab..84436d45c8 100644 --- a/linux-user/mmap.c +++ b/linux-user/mmap.c @@ -299,20 +299,8 @@ static bool mmap_frag(abi_ulong real_start, abi_ulong start, abi_ulong last, return true; } -#if HOST_LONG_BITS == 64 && TARGET_ABI_BITS == 64 -#ifdef TARGET_AARCH64 -# define TASK_UNMAPPED_BASE 0x5500000000 -#else -# define TASK_UNMAPPED_BASE (1ul << 38) -#endif -#else -#ifdef TARGET_HPPA -# define TASK_UNMAPPED_BASE 0xfa000000 -#else -# define TASK_UNMAPPED_BASE 0x40000000 -#endif -#endif -abi_ulong mmap_next_start = TASK_UNMAPPED_BASE; +abi_ulong task_unmapped_base; +abi_ulong mmap_next_start; /* * Subroutine of mmap_find_vma, used when we have pre-allocated @@ -391,7 +379,7 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size, abi_ulong align) if ((addr & (align - 1)) == 0) { /* Success. */ - if (start == mmap_next_start && addr >= TASK_UNMAPPED_BASE) { + if (start == mmap_next_start && addr >= task_unmapped_base) { mmap_next_start = addr + size; } return addr; diff --git a/linux-user/user-mmap.h b/linux-user/user-mmap.h index 7265c2c116..2c9d99ed6c 100644 --- a/linux-user/user-mmap.h +++ b/linux-user/user-mmap.h @@ -18,6 +18,39 @@ #ifndef LINUX_USER_USER_MMAP_H #define LINUX_USER_USER_MMAP_H +#if HOST_LONG_BITS == 64 && TARGET_ABI_BITS == 64 +#ifdef TARGET_AARCH64 +# define TASK_UNMAPPED_BASE 0x5500000000 +#else +# define TASK_UNMAPPED_BASE (1ul << 38) +#endif +#else +#ifdef TARGET_HPPA +# define TASK_UNMAPPED_BASE 0xfa000000 +#else +# define TASK_UNMAPPED_BASE 0x40000000 +#endif +#endif + +/* + * Guest parameters for the ADDR_COMPAT_LAYOUT personality + * (at present this is the only layout supported by QEMU). + * + * TASK_UNMAPPED_BASE: For mmap without hint (addr != 0), the search + * for unused virtual memory begins at TASK_UNMAPPED_BASE. + * + * task_unmapped_base: When the guest address space is limited via -R, + * the value of TASK_UNMAPPED_BASE is adjusted to fit. + */ +extern abi_ulong task_unmapped_base; + +/* + * mmap_next_start: The base address for the next mmap without hint, + * increased after each successful map, starting at task_unmapped_base. + * This is an optimization within QEMU and not part of ADDR_COMPAT_LAYOUT. + */ +extern abi_ulong mmap_next_start; + int target_mprotect(abi_ulong start, abi_ulong len, int prot); abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, int flags, int fd, off_t offset); @@ -26,7 +59,6 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size, abi_ulong new_size, unsigned long flags, abi_ulong new_addr); abi_long target_madvise(abi_ulong start, abi_ulong len_in, int advice); -extern abi_ulong mmap_next_start; abi_ulong mmap_find_vma(abi_ulong, abi_ulong, abi_ulong); void mmap_fork_start(void); void mmap_fork_end(int child); |