Skip to content

Commit

Permalink
target/arm: Clear exclusive monitor on v7M reset, exception entry/exit
Browse files Browse the repository at this point in the history
For M profile we must clear the exclusive monitor on reset, exception
entry and exception exit.  We weren't doing any of these things; fix
this bug.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 1505137930-13255-3-git-send-email-peter.maydell@linaro.org
  • Loading branch information
pm215 committed Sep 14, 2017
1 parent 4a16724 commit dc3c4c1
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 1 deletion.
6 changes: 6 additions & 0 deletions target/arm/cpu.c
Expand Up @@ -235,6 +235,12 @@ static void arm_cpu_reset(CPUState *s)
env->regs[15] = 0xFFFF0000;
}

/* M profile requires that reset clears the exclusive monitor;
* A profile does not, but clearing it makes more sense than having it
* set with an exclusive access on address zero.
*/
arm_clear_exclusive(env);

env->vfp.xregs[ARM_VFP_FPEXC] = 0;
#endif

Expand Down
2 changes: 2 additions & 0 deletions target/arm/helper.c
Expand Up @@ -6175,6 +6175,7 @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr)

armv7m_nvic_acknowledge_irq(env->nvic);
switch_v7m_sp(env, 0);
arm_clear_exclusive(env);
/* Clear IT bits */
env->condexec_bits = 0;
env->regs[14] = lr;
Expand Down Expand Up @@ -6354,6 +6355,7 @@ static void do_v7m_exception_exit(ARMCPU *cpu)
}

/* Otherwise, we have a successful exception exit. */
arm_clear_exclusive(env);
qemu_log_mask(CPU_LOG_INT, "...successful exception return\n");
}

Expand Down
10 changes: 10 additions & 0 deletions target/arm/internals.h
Expand Up @@ -443,6 +443,16 @@ bool arm_is_psci_call(ARMCPU *cpu, int excp_type);
void arm_handle_psci_call(ARMCPU *cpu);
#endif

/**
* arm_clear_exclusive: clear the exclusive monitor
* @env: CPU env
* Clear the CPU's exclusive monitor, like the guest CLREX instruction.
*/
static inline void arm_clear_exclusive(CPUARMState *env)
{
env->exclusive_addr = -1;
}

/**
* ARMMMUFaultInfo: Information describing an ARM MMU Fault
* @s2addr: Address that caused a fault at stage 2
Expand Down
2 changes: 1 addition & 1 deletion target/arm/op_helper.c
Expand Up @@ -1022,7 +1022,7 @@ void HELPER(exception_return)(CPUARMState *env)

aarch64_save_sp(env, cur_el);

env->exclusive_addr = -1;
arm_clear_exclusive(env);

/* We must squash the PSTATE.SS bit to zero unless both of the
* following hold:
Expand Down

0 comments on commit dc3c4c1

Please sign in to comment.