aboutsummaryrefslogtreecommitdiff
path: root/target/arm/tlb_helper.c
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2021-11-03 00:03:49 -0400
committerPeter Maydell <peter.maydell@linaro.org>2021-12-15 10:35:26 +0000
commitee03027a2cef00f977a3d28242c0a250b8552495 (patch)
tree42e74225bdb97be6a66025ec7a5b6eb519ef34ba /target/arm/tlb_helper.c
parent936a6b86030a0db172b09a1ea953091a1555611e (diff)
downloadqemu-ee03027a2cef00f977a3d28242c0a250b8552495.zip
qemu-ee03027a2cef00f977a3d28242c0a250b8552495.tar.gz
qemu-ee03027a2cef00f977a3d28242c0a250b8552495.tar.bz2
target/arm: Take an exception if PC is misaligned
For A64, any input to an indirect branch can cause this. For A32, many indirect branch paths force the branch to be aligned, but BXWritePC does not. This includes the BX instruction but also other interworking changes to PC. Prior to v8, this case is UNDEFINED. With v8, this is CONSTRAINED UNPREDICTABLE and may either raise an exception or force align the PC. We choose to raise an exception because we have the infrastructure, it makes the generated code for gen_bx simpler, and it has the possibility of catching more guest bugs. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target/arm/tlb_helper.c')
-rw-r--r--target/arm/tlb_helper.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c
index 4cacb96..b79004e 100644
--- a/target/arm/tlb_helper.c
+++ b/target/arm/tlb_helper.c
@@ -9,6 +9,7 @@
#include "cpu.h"
#include "internals.h"
#include "exec/exec-all.h"
+#include "exec/helper-proto.h"
static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
unsigned int target_el,
@@ -134,6 +135,23 @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
arm_deliver_fault(cpu, vaddr, access_type, mmu_idx, &fi);
}
+void helper_exception_pc_alignment(CPUARMState *env, target_ulong pc)
+{
+ ARMMMUFaultInfo fi = { .type = ARMFault_Alignment };
+ int target_el = exception_target_el(env);
+ int mmu_idx = cpu_mmu_index(env, true);
+ uint32_t fsc;
+
+ env->exception.vaddress = pc;
+
+ /*
+ * Note that the fsc is not applicable to this exception,
+ * since any syndrome is pcalignment not insn_abort.
+ */
+ env->exception.fsr = compute_fsr_fsc(env, &fi, target_el, mmu_idx, &fsc);
+ raise_exception(env, EXCP_PREFETCH_ABORT, syn_pcalignment(), target_el);
+}
+
#if !defined(CONFIG_USER_ONLY)
/*