|
52 | 52 | #include "target_arch_cpu.h"
|
53 | 53 |
|
54 | 54 | int singlestep;
|
55 |
| -unsigned long mmap_min_addr; |
56 | 55 | uintptr_t guest_base;
|
57 | 56 | 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 |
58 | 94 | unsigned long reserved_va;
|
| 95 | +#endif |
59 | 96 |
|
60 | 97 | static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
|
61 | 98 | const char *qemu_uname_release;
|
@@ -439,6 +476,10 @@ int main(int argc, char **argv)
|
439 | 476 | target_environ = envlist_to_environ(envlist, NULL);
|
440 | 477 | envlist_free(envlist);
|
441 | 478 |
|
| 479 | + if (reserved_va) { |
| 480 | + mmap_next_start = reserved_va; |
| 481 | + } |
| 482 | + |
442 | 483 | {
|
443 | 484 | Error *err = NULL;
|
444 | 485 | if (seed_optarg != NULL) {
|
|
0 commit comments