aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2018-08-14 17:17:21 +0100
committerPeter Maydell <peter.maydell@linaro.org>2018-08-14 17:17:21 +0100
commit7556edfb4d7bf0583c852c8cfc49ef494c41dd8a (patch)
tree09d32f987bb899b48df40d599dc7300477f08ad1 /target
parent30ac6339dca3fe0d05a611f12eedd5af20af585a (diff)
downloadqemu-7556edfb4d7bf0583c852c8cfc49ef494c41dd8a.zip
qemu-7556edfb4d7bf0583c852c8cfc49ef494c41dd8a.tar.gz
qemu-7556edfb4d7bf0583c852c8cfc49ef494c41dd8a.tar.bz2
target/arm: Honour HCR_EL2.TGE when raising synchronous exceptions
Whene we raise a synchronous exception, if HCR_EL2.TGE is set then exceptions targeting NS EL1 must be redirected to EL2. Implement this in raise_exception() -- all synchronous exceptions go through this function. (Asynchronous exceptions go via arm_cpu_exec_interrupt(), which already honours HCR_EL2.TGE when it determines the target EL in arm_phys_excp_target_el().) Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20180724115950.17316-4-peter.maydell@linaro.org
Diffstat (limited to 'target')
-rw-r--r--target/arm/op_helper.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
index f728f25..d550978 100644
--- a/target/arm/op_helper.c
+++ b/target/arm/op_helper.c
@@ -33,6 +33,20 @@ static void raise_exception(CPUARMState *env, uint32_t excp,
{
CPUState *cs = CPU(arm_env_get_cpu(env));
+ if ((env->cp15.hcr_el2 & HCR_TGE) &&
+ target_el == 1 && !arm_is_secure(env)) {
+ /*
+ * Redirect NS EL1 exceptions to NS EL2. These are reported with
+ * their original syndrome register value, with the exception of
+ * SIMD/FP access traps, which are reported as uncategorized
+ * (see DDI0478C.a D1.10.4)
+ */
+ target_el = 2;
+ if (syndrome >> ARM_EL_EC_SHIFT == EC_ADVSIMDFPACCESSTRAP) {
+ syndrome = syn_uncategorized();
+ }
+ }
+
assert(!excp_is_internal(excp));
cs->exception_index = excp;
env->exception.syndrome = syndrome;