From 39466771d669ebf3904fb0cf22fc32bebc9894aa Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 5 Mar 2018 01:47:23 -0500 Subject: [PATCH] target/arm: Add support for restoring v8M additional state context For v8M, exceptions from Secure to Non-Secure state will save callee-saved registers to the exception frame as well as the caller-saved registers. Add support for unstacking these registers in exception exit when necessary. Backports commit 907bedb3f3ce134c149599bd9cb61856d811b8ca from qemu --- qemu/target/arm/helper.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/qemu/target/arm/helper.c b/qemu/target/arm/helper.c index 677525bc..e758106a 100644 --- a/qemu/target/arm/helper.c +++ b/qemu/target/arm/helper.c @@ -5728,6 +5728,37 @@ static void do_v7m_exception_exit(ARMCPU *cpu) "for destination state is UNPREDICTABLE\n"); } + /* Do we need to pop callee-saved registers? */ + if (return_to_secure && + ((excret & R_V7M_EXCRET_ES_MASK) == 0 || + (excret & R_V7M_EXCRET_DCRS_MASK) == 0)) { + uint32_t expected_sig = 0xfefa125b; + uint32_t actual_sig = ldl_phys(cs->as, frameptr); + + if (expected_sig != actual_sig) { + /* Take a SecureFault on the current stack */ + env->v7m.sfsr |= R_V7M_SFSR_INVIS_MASK; + // Unicorn: commented out + //armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false); + v7m_exception_taken(cpu, excret); + qemu_log_mask(CPU_LOG_INT, "...taking SecureFault on existing " + "stackframe: failed exception return integrity " + "signature check\n"); + return; + } + + env->regs[4] = ldl_phys(cs->as, frameptr + 0x8); + env->regs[5] = ldl_phys(cs->as, frameptr + 0xc); + env->regs[6] = ldl_phys(cs->as, frameptr + 0x10); + env->regs[7] = ldl_phys(cs->as, frameptr + 0x14); + env->regs[8] = ldl_phys(cs->as, frameptr + 0x18); + env->regs[9] = ldl_phys(cs->as, frameptr + 0x1c); + env->regs[10] = ldl_phys(cs->as, frameptr + 0x20); + env->regs[11] = ldl_phys(cs->as, frameptr + 0x24); + + frameptr += 0x28; + } + /* Pop registers. TODO: make these accesses use the correct * attributes and address space (S/NS, priv/unpriv) and handle * memory transaction failures.