include/user: Convert GUEST_ADDR_MAX to a variable

Remove GUEST_ADDR_MAX and add guest_addr_max.
Initialize it in *-user/main.c, after reserved_va.

Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2025-04-30 18:07:47 -07:00
parent 0566f364f7
commit 30da476066
4 changed files with 25 additions and 22 deletions

View file

@ -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();

View file

@ -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;

View file

@ -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; \

View file

@ -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