@@ -23,23 +23,11 @@
extern unsigned long reserved_va;
/*
- * Limit the guest addresses as best we can.
- *
- * When not using -R reserved_va, we cannot really limit the guest
- * to less address space than the host. For 32-bit guests, this
- * acts as a sanity check that we're not giving the guest an address
- * that it cannot even represent. For 64-bit guests... the address
- * might not be what the real kernel would give, but it is at least
- * representable in the guest.
- *
- * TODO: Improve address allocation to avoid this problem, and to
- * avoid setting bits at the top of guest addresses that might need
- * to be used for tags.
+ * The last byte of the guest address space.
+ * If reserved_va is non-zero, guest_addr_max matches.
+ * If reserved_va is zero, guest_addr_max equals the full guest space.
*/
-#define GUEST_ADDR_MAX_ \
- ((MIN_CONST(TARGET_VIRT_ADDR_SPACE_BITS, TARGET_ABI_BITS) <= 32) ? \
- UINT32_MAX : ~0ul)
-#define GUEST_ADDR_MAX (reserved_va ? : GUEST_ADDR_MAX_)
+extern unsigned long guest_addr_max;
#ifndef TARGET_TAGGED_ADDRESSES
static inline abi_ptr cpu_untagged_addr(CPUState *cs, abi_ptr x)
@@ -61,17 +49,16 @@ static inline void *g2h(CPUState *cs, abi_ptr x)
static inline bool guest_addr_valid_untagged(abi_ulong x)
{
- return x <= GUEST_ADDR_MAX;
+ return x <= guest_addr_max;
}
static inline bool guest_range_valid_untagged(abi_ulong start, abi_ulong len)
{
- return len - 1 <= GUEST_ADDR_MAX && start <= GUEST_ADDR_MAX - len + 1;
+ return len - 1 <= guest_addr_max && start <= guest_addr_max - len + 1;
}
#define h2g_valid(x) \
- (HOST_LONG_BITS <= TARGET_VIRT_ADDR_SPACE_BITS || \
- (uintptr_t)(x) - guest_base <= GUEST_ADDR_MAX)
+ ((uintptr_t)(x) - guest_base <= guest_addr_max)
#define h2g_nocheck(x) ({ \
uintptr_t __ret = (uintptr_t)(x) - guest_base; \
@@ -500,7 +500,7 @@ void page_set_flags(vaddr start, vaddr last, int flags)
guest address space. If this assert fires, it probably indicates
a missing call to h2g_valid. */
assert(start <= last);
- assert(last <= GUEST_ADDR_MAX);
+ assert(last <= guest_addr_max);
/* Only set PAGE_ANON with new mappings. */
assert(!(flags & PAGE_ANON) || (flags & PAGE_RESET));
assert_memory_lock();
@@ -621,7 +621,7 @@ vaddr page_find_range_empty(vaddr min, vaddr max, vaddr len, vaddr align)
vaddr len_m1, align_m1;
assert(min <= max);
- assert(max <= GUEST_ADDR_MAX);
+ assert(max <= guest_addr_max);
assert(len != 0);
assert(is_power_of_2(align));
assert_memory_lock();
@@ -89,6 +89,7 @@ bool have_guest_base;
#endif
unsigned long reserved_va;
+unsigned long guest_addr_max;
const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
const char *qemu_uname_release;
@@ -500,6 +501,13 @@ int main(int argc, char **argv)
/* MAX_RESERVED_VA + 1 is a large power of 2, so is aligned. */
reserved_va = max_reserved_va;
}
+ if (reserved_va != 0) {
+ guest_addr_max = reserved_va;
+ } else if (MIN(TARGET_VIRT_ADDR_SPACE_BITS, TARGET_ABI_BITS) <= 32) {
+ guest_addr_max = UINT32_MAX;
+ } else {
+ guest_addr_max = ~0ul;
+ }
if (getenv("QEMU_STRACE")) {
do_strace = 1;
@@ -122,6 +122,7 @@ static const char *last_log_filename;
#endif
unsigned long reserved_va;
+unsigned long guest_addr_max;
static void usage(int exitcode);
@@ -858,6 +859,13 @@ int main(int argc, char **argv, char **envp)
/* MAX_RESERVED_VA + 1 is a large power of 2, so is aligned. */
reserved_va = max_reserved_va;
}
+ if (reserved_va != 0) {
+ guest_addr_max = reserved_va;
+ } else if (MIN(TARGET_VIRT_ADDR_SPACE_BITS, TARGET_ABI_BITS) <= 32) {
+ guest_addr_max = UINT32_MAX;
+ } else {
+ guest_addr_max = ~0ul;
+ }
/*
* Temporarily disable