[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 27/33] target/arm: Add v8M stack checks for LDRD/STRD
From: |
Peter Maydell |
Subject: |
[Qemu-devel] [PULL 27/33] target/arm: Add v8M stack checks for LDRD/STRD (imm) |
Date: |
Mon, 8 Oct 2018 14:59:58 +0100 |
Add the v8M stack checks for:
* LDRD (immediate)
* STRD (immediate)
Loads and stores are more complicated than ADD/SUB/MOV, because we
must ensure that memory accesses below the stack limit are not
performed, so we can't simply do the check when we actually update
SP.
For these instructions, if the stack limit check triggers
we must not:
* perform any memory access below the SP limit
* update PC, SP or the load/store base register
but it is IMPDEF whether we:
* perform any accesses above or equal to the SP limit
* update destination registers for loads
For QEMU we choose to always check the limit before doing any other
part of the load or store, so we won't update any registers or
perform any memory accesses.
It is UNKNOWN whether the limit check triggers for a load or store
where the initial SP value is below the limit and one of the stores
would be below the limit, but the writeback moves SP to above the
limit. For QEMU we choose to trigger the check in this situation.
Note that limit checks happen only for loads and stores which update
SP via writeback; they do not happen for loads and stores which
simply use SP as a base register.
Signed-off-by: Peter Maydell <address@hidden>
Reviewed-by: Philippe Mathieu-Daudé <address@hidden>
Reviewed-by: Richard Henderson <address@hidden>
Message-id: address@hidden
---
target/arm/translate.c | 27 +++++++++++++++++++++++++--
1 file changed, 25 insertions(+), 2 deletions(-)
diff --git a/target/arm/translate.c b/target/arm/translate.c
index fcb33b8a503..c16d6075d94 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -10278,6 +10278,8 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t
insn)
* 0b1111_1001_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
* - load/store dual (pre-indexed)
*/
+ bool wback = extract32(insn, 21, 1);
+
if (rn == 15) {
if (insn & (1 << 21)) {
/* UNPREDICTABLE */
@@ -10289,8 +10291,29 @@ static void disas_thumb2_insn(DisasContext *s,
uint32_t insn)
addr = load_reg(s, rn);
}
offset = (insn & 0xff) * 4;
- if ((insn & (1 << 23)) == 0)
+ if ((insn & (1 << 23)) == 0) {
offset = -offset;
+ }
+
+ if (s->v8m_stackcheck && rn == 13 && wback) {
+ /*
+ * Here 'addr' is the current SP; if offset is +ve we're
+ * moving SP up, else down. It is UNKNOWN whether the limit
+ * check triggers when SP starts below the limit and ends
+ * up above it; check whichever of the current and final
+ * SP is lower, so QEMU will trigger in that situation.
+ */
+ if ((int32_t)offset < 0) {
+ TCGv_i32 newsp = tcg_temp_new_i32();
+
+ tcg_gen_addi_i32(newsp, addr, offset);
+ gen_helper_v8m_stackcheck(cpu_env, newsp);
+ tcg_temp_free_i32(newsp);
+ } else {
+ gen_helper_v8m_stackcheck(cpu_env, addr);
+ }
+ }
+
if (insn & (1 << 24)) {
tcg_gen_addi_i32(addr, addr, offset);
offset = 0;
@@ -10314,7 +10337,7 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t
insn)
gen_aa32_st32(s, tmp, addr, get_mem_index(s));
tcg_temp_free_i32(tmp);
}
- if (insn & (1 << 21)) {
+ if (wback) {
/* Base writeback. */
tcg_gen_addi_i32(addr, addr, offset - 4);
store_reg(s, rn, addr);
--
2.19.0
- [Qemu-devel] [PULL 08/33] target/arm: Handle SVE vector length changes in system mode, (continued)
- [Qemu-devel] [PULL 08/33] target/arm: Handle SVE vector length changes in system mode, Peter Maydell, 2018/10/08
- [Qemu-devel] [PULL 13/33] target/arm: Rewrite helper_sve_st[1234]*_r, Peter Maydell, 2018/10/08
- [Qemu-devel] [PULL 32/33] target/arm: Add v8M stack checks for MSR to SP_NS, Peter Maydell, 2018/10/08
- [Qemu-devel] [PULL 33/33] hw/display/bcm2835_fb: Silence Coverity warning about multiply overflow, Peter Maydell, 2018/10/08
- [Qemu-devel] [PULL 31/33] target/arm: Add v8M stack checks for VLDM/VSTM, Peter Maydell, 2018/10/08
- [Qemu-devel] [PULL 29/33] target/arm: Add v8M stack checks for T32 load/store single, Peter Maydell, 2018/10/08
- [Qemu-devel] [PULL 30/33] target/arm: Add v8M stack checks for Thumb push/pop, Peter Maydell, 2018/10/08
- [Qemu-devel] [PULL 24/33] target/arm: Add some comments in Thumb decode, Peter Maydell, 2018/10/08
- [Qemu-devel] [PULL 25/33] target/arm: Add v8M stack checks on exception entry, Peter Maydell, 2018/10/08
- [Qemu-devel] [PULL 28/33] target/arm: Add v8M stack checks for Thumb2 LDM/STM, Peter Maydell, 2018/10/08
- [Qemu-devel] [PULL 27/33] target/arm: Add v8M stack checks for LDRD/STRD (imm),
Peter Maydell <=
- [Qemu-devel] [PULL 26/33] target/arm: Add v8M stack limit checks on NS function calls, Peter Maydell, 2018/10/08
- [Qemu-devel] [PULL 03/33] target/arm: Correct condition for v8M callee stack push, Peter Maydell, 2018/10/08
- [Qemu-devel] [PULL 06/33] target/arm: Adjust sve_exception_el, Peter Maydell, 2018/10/08
- [Qemu-devel] [PULL 05/33] target/arm: Define ID_AA64ZFR0_EL1, Peter Maydell, 2018/10/08
- [Qemu-devel] [PULL 04/33] target/arm: Don't read r4 from v8M exception stackframe twice, Peter Maydell, 2018/10/08
- [Qemu-devel] [PULL 07/33] target/arm: Pass in current_el to fp and sve_exception_el, Peter Maydell, 2018/10/08
- [Qemu-devel] [PULL 02/33] virt: Suppress external aborts on virt-2.10 and earlier, Peter Maydell, 2018/10/08
- [Qemu-devel] [PULL 01/33] target/arm: fix code comments error, Peter Maydell, 2018/10/08
- Re: [Qemu-devel] [PULL 00/33] target-arm queue, Peter Maydell, 2018/10/08