[PATCH] ARM v7: Fix register corruption in v7_mmu_cache_off
Sascha Hauer
s.hauer at pengutronix.de
Wed Jan 23 04:43:45 EST 2013
v7_mmu_cache_flush stores registers on the stack and restores
them afterwards. Additionally v7_mmu_cache_flush is called
from v7_mmu_cache_off *after* disabling the MMU. With this
the following can happen:
- v7_mmu_cache_off disables the MMU. From now on no new values
go to the data cache.
- v7_mmu_cache_off calls v7_mmu_cache_flush which in turn puts
registers on the stack. Due to the MMU being disabled they
do not go into the data cache.
- In v7_mmu_cache_flush the memory the stack is pointing to is
overwritten with the values currently being in the cache.
- v7_mmu_cache_flush restores the registers from the stack with
values from the cache and not the memory where the values have
previously been written to.
Fix this by storing the registers on the stack *before* we disable
the MMU and restore them after we have called v7_mmu_cache_flush.
This way v7_mmu_cache_flush still restores corrupt register values
for the case when the MMU has been disabled, but we will restore
correct values afterwards.
This has been first observed when switching to gcc-4.7.2 when compiling
in Thumb2 mode, but could explain earlier problems also. The result
here was that the register holding the kernel address in start_linux()
was corrupted so that the kernel could not be started.
Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
arch/arm/cpu/cache-armv7.S | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm/cpu/cache-armv7.S b/arch/arm/cpu/cache-armv7.S
index 2d68f27..13542d9 100644
--- a/arch/arm/cpu/cache-armv7.S
+++ b/arch/arm/cpu/cache-armv7.S
@@ -34,6 +34,7 @@ ENDPROC(v7_mmu_cache_on)
.section .text.v7_mmu_cache_off
ENTRY(v7_mmu_cache_off)
+ stmfd sp!, {r0-r7, r9-r11}
mrc p15, 0, r0, c1, c0
#ifdef CONFIG_MMU
bic r0, r0, #0x000d
@@ -50,6 +51,7 @@ ENTRY(v7_mmu_cache_off)
mcr p15, 0, r0, c7, c5, 6 @ invalidate BTC
mcr p15, 0, r0, c7, c10, 4 @ DSB
mcr p15, 0, r0, c7, c5, 4 @ ISB
+ ldmfd sp!, {r0-r7, r9-r11}
mov pc, r12
ENDPROC(v7_mmu_cache_off)
--
1.7.10.4
More information about the barebox
mailing list