mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
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 18e80c55bb from linux-user folded in to the upstream
bsd-user code as well.
Signed-off-by: Mikaël Urankar <mikael.urankar@gmail.com>
Signed-off-by: Stacey Son <sson@FreeBSD.org>
Signed-off-by: Warner Losh <imp@bsdimp.com>
Acked-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Kyle Evans <kevans@FreeBSD.org>
This commit is contained in:
+42
-1
@@ -52,10 +52,47 @@
|
||||
#include "target_arch_cpu.h"
|
||||
|
||||
int singlestep;
|
||||
unsigned long mmap_min_addr;
|
||||
uintptr_t guest_base;
|
||||
bool have_guest_base;
|
||||
/*
|
||||
* When running 32-on-64 we should make sure we can fit all of the possible
|
||||
* guest address space into a contiguous chunk of virtual host memory.
|
||||
*
|
||||
* This way we will never overlap with our own libraries or binaries or stack
|
||||
* or anything else that QEMU maps.
|
||||
*
|
||||
* Many cpus reserve the high bit (or more than one for some 64-bit cpus)
|
||||
* of the address for the kernel. Some cpus rely on this and user space
|
||||
* uses the high bit(s) for pointer tagging and the like. For them, we
|
||||
* must preserve the expected address space.
|
||||
*/
|
||||
#ifndef MAX_RESERVED_VA
|
||||
# if HOST_LONG_BITS > TARGET_VIRT_ADDR_SPACE_BITS
|
||||
# if TARGET_VIRT_ADDR_SPACE_BITS == 32 && \
|
||||
(TARGET_LONG_BITS == 32 || defined(TARGET_ABI32))
|
||||
/*
|
||||
* There are a number of places where we assign reserved_va to a variable
|
||||
* of type abi_ulong and expect it to fit. Avoid the last page.
|
||||
*/
|
||||
# define MAX_RESERVED_VA (0xfffffffful & TARGET_PAGE_MASK)
|
||||
# else
|
||||
# define MAX_RESERVED_VA (1ul << TARGET_VIRT_ADDR_SPACE_BITS)
|
||||
# endif
|
||||
# else
|
||||
# define MAX_RESERVED_VA 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* That said, reserving *too* much vm space via mmap can run into problems
|
||||
* with rlimits, oom due to page table creation, etc. We will still try it,
|
||||
* if directed by the command-line option, but not by default.
|
||||
*/
|
||||
#if HOST_LONG_BITS == 64 && TARGET_VIRT_ADDR_SPACE_BITS <= 32
|
||||
unsigned long reserved_va = MAX_RESERVED_VA;
|
||||
#else
|
||||
unsigned long reserved_va;
|
||||
#endif
|
||||
|
||||
static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
|
||||
const char *qemu_uname_release;
|
||||
@@ -439,6 +476,10 @@ int main(int argc, char **argv)
|
||||
target_environ = envlist_to_environ(envlist, NULL);
|
||||
envlist_free(envlist);
|
||||
|
||||
if (reserved_va) {
|
||||
mmap_next_start = reserved_va;
|
||||
}
|
||||
|
||||
{
|
||||
Error *err = NULL;
|
||||
if (seed_optarg != NULL) {
|
||||
|
||||
+350
-71
File diff suppressed because it is too large
Load Diff
+3
-2
@@ -105,7 +105,6 @@ typedef struct TaskState {
|
||||
|
||||
void init_task_state(TaskState *ts);
|
||||
extern const char *qemu_uname_release;
|
||||
extern unsigned long mmap_min_addr;
|
||||
|
||||
/*
|
||||
* TARGET_ARG_MAX defines the number of bytes allocated for arguments
|
||||
@@ -215,13 +214,15 @@ abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp);
|
||||
/* mmap.c */
|
||||
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, abi_ulong offset);
|
||||
int flags, int fd, off_t offset);
|
||||
int target_munmap(abi_ulong start, abi_ulong len);
|
||||
abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
|
||||
abi_ulong new_size, unsigned long flags,
|
||||
abi_ulong new_addr);
|
||||
int target_msync(abi_ulong start, abi_ulong len, int flags);
|
||||
extern unsigned long last_brk;
|
||||
extern abi_ulong mmap_next_start;
|
||||
abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size);
|
||||
void mmap_fork_start(void);
|
||||
void mmap_fork_end(int child);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user