aboutsummaryrefslogtreecommitdiff
path: root/include/exec/cpu_ldst.h
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2023-03-24 13:02:59 -0700
committerRichard Henderson <richard.henderson@linaro.org>2023-06-05 12:04:28 -0700
commit238f43809a85a47cfbbc2e1d6aff4640fec30328 (patch)
treed60c778ef821469bde1ba5ed8fe18169fc2941e6 /include/exec/cpu_ldst.h
parentff0c61bf35fbeffd5c0f85a0b67b49ccb65e04f5 (diff)
tcg: Widen CPUTLBEntry comparators to 64-bits
This makes CPUTLBEntry agnostic to the address size of the guest. When 32-bit addresses are in effect, we can simply read the low 32 bits of the 64-bit field. Similarly when we need to update the field for setting TLB_NOTDIRTY. For TCG backends that could in theory be big-endian, but in practice are not (arm, loongarch, riscv), use QEMU_BUILD_BUG_ON to document and ensure this is not accidentally missed. For s390x, which is always big-endian, use HOST_BIG_ENDIAN anyway, to document the reason for the adjustment. For sparc64 and ppc64, always perform a 64-bit load, and rely on the following 32-bit comparison to ignore the high bits. Rearrange mips and ppc if ladders for clarity. Reviewed-by: Anton Johansson <anjo@rev.ng> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'include/exec/cpu_ldst.h')
-rw-r--r--include/exec/cpu_ldst.h19
1 files changed, 13 insertions, 6 deletions
diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h
index 5939688f69..a43b34e46b 100644
--- a/include/exec/cpu_ldst.h
+++ b/include/exec/cpu_ldst.h
@@ -334,18 +334,25 @@ static inline target_ulong tlb_read_idx(const CPUTLBEntry *entry,
{
/* Do not rearrange the CPUTLBEntry structure members. */
QEMU_BUILD_BUG_ON(offsetof(CPUTLBEntry, addr_read) !=
- MMU_DATA_LOAD * TARGET_LONG_SIZE);
+ MMU_DATA_LOAD * sizeof(uint64_t));
QEMU_BUILD_BUG_ON(offsetof(CPUTLBEntry, addr_write) !=
- MMU_DATA_STORE * TARGET_LONG_SIZE);
+ MMU_DATA_STORE * sizeof(uint64_t));
QEMU_BUILD_BUG_ON(offsetof(CPUTLBEntry, addr_code) !=
- MMU_INST_FETCH * TARGET_LONG_SIZE);
+ MMU_INST_FETCH * sizeof(uint64_t));
- const target_ulong *ptr = &entry->addr_idx[access_type];
-#if TCG_OVERSIZED_GUEST
- return *ptr;
+#if TARGET_LONG_BITS == 32
+ /* Use qatomic_read, in case of addr_write; only care about low bits. */
+ const uint32_t *ptr = (uint32_t *)&entry->addr_idx[access_type];
+ ptr += HOST_BIG_ENDIAN;
+ return qatomic_read(ptr);
#else
+ const uint64_t *ptr = &entry->addr_idx[access_type];
+# if TCG_OVERSIZED_GUEST
+ return *ptr;
+# else
/* ofs might correspond to .addr_write, so use qatomic_read */
return qatomic_read(ptr);
+# endif
#endif
}