Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ARM: 7091/1: errata: D-cache line maintenance operation by MVA may not succeed

This patch implements a workaround for erratum 764369 affecting
Cortex-A9 MPCore with two or more processors (all current revisions).
Under certain timing circumstances, a data cache line maintenance
operation by MVA targeting an Inner Shareable memory region may fail to
proceed up to either the Point of Coherency or to the Point of
Unification of the system. This workaround adds a DSB instruction before
the relevant cache maintenance functions and sets a specific bit in the
diagnostic control register of the SCU.

Cc: <stable@kernel.org>
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Tested-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

authored by

Will Deacon and committed by
Russell King
f630c1bd 279b1e0f

+44
+14
arch/arm/Kconfig
··· 1283 1283 processor into full low interrupt latency mode. ARM11MPCore 1284 1284 is not affected. 1285 1285 1286 + config ARM_ERRATA_764369 1287 + bool "ARM errata: Data cache line maintenance operation by MVA may not succeed" 1288 + depends on CPU_V7 && SMP 1289 + help 1290 + This option enables the workaround for erratum 764369 1291 + affecting Cortex-A9 MPCore with two or more processors (all 1292 + current revisions). Under certain timing circumstances, a data 1293 + cache line maintenance operation by MVA targeting an Inner 1294 + Shareable memory region may fail to proceed up to either the 1295 + Point of Coherency or to the Point of Unification of the 1296 + system. This workaround adds a DSB instruction before the 1297 + relevant cache maintenance functions and sets a specific bit 1298 + in the diagnostic control register of the SCU. 1299 + 1286 1300 endmenu 1287 1301 1288 1302 source "arch/arm/common/Kconfig"
+10
arch/arm/kernel/smp_scu.c
··· 13 13 14 14 #include <asm/smp_scu.h> 15 15 #include <asm/cacheflush.h> 16 + #include <asm/cputype.h> 16 17 17 18 #define SCU_CTRL 0x00 18 19 #define SCU_CONFIG 0x04 ··· 37 36 void __init scu_enable(void __iomem *scu_base) 38 37 { 39 38 u32 scu_ctrl; 39 + 40 + #ifdef CONFIG_ARM_ERRATA_764369 41 + /* Cortex-A9 only */ 42 + if ((read_cpuid(CPUID_ID) & 0xff0ffff0) == 0x410fc090) { 43 + scu_ctrl = __raw_readl(scu_base + 0x30); 44 + if (!(scu_ctrl & 1)) 45 + __raw_writel(scu_ctrl | 0x1, scu_base + 0x30); 46 + } 47 + #endif 40 48 41 49 scu_ctrl = __raw_readl(scu_base + SCU_CTRL); 42 50 /* already enabled? */
+20
arch/arm/mm/cache-v7.S
··· 174 174 dcache_line_size r2, r3 175 175 sub r3, r2, #1 176 176 bic r12, r0, r3 177 + #ifdef CONFIG_ARM_ERRATA_764369 178 + ALT_SMP(W(dsb)) 179 + ALT_UP(W(nop)) 180 + #endif 177 181 1: 178 182 USER( mcr p15, 0, r12, c7, c11, 1 ) @ clean D line to the point of unification 179 183 add r12, r12, r2 ··· 227 223 add r1, r0, r1 228 224 sub r3, r2, #1 229 225 bic r0, r0, r3 226 + #ifdef CONFIG_ARM_ERRATA_764369 227 + ALT_SMP(W(dsb)) 228 + ALT_UP(W(nop)) 229 + #endif 230 230 1: 231 231 mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line / unified line 232 232 add r0, r0, r2 ··· 255 247 sub r3, r2, #1 256 248 tst r0, r3 257 249 bic r0, r0, r3 250 + #ifdef CONFIG_ARM_ERRATA_764369 251 + ALT_SMP(W(dsb)) 252 + ALT_UP(W(nop)) 253 + #endif 258 254 mcrne p15, 0, r0, c7, c14, 1 @ clean & invalidate D / U line 259 255 260 256 tst r1, r3 ··· 282 270 dcache_line_size r2, r3 283 271 sub r3, r2, #1 284 272 bic r0, r0, r3 273 + #ifdef CONFIG_ARM_ERRATA_764369 274 + ALT_SMP(W(dsb)) 275 + ALT_UP(W(nop)) 276 + #endif 285 277 1: 286 278 mcr p15, 0, r0, c7, c10, 1 @ clean D / U line 287 279 add r0, r0, r2 ··· 304 288 dcache_line_size r2, r3 305 289 sub r3, r2, #1 306 290 bic r0, r0, r3 291 + #ifdef CONFIG_ARM_ERRATA_764369 292 + ALT_SMP(W(dsb)) 293 + ALT_UP(W(nop)) 294 + #endif 307 295 1: 308 296 mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D / U line 309 297 add r0, r0, r2