diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2023-07-27 09:11:48 -0700 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2023-07-31 12:19:13 -0700 |
commit | 28b61d49ac80bac8ef74aff0b75058bdd0b2f108 (patch) | |
tree | 0977685b89a4ff2b5f89de5155ae8e5c06de6633 /bsd-user/main.c | |
parent | ad17868eb162a5466d8ad43e5ccb428776403308 (diff) | |
download | qemu-28b61d49ac80bac8ef74aff0b75058bdd0b2f108.zip qemu-28b61d49ac80bac8ef74aff0b75058bdd0b2f108.tar.gz qemu-28b61d49ac80bac8ef74aff0b75058bdd0b2f108.tar.bz2 |
bsd-user: Allocate guest virtual address space
With reserved_va, mmap.c expects to have pre-allocated host address
space for the entire guest address space. When combined with the -B
command-line option, ensure that the chosen address does not overlap
anything else. Ensure that mmap_next_start is within reserved_va,
as we use it within mmap.c without checking.
Reviewed by: Warner Losh <imp@bsdimp.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20230727161148.444988-1-richard.henderson@linaro.org>
Diffstat (limited to 'bsd-user/main.c')
-rw-r--r-- | bsd-user/main.c | 48 |
1 files changed, 43 insertions, 5 deletions
diff --git a/bsd-user/main.c b/bsd-user/main.c index b597328..381bb18 100644 --- a/bsd-user/main.c +++ b/bsd-user/main.c @@ -473,10 +473,6 @@ int main(int argc, char **argv) target_environ = envlist_to_environ(envlist, NULL); envlist_free(envlist); - if (reserved_va) { - mmap_next_start = reserved_va + 1; - } - { Error *err = NULL; if (seed_optarg != NULL) { @@ -494,7 +490,49 @@ int main(int argc, char **argv) * Now that page sizes are configured we can do * proper page alignment for guest_base. */ - guest_base = HOST_PAGE_ALIGN(guest_base); + if (have_guest_base) { + if (guest_base & ~qemu_host_page_mask) { + error_report("Selected guest base not host page aligned"); + exit(1); + } + } + + /* + * If reserving host virtual address space, do so now. + * Combined with '-B', ensure that the chosen range is free. + */ + if (reserved_va) { + void *p; + + if (have_guest_base) { + p = mmap((void *)guest_base, reserved_va + 1, PROT_NONE, + MAP_ANON | MAP_PRIVATE | MAP_FIXED | MAP_EXCL, -1, 0); + } else { + p = mmap(NULL, reserved_va + 1, PROT_NONE, + MAP_ANON | MAP_PRIVATE, -1, 0); + } + if (p == MAP_FAILED) { + const char *err = strerror(errno); + char *sz = size_to_str(reserved_va + 1); + + if (have_guest_base) { + error_report("Cannot allocate %s bytes at -B %p for guest " + "address space: %s", sz, (void *)guest_base, err); + } else { + error_report("Cannot allocate %s bytes for guest " + "address space: %s", sz, err); + } + exit(1); + } + guest_base = (uintptr_t)p; + have_guest_base = true; + + /* Ensure that mmap_next_start is within range. */ + if (reserved_va <= mmap_next_start) { + mmap_next_start = (reserved_va / 4 * 3) + & TARGET_PAGE_MASK & qemu_host_page_mask; + } + } if (loader_exec(filename, argv + optind, target_environ, regs, info, &bprm) != 0) { |