提交 ee947430 编写于 作者: A Alex Bennée

linux-user: completely re-write init_guest_space

First we ensure all guest space initialisation logic comes through
probe_guest_base once we understand the nature of the binary we are
loading. The convoluted init_guest_space routine is removed and
replaced with a number of pgb_* helpers which are called depending on
what requirements we have when loading the binary.

We first try to do what is requested by the host. Failing that we try
and satisfy the guest requested base address. If all those options
fail we fall back to finding a space in the memory map using our
recently written read_self_maps() helper.

There are some additional complications we try and take into account
when looking for holes in the address space. We try not to go directly
after the system brk() space so there is space for a little growth. We
also don't want to have to use negative offsets which would result in
slightly less efficient code on x86 when it's unable to use the
segment offset register.

Less mind-binding gotos and hopefully clearer logic throughout.
Signed-off-by: NAlex Bennée <alex.bennee@linaro.org>
Acked-by: NLaurent Vivier <laurent@vivier.eu>

Message-Id: <20200513175134.19619-5-alex.bennee@linaro.org>
上级 aae8b87e
此差异已折叠。
......@@ -441,6 +441,12 @@ static int load_flat_file(struct linux_binprm * bprm,
indx_len = MAX_SHARED_LIBS * sizeof(abi_ulong);
indx_len = (indx_len + 15) & ~(abi_ulong)15;
/*
* Alloate the address space.
*/
probe_guest_base(bprm->filename, 0,
text_len + data_len + extra + indx_len);
/*
* there are a couple of cases here, the separate code/data
* case, and then the fully copied to RAM case which lumps
......
......@@ -24,6 +24,7 @@
#include "qemu-version.h"
#include <sys/syscall.h>
#include <sys/resource.h>
#include <sys/shm.h>
#include "qapi/error.h"
#include "qemu.h"
......@@ -747,28 +748,6 @@ int main(int argc, char **argv, char **envp)
target_environ = envlist_to_environ(envlist, NULL);
envlist_free(envlist);
/*
* Now that page sizes are configured in tcg_exec_init() we can do
* proper page alignment for guest_base.
*/
guest_base = HOST_PAGE_ALIGN(guest_base);
if (reserved_va || have_guest_base) {
guest_base = init_guest_space(guest_base, reserved_va, 0,
have_guest_base);
if (guest_base == (unsigned long)-1) {
fprintf(stderr, "Unable to reserve 0x%lx bytes of virtual address "
"space for use as guest address space (check your virtual "
"memory ulimit setting or reserve less using -R option)\n",
reserved_va);
exit(EXIT_FAILURE);
}
if (reserved_va) {
mmap_next_start = reserved_va;
}
}
/*
* Read in mmap_min_addr kernel parameter. This value is used
* When loading the ELF image to determine whether guest_base
......
......@@ -219,18 +219,27 @@ void init_qemu_uname_release(void);
void fork_start(void);
void fork_end(int child);
/* Creates the initial guest address space in the host memory space using
* the given host start address hint and size. The guest_start parameter
* specifies the start address of the guest space. guest_base will be the
* difference between the host start address computed by this function and
* guest_start. If fixed is specified, then the mapped address space must
* start at host_start. The real start address of the mapped memory space is
* returned or -1 if there was an error.
/**
* probe_guest_base:
* @image_name: the executable being loaded
* @loaddr: the lowest fixed address in the executable
* @hiaddr: the highest fixed address in the executable
*
* Creates the initial guest address space in the host memory space.
*
* If @loaddr == 0, then no address in the executable is fixed,
* i.e. it is fully relocatable. In that case @hiaddr is the size
* of the executable.
*
* This function will not return if a valid value for guest_base
* cannot be chosen. On return, the executable loader can expect
*
* target_mmap(loaddr, hiaddr - loaddr, ...)
*
* to succeed.
*/
unsigned long init_guest_space(unsigned long host_start,
unsigned long host_size,
unsigned long guest_start,
bool fixed);
void probe_guest_base(const char *image_name,
abi_ulong loaddr, abi_ulong hiaddr);
#include "qemu/log.h"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册