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 "exec/vaddr.h" 12 #include "user/guest-base.h" 13 #include "accel/tcg/cpu-ops.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 * The last byte of the guest address space. 27 * If reserved_va is non-zero, guest_addr_max matches. 28 * If reserved_va is zero, guest_addr_max equals the full guest space. 29 */ 30 extern unsigned long guest_addr_max; 31 32 static inline vaddr cpu_untagged_addr(CPUState *cs, vaddr x) 33 { 34 const TCGCPUOps *tcg_ops = cs->cc->tcg_ops; 35 if (tcg_ops->untagged_addr) { 36 return tcg_ops->untagged_addr(cs, x); 37 } 38 return x; 39 } 40 41 /* All direct uses of g2h and h2g need to go away for usermode softmmu. */ 42 static inline void *g2h_untagged(vaddr x) 43 { 44 return (void *)((uintptr_t)(x) + guest_base); 45 } 46 47 static inline void *g2h(CPUState *cs, vaddr x) 48 { 49 return g2h_untagged(cpu_untagged_addr(cs, x)); 50 } 51 52 static inline bool guest_addr_valid_untagged(vaddr x) 53 { 54 return x <= guest_addr_max; 55 } 56 57 static inline bool guest_range_valid_untagged(vaddr start, vaddr len) 58 { 59 return len - 1 <= guest_addr_max && start <= guest_addr_max - len + 1; 60 } 61 62 #define h2g_valid(x) \ 63 ((uintptr_t)(x) - guest_base <= guest_addr_max) 64 65 #define h2g_nocheck(x) ({ \ 66 uintptr_t __ret = (uintptr_t)(x) - guest_base; \ 67 (vaddr)__ret; \ 68 }) 69 70 #define h2g(x) ({ \ 71 /* Check if given address fits target address space */ \ 72 assert(h2g_valid(x)); \ 73 h2g_nocheck(x); \ 74 }) 75 76 #endif 77