On 30 January 2018 at 15:02, Peter Maydell <[email protected]> wrote:
> -static void v7m_push(CPUARMState *env, uint32_t val)
> +static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
> + ARMMMUIdx mmu_idx, bool ignfault)
> {
> - CPUState *cs = CPU(arm_env_get_cpu(env));
> + CPUState *cs = CPU(cpu);
> + CPUARMState *env = &cpu->env;
> + MemTxAttrs attrs = {};
> + MemTxResult txres;
> + target_ulong page_size;
> + hwaddr physaddr;
> + int prot;
> + ARMMMUFaultInfo fi;
> + bool secure = mmu_idx & ARM_MMU_IDX_M_S;
> + int exc;
> + bool exc_secure;
>
> - env->regs[13] -= 4;
> - stl_phys(cs->as, env->regs[13], val);
> + if (get_phys_addr(env, addr, MMU_DATA_STORE, mmu_idx, &physaddr,
> + &attrs, &prot, &page_size, &fi, NULL)) {
> + /* MPU/SAU lookup failed */
> + if (fi.type == ARMFault_QEMU_SFault) {
> + qemu_log_mask(CPU_LOG_INT,
> + "...SecureFault with SFSR.AUVIOL during
> stacking\n");
> + env->v7m.sfsr |= R_V7M_SFSR_AUVIOL_MASK |
> R_V7M_SFSR_SFARVALID_MASK;
> + env->v7m.sfar = addr;
> + exc = ARMV7M_EXCP_SECURE;
> + exc_secure = true;
I noticed on Friday that this code isn't quite right -- it should be
exc_secure = false;
This is because SecureFault is not banked, and for non-banked exceptions
we want to always pass false to armv7m_nvic_set_pending{,_derived}().
Otherwise that function will assert().
v7m_stack_read() in a later patch has the same bug.
thanks
-- PMM