Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

arm64: Add workaround for Cavium erratum 27456

On ThunderX T88 pass 1.x through 2.1 parts, broadcast TLBI
instructions may cause the icache to become corrupted if it contains
data for a non-current ASID.

This patch implements the workaround (which invalidates the local
icache when switching the mm) by using code patching.

Signed-off-by: Andrew Pinski <apinski@cavium.com>
Signed-off-by: David Daney <david.daney@cavium.com>
Reviewed-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>

authored by

Andrew Pinski and committed by
Catalin Marinas
104a0c02 2f39b5f9

+35 -1
+1
Documentation/arm64/silicon-errata.txt
··· 56 56 | | | | | 57 57 | Cavium | ThunderX ITS | #22375, #24313 | CAVIUM_ERRATUM_22375 | 58 58 | Cavium | ThunderX GICv3 | #23154 | CAVIUM_ERRATUM_23154 | 59 + | Cavium | ThunderX Core | #27456 | CAVIUM_ERRATUM_27456 |
+11
arch/arm64/Kconfig
··· 435 435 436 436 If unsure, say Y. 437 437 438 + config CAVIUM_ERRATUM_27456 439 + bool "Cavium erratum 27456: Broadcast TLBI instructions may cause icache corruption" 440 + default y 441 + help 442 + On ThunderX T88 pass 1.x through 2.1 parts, broadcast TLBI 443 + instructions may cause the icache to become corrupted if it 444 + contains data for a non-current ASID. The fix is to 445 + invalidate the icache when changing the mm context. 446 + 447 + If unsure, say Y. 448 + 438 449 endmenu 439 450 440 451
+2 -1
arch/arm64/include/asm/cpufeature.h
··· 33 33 #define ARM64_HAS_NO_HW_PREFETCH 8 34 34 #define ARM64_HAS_UAO 9 35 35 #define ARM64_ALT_PAN_NOT_UAO 10 36 + #define ARM64_WORKAROUND_CAVIUM_27456 12 36 37 37 - #define ARM64_NCAPS 11 38 + #define ARM64_NCAPS 13 38 39 39 40 #ifndef __ASSEMBLY__ 40 41
+9
arch/arm64/kernel/cpu_errata.c
··· 88 88 MIDR_RANGE(MIDR_THUNDERX, 0x00, 0x01), 89 89 }, 90 90 #endif 91 + #ifdef CONFIG_CAVIUM_ERRATUM_27456 92 + { 93 + /* Cavium ThunderX, T88 pass 1.x - 2.1 */ 94 + .desc = "Cavium erratum 27456", 95 + .capability = ARM64_WORKAROUND_CAVIUM_27456, 96 + MIDR_RANGE(MIDR_THUNDERX, 0x00, 97 + (1 << MIDR_VARIANT_SHIFT) | 1), 98 + }, 99 + #endif 91 100 { 92 101 } 93 102 };
+12
arch/arm64/mm/proc.S
··· 25 25 #include <asm/hwcap.h> 26 26 #include <asm/pgtable-hwdef.h> 27 27 #include <asm/pgtable.h> 28 + #include <asm/cpufeature.h> 29 + #include <asm/alternative.h> 28 30 29 31 #include "proc-macros.S" 30 32 ··· 139 137 bfi x0, x1, #48, #16 // set the ASID 140 138 msr ttbr0_el1, x0 // set TTBR0 141 139 isb 140 + alternative_if_not ARM64_WORKAROUND_CAVIUM_27456 142 141 ret 142 + nop 143 + nop 144 + nop 145 + alternative_else 146 + ic iallu 147 + dsb nsh 148 + isb 149 + ret 150 + alternative_endif 143 151 ENDPROC(cpu_do_switch_mm) 144 152 145 153 .pushsection ".idmap.text", "ax"