[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v3 65/66] tcg/riscv: Support raising sigbus for user-only
From: |
Richard Henderson |
Subject: |
[PATCH v3 65/66] tcg/riscv: Support raising sigbus for user-only |
Date: |
Wed, 18 Aug 2021 09:19:19 -1000 |
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
tcg/riscv/tcg-target.h | 2 --
tcg/riscv/tcg-target.c.inc | 64 +++++++++++++++++++++++++++++++++++---
2 files changed, 60 insertions(+), 6 deletions(-)
diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
index ef78b99e98..11c9b3e4f4 100644
--- a/tcg/riscv/tcg-target.h
+++ b/tcg/riscv/tcg-target.h
@@ -165,9 +165,7 @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t,
uintptr_t, uintptr_t);
#define TCG_TARGET_DEFAULT_MO (0)
-#ifdef CONFIG_SOFTMMU
#define TCG_TARGET_NEED_LDST_LABELS
-#endif
#define TCG_TARGET_NEED_POOL_LABELS
#define TCG_TARGET_HAS_MEMORY_BSWAP 0
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
index c1b0c3764d..f75dcf88f8 100644
--- a/tcg/riscv/tcg-target.c.inc
+++ b/tcg/riscv/tcg-target.c.inc
@@ -27,6 +27,7 @@
* THE SOFTWARE.
*/
+#include "../tcg-ldst.c.inc"
#include "../tcg-pool.c.inc"
#ifdef CONFIG_DEBUG_TCG
@@ -847,8 +848,6 @@ static void tcg_out_mb(TCGContext *s, TCGArg a0)
*/
#if defined(CONFIG_SOFTMMU)
-#include "../tcg-ldst.c.inc"
-
/* helper signature: helper_ret_ld_mmu(CPUState *env, target_ulong addr,
* MemOpIdx oi, uintptr_t ra)
*/
@@ -1053,6 +1052,53 @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s,
TCGLabelQemuLdst *l)
tcg_out_goto(s, l->raddr);
return true;
}
+#else
+
+static void tcg_out_test_alignment(TCGContext *s, bool is_ld, TCGReg addr_reg,
+ unsigned a_bits)
+{
+ unsigned a_mask = (1 << a_bits) - 1;
+ TCGLabelQemuLdst *l = new_ldst_label(s);
+
+ l->is_ld = is_ld;
+ l->addrlo_reg = addr_reg;
+
+ /* We are expecting a_bits to max out at 7, so we can always use andi. */
+ tcg_debug_assert(a_bits < 12);
+ tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_TMP1, addr_reg, a_mask);
+
+ l->label_ptr[0] = s->code_ptr;
+ tcg_out_opc_branch(s, OPC_BNE, TCG_REG_TMP1, TCG_REG_ZERO, 0);
+
+ l->raddr = tcg_splitwx_to_rx(s->code_ptr);
+}
+
+static bool tcg_out_fail_alignment(TCGContext *s, TCGLabelQemuLdst *l)
+{
+ /* resolve label address */
+ if (!reloc_sbimm12(l->label_ptr[0], tcg_splitwx_to_rx(s->code_ptr))) {
+ return false;
+ }
+
+ tcg_out_mov(s, TCG_TYPE_TL, TCG_REG_A1, l->addrlo_reg);
+ tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_A0, TCG_AREG0);
+ /* tail call, with the return address back inline for unwinding */
+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_RA, (uintptr_t)l->raddr);
+ tcg_out_call_int(s, (const void *)(l->is_ld ? helper_unaligned_ld
+ : helper_unaligned_st), true);
+ return true;
+}
+
+static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
+{
+ return tcg_out_fail_alignment(s, l);
+}
+
+static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
+{
+ return tcg_out_fail_alignment(s, l);
+}
+
#endif /* CONFIG_SOFTMMU */
static void tcg_out_qemu_ld_direct(TCGContext *s, TCGReg lo, TCGReg hi,
@@ -1108,6 +1154,8 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg
*args, bool is_64)
MemOp opc;
#if defined(CONFIG_SOFTMMU)
tcg_insn_unit *label_ptr[1];
+#else
+ unsigned a_bits;
#endif
TCGReg base = TCG_REG_TMP0;
@@ -1130,7 +1178,10 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg
*args, bool is_64)
tcg_out_ext32u(s, base, addr_regl);
addr_regl = base;
}
-
+ a_bits = get_alignment_bits(opc);
+ if (a_bits) {
+ tcg_out_test_alignment(s, true, addr_regl, a_bits);
+ }
if (guest_base == 0) {
tcg_out_opc_reg(s, OPC_ADD, base, addr_regl, TCG_REG_ZERO);
} else {
@@ -1177,6 +1228,8 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg
*args, bool is_64)
MemOp opc;
#if defined(CONFIG_SOFTMMU)
tcg_insn_unit *label_ptr[1];
+#else
+ unsigned a_bits;
#endif
TCGReg base = TCG_REG_TMP0;
@@ -1199,7 +1252,10 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg
*args, bool is_64)
tcg_out_ext32u(s, base, addr_regl);
addr_regl = base;
}
-
+ a_bits = get_alignment_bits(opc);
+ if (a_bits) {
+ tcg_out_test_alignment(s, false, addr_regl, a_bits);
+ }
if (guest_base == 0) {
tcg_out_opc_reg(s, OPC_ADD, base, addr_regl, TCG_REG_ZERO);
} else {
--
2.25.1
- Re: [PATCH v3 62/66] tcg/s390: Support raising sigbus for user-only, (continued)
[PATCH v3 64/66] tcg: Canonicalize alignment flags in MemOp, Richard Henderson, 2021/08/18
[PATCH v3 65/66] tcg/riscv: Support raising sigbus for user-only,
Richard Henderson <=
[PATCH v3 66/66] tcg/riscv: Remove add with zero on user-only memory access, Richard Henderson, 2021/08/18