diff options
| author | Will Deacon <will.deacon@arm.com> | 2010-08-05 06:20:51 -0400 |
|---|---|---|
| committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-08-10 17:10:54 -0400 |
| commit | cdf357f1e13a08a11261edacb3083746f65c1ed9 (patch) | |
| tree | bb49c4536929906b69f6e99e2457fc2ccc7944d9 | |
| parent | 988257cfcbc468cb26b3addfcab1d0187c4e2399 (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>
| -rw-r--r-- | arch/arm/Kconfig | 12 | ||||
| -rw-r--r-- | arch/arm/include/asm/tlbflush.h | 8 |
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 | |||
| 1044 | config 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. | ||
| 1043 | endmenu | 1055 | endmenu |
| 1044 | 1056 | ||
| 1045 | source "arch/arm/common/Kconfig" | 1057 | source "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 */ |
