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 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. */ 52 static inline void *g2h_untagged(abi_ptr x) 53 { 54 return (void *)((uintptr_t)(x) + guest_base); 55 } 56 57 static inline void *g2h(CPUState *cs, abi_ptr x) 58 { 59 return g2h_untagged(cpu_untagged_addr(cs, x)); 60 } 61 62 static inline bool guest_addr_valid_untagged(abi_ulong x) 63 { 64 return x <= GUEST_ADDR_MAX; 65 } 66 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