aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorWill Deacon <will.deacon@arm.com>2010-08-05 06:20:51 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2010-08-10 17:10:54 -0400
commitcdf357f1e13a08a11261edacb3083746f65c1ed9 (patch)
treebb49c4536929906b69f6e99e2457fc2ccc7944d9 /arch
parent988257cfcbc468cb26b3addfcab1d0187c4e2399 (diff)
ARM: 6299/1: errata: TLBIASIDIS and TLBIMVAIS operations can broadcast a faulty ASID
On versions of the Cortex-A9 prior to r2p0, performing TLB invalidations by ASID match can result in the incorrect ASID being broadcast to other CPUs. As a consequence of this, the targetted TLB entries are not invalidated across the system. This workaround changes the TLB flushing routines to invalidate entries regardless of the ASID. Cc: <stable@kernel.org> Tested-by: Rob Clark <rob@ti.com> Acked-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/Kconfig12
-rw-r--r--arch/arm/include/asm/tlbflush.h8
2 files changed, 20 insertions, 0 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 232f0c758252..e3956042892c 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1040,6 +1040,18 @@ config PL310_ERRATA_588369
1040 is not correctly implemented in PL310 as clean lines are not 1040 is not correctly implemented in PL310 as clean lines are not
1041 invalidated as a result of these operations. Note that this errata 1041 invalidated as a result of these operations. Note that this errata
1042 uses Texas Instrument's secure monitor api. 1042 uses Texas Instrument's secure monitor api.
1043
1044config ARM_ERRATA_720789
1045 bool "ARM errata: TLBIASIDIS and TLBIMVAIS operations can broadcast a faulty ASID"
1046 depends on CPU_V7 && SMP
1047 help
1048 This option enables the workaround for the 720789 Cortex-A9 (prior to
1049 r2p0) erratum. A faulty ASID can be sent to the other CPUs for the
1050 broadcasted CP15 TLB maintenance operations TLBIASIDIS and TLBIMVAIS.
1051 As a consequence of this erratum, some TLB entries which should be
1052 invalidated are not, resulting in an incoherency in the system page
1053 tables. The workaround changes the TLB flushing routines to invalidate
1054 entries regardless of the ASID.
1043endmenu 1055endmenu
1044 1056
1045source "arch/arm/common/Kconfig" 1057source "arch/arm/common/Kconfig"
diff --git a/arch/arm/include/asm/tlbflush.h b/arch/arm/include/asm/tlbflush.h
index bd863d8608cd..33b546ae72d4 100644
--- a/arch/arm/include/asm/tlbflush.h
+++ b/arch/arm/include/asm/tlbflush.h
@@ -378,7 +378,11 @@ static inline void local_flush_tlb_mm(struct mm_struct *mm)
378 if (tlb_flag(TLB_V6_I_ASID)) 378 if (tlb_flag(TLB_V6_I_ASID))
379 asm("mcr p15, 0, %0, c8, c5, 2" : : "r" (asid) : "cc"); 379 asm("mcr p15, 0, %0, c8, c5, 2" : : "r" (asid) : "cc");
380 if (tlb_flag(TLB_V7_UIS_ASID)) 380 if (tlb_flag(TLB_V7_UIS_ASID))
381#ifdef CONFIG_ARM_ERRATA_720789
382 asm("mcr p15, 0, %0, c8, c3, 0" : : "r" (zero) : "cc");
383#else
381 asm("mcr p15, 0, %0, c8, c3, 2" : : "r" (asid) : "cc"); 384 asm("mcr p15, 0, %0, c8, c3, 2" : : "r" (asid) : "cc");
385#endif
382 386
383 if (tlb_flag(TLB_BTB)) { 387 if (tlb_flag(TLB_BTB)) {
384 /* flush the branch target cache */ 388 /* flush the branch target cache */
@@ -424,7 +428,11 @@ local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
424 if (tlb_flag(TLB_V6_I_PAGE)) 428 if (tlb_flag(TLB_V6_I_PAGE))
425 asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (uaddr) : "cc"); 429 asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (uaddr) : "cc");
426 if (tlb_flag(TLB_V7_UIS_PAGE)) 430 if (tlb_flag(TLB_V7_UIS_PAGE))
431#ifdef CONFIG_ARM_ERRATA_720789
432 asm("mcr p15, 0, %0, c8, c3, 3" : : "r" (uaddr & PAGE_MASK) : "cc");
433#else
427 asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (uaddr) : "cc"); 434 asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (uaddr) : "cc");
435#endif
428 436
429 if (tlb_flag(TLB_BTB)) { 437 if (tlb_flag(TLB_BTB)) {
430 /* flush the branch target cache */ 438 /* flush the branch target cache */