master
h 128 lines 3.44 KB
Raw
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 "hw/core/cpu.h"
14 #include "accel/tcg/cpu-ops.h"
15
16 /*
17 * If non-zero, the guest virtual address space is a contiguous subset
18 * of the host virtual address space, i.e. '-R reserved_va' is in effect
19 * either from the command-line or by default. The value is the last
20 * byte of the guest address space e.g. UINT32_MAX.
21 *
22 * If zero, the host and guest virtual address spaces are intermingled.
23 */
24 extern unsigned long reserved_va;
25
26 /*
27 * The last byte of the guest address space.
28 * If reserved_va is non-zero, guest_addr_max matches.
29 * If reserved_va is zero, guest_addr_max equals the full guest space.
30 */
31 extern unsigned long guest_addr_max;
32
33 /*
34 * These functions take the guest virtual address as a vaddr,
35 * and are suitable for use from target-independent code.
36 */
37
38 static inline vaddr cpu_untagged_addr_vaddr(CPUState *cs, vaddr x)
39 {
40 const TCGCPUOps *tcg_ops = cs->cc->tcg_ops;
41 if (tcg_ops->untagged_addr) {
42 return tcg_ops->untagged_addr(cs, x);
43 }
44 return x;
45 }
46
47 /* All direct uses of g2h and h2g need to go away for usermode softmmu. */
48 static inline void *g2h_untagged_vaddr(vaddr x)
49 {
50 return (void *)((uintptr_t)(x) + guest_base);
51 }
52
53 static inline void *g2h_vaddr(CPUState *cs, vaddr x)
54 {
55 return g2h_untagged_vaddr(cpu_untagged_addr_vaddr(cs, x));
56 }
57
58 static inline bool guest_addr_valid_untagged_vaddr(vaddr x)
59 {
60 return x <= guest_addr_max;
61 }
62
63 static inline bool guest_range_valid_untagged_vaddr(vaddr start, vaddr len)
64 {
65 return len - 1 <= guest_addr_max && start <= guest_addr_max - len + 1;
66 }
67
68 #define h2g_valid(x) \
69 ((uintptr_t)(x) - guest_base <= guest_addr_max)
70
71 #define h2g_nocheck(x) ({ \
72 uintptr_t __ret = (uintptr_t)(x) - guest_base; \
73 (vaddr)__ret; \
74 })
75
76 #define h2g(x) ({ \
77 /* Check if given address fits target address space */ \
78 assert(h2g_valid(x)); \
79 h2g_nocheck(x); \
80 })
81
82 #ifdef COMPILING_PER_TARGET
83 #include "exec/abi_ptr.h"
84
85 /*
86 * These functions take the guest virtual address as an abi_ptr. This
87 * is an important difference from a vaddr for the common case where
88 * the address is a syscall argument in a variable of type abi_long,
89 * which may be smaller than the vaddr type. If you pass an address in
90 * an abi_long to these functions then the value will be converted to
91 * an unsigned type and then zero extended to give the vaddr. If you
92 * use the g2h_vaddr() and similar functions which take an argument of
93 * type vaddr, then the value will be sign-extended, giving the wrong
94 * answer for addresses above the 2GB mark on 32-bit guests.
95 *
96 * Providing these functions with their traditional QEMU semantics is
97 * less bug-prone than requiring many callsites to remember to cast
98 * their abi_long variable to an abi_ptr before calling.
99 */
100
101 static inline void *g2h(CPUState *cs, abi_ptr x)
102 {
103 return g2h_vaddr(cs, x);
104 }
105
106 static inline void *g2h_untagged(abi_ptr x)
107 {
108 return g2h_untagged_vaddr(x);
109 }
110
111 static inline bool guest_addr_valid_untagged(abi_ptr x)
112 {
113 return guest_addr_valid_untagged_vaddr(x);
114 }
115
116 static inline bool guest_range_valid_untagged(abi_ptr start, abi_ptr len)
117 {
118 return guest_range_valid_untagged_vaddr(start, len);
119 }
120
121 static inline abi_ptr cpu_untagged_addr(CPUState *cs, abi_ptr x)
122 {
123 return cpu_untagged_addr_vaddr(cs, x);
124 }
125
126 #endif
127
128 #endif