1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 /*
3 * guest <-> host helpers.
4 *
5 * Copyright (c) 2003 Fabrice Bellard
6 */
7
8 #ifndef USER_GUEST_HOST_H
9 #define USER_GUEST_HOST_H
10
11 #include "user/abitypes.h"
12 #include "user/guest-base.h"
13 #include "cpu.h"
14
15 /*
16 * If non-zero, the guest virtual address space is a contiguous subset
17 * of the host virtual address space, i.e. '-R reserved_va' is in effect
18 * either from the command-line or by default. The value is the last
19 * byte of the guest address space e.g. UINT32_MAX.
20 *
21 * If zero, the host and guest virtual address spaces are intermingled.
22 */
23 extern unsigned long reserved_va;
24
25 /*
26 * Limit the guest addresses as best we can.
27 *
28 * When not using -R reserved_va, we cannot really limit the guest
29 * to less address space than the host. For 32-bit guests, this
30 * acts as a sanity check that we're not giving the guest an address
31 * that it cannot even represent. For 64-bit guests... the address
32 * might not be what the real kernel would give, but it is at least
33 * representable in the guest.
34 *
35 * TODO: Improve address allocation to avoid this problem, and to
36 * avoid setting bits at the top of guest addresses that might need
37 * to be used for tags.
38 */
39 #define GUEST_ADDR_MAX_ \
40 ((MIN_CONST(TARGET_VIRT_ADDR_SPACE_BITS, TARGET_ABI_BITS) <= 32) ? \
41 UINT32_MAX : ~0ul)
42 #define GUEST_ADDR_MAX (reserved_va ? : GUEST_ADDR_MAX_)
43
44 #ifndef TARGET_TAGGED_ADDRESSES
cpu_untagged_addr(CPUState * cs,abi_ptr x)45 static inline abi_ptr cpu_untagged_addr(CPUState *cs, abi_ptr x)
46 {
47 return x;
48 }
49 #endif
50
51 /* All direct uses of g2h and h2g need to go away for usermode softmmu. */
g2h_untagged(abi_ptr x)52 static inline void *g2h_untagged(abi_ptr x)
53 {
54 return (void *)((uintptr_t)(x) + guest_base);
55 }
56
g2h(CPUState * cs,abi_ptr x)57 static inline void *g2h(CPUState *cs, abi_ptr x)
58 {
59 return g2h_untagged(cpu_untagged_addr(cs, x));
60 }
61
guest_addr_valid_untagged(abi_ulong x)62 static inline bool guest_addr_valid_untagged(abi_ulong x)
63 {
64 return x <= GUEST_ADDR_MAX;
65 }
66
guest_range_valid_untagged(abi_ulong start,abi_ulong len)67 static inline bool guest_range_valid_untagged(abi_ulong start, abi_ulong len)
68 {
69 return len - 1 <= GUEST_ADDR_MAX && start <= GUEST_ADDR_MAX - len + 1;
70 }
71
72 #define h2g_valid(x) \
73 (HOST_LONG_BITS <= TARGET_VIRT_ADDR_SPACE_BITS || \
74 (uintptr_t)(x) - guest_base <= GUEST_ADDR_MAX)
75
76 #define h2g_nocheck(x) ({ \
77 uintptr_t __ret = (uintptr_t)(x) - guest_base; \
78 (abi_ptr)__ret; \
79 })
80
81 #define h2g(x) ({ \
82 /* Check if given address fits target address space */ \
83 assert(h2g_valid(x)); \
84 h2g_nocheck(x); \
85 })
86
87 #endif
88