diff options
author | Jerome Forissier <jerome.forissier@linaro.org> | 2017-06-08 15:51:45 +0200 |
---|---|---|
committer | Jérôme Forissier <jerome.forissier@linaro.org> | 2017-06-12 14:15:47 +0200 |
commit | aaaf00a257488d2b6fbf8a4e842e1333529c704c (patch) | |
tree | 71b9815925220264f63214ac8898a89119172d98 /core | |
parent | 4c56bf5f97b6344e840519f6a76770552d4c924b (diff) |
core: arm: make alignment check configurable
We occasionally get reports from people stumbling upon data abort
exceptions caused by alignment faults in TAs. The recommended fix is to
change the code so that the unaligned access won't occur. But it is
sometimes difficult to achieve.
Therefore we provide a compile-time option to disable alignment checks.
For AArch64 it applies to both SEL1 and SEL0.
Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
Tested-by: Jerome Forissier <jerome.forissier@linaro.org> (HiKey)
Acked-by: Jens Wiklander <jens.wiklander@linaro.org>
Diffstat (limited to 'core')
-rw-r--r-- | core/arch/arm/arm.mk | 2 | ||||
-rw-r--r-- | core/arch/arm/kernel/generic_entry_a32.S | 8 | ||||
-rw-r--r-- | core/arch/arm/kernel/generic_entry_a64.S | 31 | ||||
-rw-r--r-- | core/arch/arm/plat-sunxi/entry.S | 6 | ||||
-rw-r--r-- | core/arch/arm/plat-sunxi/smp_boot.S | 4 |
5 files changed, 36 insertions, 15 deletions
diff --git a/core/arch/arm/arm.mk b/core/arch/arm/arm.mk index 13361d8a..40253d06 100644 --- a/core/arch/arm/arm.mk +++ b/core/arch/arm/arm.mk @@ -31,6 +31,8 @@ CFG_CORE_RODATA_NOEXEC ?= n ifeq ($(CFG_CORE_RODATA_NOEXEC),y) $(call force,CFG_CORE_RWDATA_NOEXEC,y) endif +# 'y' to set the Alignment Check Enable bit in SCTLR/SCTLR_EL1, 'n' to clear it +CFG_SCTLR_ALIGNMENT_CHECK ?= y ifeq ($(CFG_WITH_PAGER),y) ifeq ($(CFG_CORE_SANITIZE_KADDRESS),y) diff --git a/core/arch/arm/kernel/generic_entry_a32.S b/core/arch/arm/kernel/generic_entry_a32.S index 6100bb88..005d85c4 100644 --- a/core/arch/arm/kernel/generic_entry_a32.S +++ b/core/arch/arm/kernel/generic_entry_a32.S @@ -187,7 +187,11 @@ UNWIND( .cantunwind) /* Enable alignment checks and disable data and instruction cache. */ read_sctlr r0 +#if defined(CFG_SCTLR_ALIGNMENT_CHECK) orr r0, r0, #SCTLR_A +#else + bic r0, r0, #SCTLR_A +#endif bic r0, r0, #SCTLR_C bic r0, r0, #SCTLR_I #if defined(CFG_HWSUPP_MEM_PERM_WXN) && defined(CFG_CORE_RWDATA_NOEXEC) @@ -457,7 +461,11 @@ UNWIND( .cantunwind) mov r5, r1 mov r6, lr read_sctlr r0 +#if defined(CFG_SCTLR_ALIGNMENT_CHECK) orr r0, r0, #SCTLR_A +#else + bic r0, r0, #SCTLR_A +#endif #if defined(CFG_HWSUPP_MEM_PERM_WXN) && defined(CFG_CORE_RWDATA_NOEXEC) orr r0, r0, #(SCTLR_WXN | SCTLR_UWXN) #endif diff --git a/core/arch/arm/kernel/generic_entry_a64.S b/core/arch/arm/kernel/generic_entry_a64.S index 7221ad1b..b7290e6c 100644 --- a/core/arch/arm/kernel/generic_entry_a64.S +++ b/core/arch/arm/kernel/generic_entry_a64.S @@ -58,6 +58,21 @@ msr spsel, #0 .endm + .macro set_sctlr_el1 + mrs x0, sctlr_el1 + orr x0, x0, #SCTLR_I + orr x0, x0, #SCTLR_SA +#if defined(CFG_CORE_RWDATA_NOEXEC) + orr x0, x0, #SCTLR_WXN +#endif +#if defined(CFG_SCTLR_ALIGNMENT_CHECK) + orr x0, x0, #SCTLR_A +#else + bic x0, x0, #SCTLR_A +#endif + msr sctlr_el1, x0 + .endm + .section .text.boot FUNC _start , : mov x19, x0 /* Save pagable part address */ @@ -67,13 +82,7 @@ FUNC _start , : msr vbar_el1, x0 isb - mrs x0, sctlr_el1 - mov x1, #(SCTLR_I | SCTLR_A | SCTLR_SA) -#if defined(CFG_CORE_RWDATA_NOEXEC) - orr x1, x1, #SCTLR_WXN -#endif - orr x0, x0, x1 - msr sctlr_el1, x0 + set_sctlr_el1 isb #ifdef CFG_WITH_PAGER @@ -186,13 +195,7 @@ FUNC cpu_on_handler , : msr vbar_el1, x0 isb - mrs x0, sctlr_el1 - mov x1, #(SCTLR_I | SCTLR_A | SCTLR_SA) -#if defined(CFG_CORE_RWDATA_NOEXEC) - orr x1, x1, #SCTLR_WXN -#endif - orr x0, x0, x1 - msr sctlr_el1, x0 + set_sctlr_el1 isb /* Setup SP_EL0 and SP_EL1, SP will be set to SP_EL0 */ diff --git a/core/arch/arm/plat-sunxi/entry.S b/core/arch/arm/plat-sunxi/entry.S index 5b1dc392..d015ee6e 100644 --- a/core/arch/arm/plat-sunxi/entry.S +++ b/core/arch/arm/plat-sunxi/entry.S @@ -52,7 +52,11 @@ LOCAL_FUNC reset , : UNWIND( .fnstart) UNWIND( .cantunwind) read_sctlr r0 - orr r0, r0, #SCTLR_A +#if defined(CFG_SCTLR_ALIGNMENT_CHECK) + orr r0, r0, #SCTLR_A +#else + bic r0, r0, #SCTLR_A +#endif write_sctlr r0 ldr r0, =_start diff --git a/core/arch/arm/plat-sunxi/smp_boot.S b/core/arch/arm/plat-sunxi/smp_boot.S index 98c63a59..da93d7de 100644 --- a/core/arch/arm/plat-sunxi/smp_boot.S +++ b/core/arch/arm/plat-sunxi/smp_boot.S @@ -50,7 +50,11 @@ UNWIND( .fnstart) UNWIND( .cantunwind) /* secondary CPUs internal initialization */ read_sctlr r0 +#if defined(CFG_SCTLR_ALIGNMENT_CHECK) orr r0, r0, #SCTLR_A +#else + bic r0, r0, #SCTLR_A +#endif write_sctlr r0 /* install smp initialization vector */ |