From cc9458cf599e3341e4b07343a3e27d87e34c08b4 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Fri, 2 Mar 2018 13:35:47 -0500 Subject: [PATCH] armv7m: Explicit error for bad vector table Give an explicit error and abort when a load from the vector table fails. Architecturally this should HardFault (which will then immediately fail to load the HardFault vector and go into Lockup). Since we don't model Lockup, just report this guest error via cpu_abort(). This is more helpful than the previous behaviour of reading a zero, which is the address of the reset stack pointer and not a sensible location to jump to. Backports commit 1b9ea408fca1ce8caae67b792355b023c69c5ac5 from qemu --- qemu/target/arm/helper.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/qemu/target/arm/helper.c b/qemu/target/arm/helper.c index 4fe3fad0..8c0b7b01 100644 --- a/qemu/target/arm/helper.c +++ b/qemu/target/arm/helper.c @@ -5389,8 +5389,33 @@ static void arm_log_exception(int idx) } } +static uint32_t arm_v7m_load_vector(ARMCPU *cpu) + +{ + CPUState *cs = CPU(cpu); + CPUARMState *env = &cpu->env; + MemTxResult result; + hwaddr vec = env->v7m.vecbase + env->v7m.exception * 4; + uint32_t addr; + + addr = address_space_ldl(cs->as, vec, + MEMTXATTRS_UNSPECIFIED, &result); + if (result != MEMTX_OK) { + /* Architecturally this should cause a HardFault setting HSFR.VECTTBL, + * which would then be immediately followed by our failing to load + * the entry vector for that HardFault, which is a Lockup case. + * Since we don't model Lockup, we just report this guest error + * via cpu_abort(). + */ + cpu_abort(cs, "Failed to read from exception vector table " + "entry %08x\n", (unsigned)vec); + } + return addr; +} + void arm_v7m_cpu_do_interrupt(CPUState *cs) { + ARMCPU *cpu = ARM_CPU(cs->uc, cs); CPUARMState *env = cs->env_ptr; uint32_t xpsr = xpsr_read(env); uint32_t lr; @@ -5472,7 +5497,7 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs) /* Clear IT bits */ env->condexec_bits = 0; env->regs[14] = lr; - addr = ldl_phys(cs->as, env->v7m.vecbase + env->v7m.exception * 4); + addr = arm_v7m_load_vector(cpu); env->regs[15] = addr & 0xfffffffe; env->thumb = addr & 1; }