Skip to content

Commit be04f21

Browse files
committed
bsd-user: Update mapping to handle reserved and starting conditions
Update the reserved base based on what platform we're on, as well as the start of the mmap range. Update routines that find va ranges to interact with the reserved ranges as well as properly align the mapping (this is especially important for targets whose page size does not match the host's). Loop where appropriate when the initial address space offered by mmap does not meet the contraints. This has 18e80c5 from linux-user folded in to the upstream bsd-user code as well. Signed-off-by: Mikaël Urankar <[email protected]> Signed-off-by: Stacey Son <[email protected]> Signed-off-by: Warner Losh <[email protected]> Acked-by: Richard Henderson <[email protected]> Reviewed-by: Kyle Evans <[email protected]>
1 parent b801264 commit be04f21

File tree

3 files changed

+392
-71
lines changed

3 files changed

+392
-71
lines changed

bsd-user/main.c

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,47 @@
5252
#include "target_arch_cpu.h"
5353

5454
int singlestep;
55-
unsigned long mmap_min_addr;
5655
uintptr_t guest_base;
5756
bool have_guest_base;
57+
/*
58+
* When running 32-on-64 we should make sure we can fit all of the possible
59+
* guest address space into a contiguous chunk of virtual host memory.
60+
*
61+
* This way we will never overlap with our own libraries or binaries or stack
62+
* or anything else that QEMU maps.
63+
*
64+
* Many cpus reserve the high bit (or more than one for some 64-bit cpus)
65+
* of the address for the kernel. Some cpus rely on this and user space
66+
* uses the high bit(s) for pointer tagging and the like. For them, we
67+
* must preserve the expected address space.
68+
*/
69+
#ifndef MAX_RESERVED_VA
70+
# if HOST_LONG_BITS > TARGET_VIRT_ADDR_SPACE_BITS
71+
# if TARGET_VIRT_ADDR_SPACE_BITS == 32 && \
72+
(TARGET_LONG_BITS == 32 || defined(TARGET_ABI32))
73+
/*
74+
* There are a number of places where we assign reserved_va to a variable
75+
* of type abi_ulong and expect it to fit. Avoid the last page.
76+
*/
77+
# define MAX_RESERVED_VA (0xfffffffful & TARGET_PAGE_MASK)
78+
# else
79+
# define MAX_RESERVED_VA (1ul << TARGET_VIRT_ADDR_SPACE_BITS)
80+
# endif
81+
# else
82+
# define MAX_RESERVED_VA 0
83+
# endif
84+
#endif
85+
86+
/*
87+
* That said, reserving *too* much vm space via mmap can run into problems
88+
* with rlimits, oom due to page table creation, etc. We will still try it,
89+
* if directed by the command-line option, but not by default.
90+
*/
91+
#if HOST_LONG_BITS == 64 && TARGET_VIRT_ADDR_SPACE_BITS <= 32
92+
unsigned long reserved_va = MAX_RESERVED_VA;
93+
#else
5894
unsigned long reserved_va;
95+
#endif
5996

6097
static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
6198
const char *qemu_uname_release;
@@ -439,6 +476,10 @@ int main(int argc, char **argv)
439476
target_environ = envlist_to_environ(envlist, NULL);
440477
envlist_free(envlist);
441478

479+
if (reserved_va) {
480+
mmap_next_start = reserved_va;
481+
}
482+
442483
{
443484
Error *err = NULL;
444485
if (seed_optarg != NULL) {

0 commit comments

Comments
 (0)