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