aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWill Deacon <will.deacon@arm.com>2014-11-04 05:40:46 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2014-11-13 18:45:20 -0500
commit238962ac71910d6c20162ea5230685fead1836a4 (patch)
tree4dcd3ffbc4dbbad6d78280ffd209dcb29962ef55
parent9ff0bb5ba60638a688a46e93df8c5009896672eb (diff)
ARM: 8191/1: decompressor: ensure I-side picks up relocated code
To speed up decompression, the decompressor sets up a flat, cacheable mapping of memory. However, when there is insufficient space to hold the page tables for this mapping, we don't bother to enable the caches and subsequently skip all the cache maintenance hooks. Skipping the cache maintenance before jumping to the relocated code allows the processor to predict the branch and populate the I-cache with stale data before the relocation loop has completed (since a bootloader may have SCTLR.I set, which permits normal, cacheable instruction fetches regardless of SCTLR.M). This patch moves the cache maintenance check into the maintenance routines themselves, allowing the v6/v7 versions to invalidate the I-cache regardless of the MMU state. Cc: <stable@vger.kernel.org> Reported-by: Marc Carino <marc.ceeeee@gmail.com> Tested-by: Julien Grall <julien.grall@linaro.org> Signed-off-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--arch/arm/boot/compressed/head.S20
1 files changed, 16 insertions, 4 deletions
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 413fd94b5301..68be9017593d 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -397,8 +397,7 @@ dtb_check_done:
397 add sp, sp, r6 397 add sp, sp, r6
398#endif 398#endif
399 399
400 tst r4, #1 400 bl cache_clean_flush
401 bleq cache_clean_flush
402 401
403 adr r0, BSYM(restart) 402 adr r0, BSYM(restart)
404 add r0, r0, r6 403 add r0, r0, r6
@@ -1047,6 +1046,8 @@ cache_clean_flush:
1047 b call_cache_fn 1046 b call_cache_fn
1048 1047
1049__armv4_mpu_cache_flush: 1048__armv4_mpu_cache_flush:
1049 tst r4, #1
1050 movne pc, lr
1050 mov r2, #1 1051 mov r2, #1
1051 mov r3, #0 1052 mov r3, #0
1052 mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache 1053 mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache
@@ -1064,6 +1065,8 @@ __armv4_mpu_cache_flush:
1064 mov pc, lr 1065 mov pc, lr
1065 1066
1066__fa526_cache_flush: 1067__fa526_cache_flush:
1068 tst r4, #1
1069 movne pc, lr
1067 mov r1, #0 1070 mov r1, #0
1068 mcr p15, 0, r1, c7, c14, 0 @ clean and invalidate D cache 1071 mcr p15, 0, r1, c7, c14, 0 @ clean and invalidate D cache
1069 mcr p15, 0, r1, c7, c5, 0 @ flush I cache 1072 mcr p15, 0, r1, c7, c5, 0 @ flush I cache
@@ -1072,13 +1075,16 @@ __fa526_cache_flush:
1072 1075
1073__armv6_mmu_cache_flush: 1076__armv6_mmu_cache_flush:
1074 mov r1, #0 1077 mov r1, #0
1075 mcr p15, 0, r1, c7, c14, 0 @ clean+invalidate D 1078 tst r4, #1
1079 mcreq p15, 0, r1, c7, c14, 0 @ clean+invalidate D
1076 mcr p15, 0, r1, c7, c5, 0 @ invalidate I+BTB 1080 mcr p15, 0, r1, c7, c5, 0 @ invalidate I+BTB
1077 mcr p15, 0, r1, c7, c15, 0 @ clean+invalidate unified 1081 mcreq p15, 0, r1, c7, c15, 0 @ clean+invalidate unified
1078 mcr p15, 0, r1, c7, c10, 4 @ drain WB 1082 mcr p15, 0, r1, c7, c10, 4 @ drain WB
1079 mov pc, lr 1083 mov pc, lr
1080 1084
1081__armv7_mmu_cache_flush: 1085__armv7_mmu_cache_flush:
1086 tst r4, #1
1087 bne iflush
1082 mrc p15, 0, r10, c0, c1, 5 @ read ID_MMFR1 1088 mrc p15, 0, r10, c0, c1, 5 @ read ID_MMFR1
1083 tst r10, #0xf << 16 @ hierarchical cache (ARMv7) 1089 tst r10, #0xf << 16 @ hierarchical cache (ARMv7)
1084 mov r10, #0 1090 mov r10, #0
@@ -1139,6 +1145,8 @@ iflush:
1139 mov pc, lr 1145 mov pc, lr
1140 1146
1141__armv5tej_mmu_cache_flush: 1147__armv5tej_mmu_cache_flush:
1148 tst r4, #1
1149 movne pc, lr
11421: mrc p15, 0, r15, c7, c14, 3 @ test,clean,invalidate D cache 11501: mrc p15, 0, r15, c7, c14, 3 @ test,clean,invalidate D cache
1143 bne 1b 1151 bne 1b
1144 mcr p15, 0, r0, c7, c5, 0 @ flush I cache 1152 mcr p15, 0, r0, c7, c5, 0 @ flush I cache
@@ -1146,6 +1154,8 @@ __armv5tej_mmu_cache_flush:
1146 mov pc, lr 1154 mov pc, lr
1147 1155
1148__armv4_mmu_cache_flush: 1156__armv4_mmu_cache_flush:
1157 tst r4, #1
1158 movne pc, lr
1149 mov r2, #64*1024 @ default: 32K dcache size (*2) 1159 mov r2, #64*1024 @ default: 32K dcache size (*2)
1150 mov r11, #32 @ default: 32 byte line size 1160 mov r11, #32 @ default: 32 byte line size
1151 mrc p15, 0, r3, c0, c0, 1 @ read cache type 1161 mrc p15, 0, r3, c0, c0, 1 @ read cache type
@@ -1179,6 +1189,8 @@ no_cache_id:
1179 1189
1180__armv3_mmu_cache_flush: 1190__armv3_mmu_cache_flush:
1181__armv3_mpu_cache_flush: 1191__armv3_mpu_cache_flush:
1192 tst r4, #1
1193 movne pc, lr
1182 mov r1, #0 1194 mov r1, #0
1183 mcr p15, 0, r1, c7, c0, 0 @ invalidate whole cache v3 1195 mcr p15, 0, r1, c7, c0, 0 @ invalidate whole cache v3
1184 mov pc, lr 1196 mov pc, lr