[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