aboutsummaryrefslogtreecommitdiff
path: root/include/exec/cpu_ldst.h
diff options
context:
space:
mode:
authorLaurent Vivier <laurent@vivier.eu>2018-08-14 19:12:17 +0200
committerLaurent Vivier <laurent@vivier.eu>2018-08-17 13:56:33 +0200
commit3e23de15237c81fe7af7c3ffa299a6ae5fec7d43 (patch)
tree41b0808ca14091f7d436b1bd4c72c7065d24c263 /include/exec/cpu_ldst.h
parentb8dbfc9cc662ba05ea0b8ffc4598e422b76fbcbd (diff)
linux-user: fix 32bit g2h()/h2g()
sparc32plus has 64bit long type but only 32bit virtual address space. For instance, "apt-get upgrade" failed because of a mmap()/msync() sequence. mmap() returned 0xff252000 but msync() used g2h(0xffffffffff252000) to find the host address. The "(target_ulong)" in g2h() doesn't fix the address because it is 64bit long. This patch introduces an "abi_ptr" that is set to uint32_t if the virtual address space is addressed using 32bit in the linux-user case. It stays set to target_ulong with softmmu case. Signed-off-by: Laurent Vivier <laurent@vivier.eu> Message-Id: <20180814171217.14680-1-laurent@vivier.eu> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> [lv: added "%" in TARGET_ABI_FMT_ptr "%"PRIx64]
Diffstat (limited to 'include/exec/cpu_ldst.h')
-rw-r--r--include/exec/cpu_ldst.h23
1 files changed, 18 insertions, 5 deletions
diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h
index 0f2cb717b1..41ed0526e2 100644
--- a/include/exec/cpu_ldst.h
+++ b/include/exec/cpu_ldst.h
@@ -48,8 +48,19 @@
#define CPU_LDST_H
#if defined(CONFIG_USER_ONLY)
+/* sparc32plus has 64bit long but 32bit space address
+ * this can make bad result with g2h() and h2g()
+ */
+#if TARGET_VIRT_ADDR_SPACE_BITS <= 32
+typedef uint32_t abi_ptr;
+#define TARGET_ABI_FMT_ptr "%x"
+#else
+typedef uint64_t abi_ptr;
+#define TARGET_ABI_FMT_ptr "%"PRIx64
+#endif
+
/* All direct uses of g2h and h2g need to go away for usermode softmmu. */
-#define g2h(x) ((void *)((unsigned long)(target_ulong)(x) + guest_base))
+#define g2h(x) ((void *)((unsigned long)(abi_ptr)(x) + guest_base))
#define guest_addr_valid(x) ((x) <= GUEST_ADDR_MAX)
#define h2g_valid(x) guest_addr_valid((unsigned long)(x) - guest_base)
@@ -61,7 +72,7 @@ static inline int guest_range_valid(unsigned long start, unsigned long len)
#define h2g_nocheck(x) ({ \
unsigned long __ret = (unsigned long)(x) - guest_base; \
- (abi_ulong)__ret; \
+ (abi_ptr)__ret; \
})
#define h2g(x) ({ \
@@ -69,7 +80,9 @@ static inline int guest_range_valid(unsigned long start, unsigned long len)
assert(h2g_valid(x)); \
h2g_nocheck(x); \
})
-
+#else
+typedef target_ulong abi_ptr;
+#define TARGET_ABI_FMT_ptr TARGET_ABI_FMT_lx
#endif
#if defined(CONFIG_USER_ONLY)
@@ -397,7 +410,7 @@ extern __thread uintptr_t helper_retaddr;
* This is the equivalent of the initial fast-path code used by
* TCG backends for guest load and store accesses.
*/
-static inline void *tlb_vaddr_to_host(CPUArchState *env, target_ulong addr,
+static inline void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr,
int access_type, int mmu_idx)
{
#if defined(CONFIG_USER_ONLY)
@@ -405,7 +418,7 @@ static inline void *tlb_vaddr_to_host(CPUArchState *env, target_ulong addr,
#else
int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
CPUTLBEntry *tlbentry = &env->tlb_table[mmu_idx][index];
- target_ulong tlb_addr;
+ abi_ptr tlb_addr;
uintptr_t haddr;
switch (access_type) {