[PATCH 2/3] ARM PJ4B: Add support for errata 6124

Gregory CLEMENT gregory.clement at free-electrons.com
Wed May 29 06:16:57 EDT 2013


From: Lior Amsalem <alior at marvell.com>

A rare timing scenario exists where a clean operation occurs, followed
by an additional store operation. If a matching snoop also occurs, it
is possible for the write-back from the original clean operation and
the intervention from the snoop to race, which could result in data
corruption.
Replacing all clean cache maintenance operations with Clean &
Invalidate operation to avoid the issue

[gregory.clement at free-electrons.com:add errata description in changelog]
[gregory.clement at free-electrons.com: make this errata depend on Aramda
XP]
Signed-off-by: Lior Amsalem <alior at marvell.com>
Signed-off-by: Gregory CLEMENT <gregory.clement at free-electrons.com>
---
 arch/arm/Kconfig                | 13 +++++++++++++
 arch/arm/include/asm/tlbflush.h |  8 ++++++++
 arch/arm/mm/cache-v7.S          |  8 ++++++++
 arch/arm/mm/proc-v7-2level.S    |  4 ++++
 arch/arm/mm/proc-v7-3level.S    |  4 ++++
 arch/arm/mm/proc-v7.S           |  4 ++++
 6 files changed, 41 insertions(+)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 745781f..48cdbea 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1099,6 +1099,19 @@ config PJ4B_ERRATA_4742
 	  The software must insert either a Data Synchronization Barrier (DSB)
 	  or Data Memory Barrier (DMB) command immediately after the WFI/WFE instruction
 
+config PJ4B_ERRATA_6124
+        bool "PJ4B Errata 6124: Multiple writebacks can be issued in a rare timing scenario associated with a clean operation and an incoming snoop"
+        depends on CPU_PJ4B && MACH_ARMADA_XP
+        help
+	  A rare timing scenario exists where a clean operation occurs, followed
+	  by an additional store operation. If a matching snoop also occurs, it
+	  is possible for the write-back from the original clean operation and
+	  the intervention from the snoop to race, which could result in data
+	  corruption.
+	  Workaround:
+	  Replacing all clean cache maintenance operations with
+	  Clean & Invalidate operation will avoid the issue
+
 config ARM_ERRATA_326103
 	bool "ARM errata: FSR write bit incorrect on a SWP to read-only memory"
 	depends on CPU_V6
diff --git a/arch/arm/include/asm/tlbflush.h b/arch/arm/include/asm/tlbflush.h
index a3625d1..e3a8064 100644
--- a/arch/arm/include/asm/tlbflush.h
+++ b/arch/arm/include/asm/tlbflush.h
@@ -475,7 +475,11 @@ static inline void flush_pmd_entry(void *pmd)
 {
 	const unsigned int __tlb_flag = __cpu_tlb_flags;
 
+#ifdef CONFIG_PJ4B_ERRATA_6124
+	tlb_op(TLB_DCLEAN, "c7, c14, 1	@ flush_pmd", pmd);
+#else
 	tlb_op(TLB_DCLEAN, "c7, c10, 1	@ flush_pmd", pmd);
+#endif
 	tlb_l2_op(TLB_L2CLEAN_FR, "c15, c9, 1  @ L2 flush_pmd", pmd);
 
 	if (tlb_flag(TLB_WB))
@@ -486,7 +490,11 @@ static inline void clean_pmd_entry(void *pmd)
 {
 	const unsigned int __tlb_flag = __cpu_tlb_flags;
 
+#ifdef CONFIG_PJ4B_ERRATA_6124
+	tlb_op(TLB_DCLEAN, "c7, c14, 1	@ flush_pmd", pmd);
+#else
 	tlb_op(TLB_DCLEAN, "c7, c10, 1	@ flush_pmd", pmd);
+#endif
 	tlb_l2_op(TLB_L2CLEAN_FR, "c15, c9, 1  @ L2 flush_pmd", pmd);
 }
 
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S
index 15451ee..d353649 100644
--- a/arch/arm/mm/cache-v7.S
+++ b/arch/arm/mm/cache-v7.S
@@ -270,7 +270,11 @@ ENTRY(v7_coherent_user_range)
 	ALT_UP(W(nop))
 #endif
 1:
+#ifdef CONFIG_PJ4B_ERRATA_6124
+ USER(	mcr	p15, 0, r12, c7, c14, 1	)	@ clean & invalidate D line to the point of unification
+#else
  USER(	mcr	p15, 0, r12, c7, c11, 1	)	@ clean D line to the point of unification
+#endif
 	add	r12, r12, r2
 	cmp	r12, r1
 	blo	1b
@@ -378,7 +382,11 @@ v7_dma_clean_range:
 	ALT_UP(W(nop))
 #endif
 1:
+#ifdef CONFIG_PJ4B_ERRATA_6124
+	mcr	p15, 0, r0, c7, c14, 1		@ clean & invalidate D line to the point of unification
+#else
 	mcr	p15, 0, r0, c7, c10, 1		@ clean D / U line
+#endif
 	add	r0, r0, r2
 	cmp	r0, r1
 	blo	1b
diff --git a/arch/arm/mm/proc-v7-2level.S b/arch/arm/mm/proc-v7-2level.S
index 9704097..0999fd3 100644
--- a/arch/arm/mm/proc-v7-2level.S
+++ b/arch/arm/mm/proc-v7-2level.S
@@ -111,8 +111,12 @@ ENTRY(cpu_v7_set_pte_ext)
  THUMB(	add	r0, r0, #2048 )
  THUMB(	str	r3, [r0] )
 	ALT_SMP(mov	pc,lr)
+#ifdef CONFIG_PJ4B_ERRATA_6124
+	ALT_UP (mcr	p15, 0, r0, c7, c14, 1)		@ flush_pte by clean & invalidate D entry
+#else
 	ALT_UP (mcr	p15, 0, r0, c7, c10, 1)		@ flush_pte
 #endif
+#endif
 	mov	pc, lr
 ENDPROC(cpu_v7_set_pte_ext)
 
diff --git a/arch/arm/mm/proc-v7-3level.S b/arch/arm/mm/proc-v7-3level.S
index 363027e..7a917ff 100644
--- a/arch/arm/mm/proc-v7-3level.S
+++ b/arch/arm/mm/proc-v7-3level.S
@@ -74,8 +74,12 @@ ENTRY(cpu_v7_set_pte_ext)
 	orreq	r2, #L_PTE_RDONLY
 1:	strd	r2, r3, [r0]
 	ALT_SMP(mov	pc, lr)
+#ifdef CONFIG_PJ4B_ERRATA_6124
+	ALT_UP (mcr	p15, 0, r0, c7, c14, 1)		@ flush_pte by clean & invalidate D entry
+#else
 	ALT_UP (mcr	p15, 0, r0, c7, c10, 1)		@ flush_pte
 #endif
+#endif
 	mov	pc, lr
 ENDPROC(cpu_v7_set_pte_ext)
 
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index f872432..b86d688 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -81,7 +81,11 @@ ENTRY(cpu_v7_dcache_clean_area)
 	ALT_SMP(mov	pc, lr)			@ MP extensions imply L1 PTW
 	ALT_UP(W(nop))
 	dcache_line_size r2, r3
+#ifdef CONFIG_PJ4B_ERRATA_6124
+1:	mcr	p15, 0, r0, c7, c14, 1		@ clean & invalidate D entry
+#else
 1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+#endif
 	add	r0, r0, r2
 	subs	r1, r1, r2
 	bhi	1b
-- 
1.8.1.2




More information about the linux-arm-kernel mailing list