1 From cdf357f1e13a08a11261edacb3083746f65c1ed9 Mon Sep 17 00:00:00 2001
2 From: Will Deacon <will.deacon@arm.com>
3 Date: Thu, 5 Aug 2010 11:20:51 +0100
4 Subject: ARM: 6299/1: errata: TLBIASIDIS and TLBIMVAIS operations can broadcast a faulty ASID
6 From: Will Deacon <will.deacon@arm.com>
8 commit cdf357f1e13a08a11261edacb3083746f65c1ed9 upstream.
10 On versions of the Cortex-A9 prior to r2p0, performing TLB invalidations by
11 ASID match can result in the incorrect ASID being broadcast to other CPUs.
12 As a consequence of this, the targetted TLB entries are not invalidated
15 This workaround changes the TLB flushing routines to invalidate entries
16 regardless of the ASID.
18 Tested-by: Rob Clark <rob@ti.com>
19 Acked-by: Catalin Marinas <catalin.marinas@arm.com>
20 Signed-off-by: Will Deacon <will.deacon@arm.com>
21 Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
22 Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
25 arch/arm/Kconfig | 12 ++++++++++++
26 arch/arm/include/asm/tlbflush.h | 8 ++++++++
27 2 files changed, 20 insertions(+)
29 --- a/arch/arm/Kconfig
30 +++ b/arch/arm/Kconfig
31 @@ -1025,6 +1025,18 @@ config PL310_ERRATA_588369
32 is not correctly implemented in PL310 as clean lines are not
33 invalidated as a result of these operations. Note that this errata
34 uses Texas Instrument's secure monitor api.
36 +config ARM_ERRATA_720789
37 + bool "ARM errata: TLBIASIDIS and TLBIMVAIS operations can broadcast a faulty ASID"
38 + depends on CPU_V7 && SMP
40 + This option enables the workaround for the 720789 Cortex-A9 (prior to
41 + r2p0) erratum. A faulty ASID can be sent to the other CPUs for the
42 + broadcasted CP15 TLB maintenance operations TLBIASIDIS and TLBIMVAIS.
43 + As a consequence of this erratum, some TLB entries which should be
44 + invalidated are not, resulting in an incoherency in the system page
45 + tables. The workaround changes the TLB flushing routines to invalidate
46 + entries regardless of the ASID.
49 source "arch/arm/common/Kconfig"
50 --- a/arch/arm/include/asm/tlbflush.h
51 +++ b/arch/arm/include/asm/tlbflush.h
52 @@ -378,7 +378,11 @@ static inline void local_flush_tlb_mm(st
53 if (tlb_flag(TLB_V6_I_ASID))
54 asm("mcr p15, 0, %0, c8, c5, 2" : : "r" (asid) : "cc");
55 if (tlb_flag(TLB_V7_UIS_ASID))
56 +#ifdef CONFIG_ARM_ERRATA_720789
57 + asm("mcr p15, 0, %0, c8, c3, 0" : : "r" (zero) : "cc");
59 asm("mcr p15, 0, %0, c8, c3, 2" : : "r" (asid) : "cc");
62 if (tlb_flag(TLB_BTB)) {
63 /* flush the branch target cache */
64 @@ -424,7 +428,11 @@ local_flush_tlb_page(struct vm_area_stru
65 if (tlb_flag(TLB_V6_I_PAGE))
66 asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (uaddr) : "cc");
67 if (tlb_flag(TLB_V7_UIS_PAGE))
68 +#ifdef CONFIG_ARM_ERRATA_720789
69 + asm("mcr p15, 0, %0, c8, c3, 3" : : "r" (uaddr & PAGE_MASK) : "cc");
71 asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (uaddr) : "cc");
74 if (tlb_flag(TLB_BTB)) {
75 /* flush the branch target cache */