Skip to content

Commit fa82d0b

Browse files
Suzuki K Poulosewilldeacon
authored andcommitted
arm64: errata: Add workaround for TSB flush failures
Arm Neoverse-N2 (#2067961) and Cortex-A710 (#2054223) suffers from errata, where a TSB (trace synchronization barrier) fails to flush the trace data completely, when executed from a trace prohibited region. In Linux we always execute it after we have moved the PE to trace prohibited region. So, we can apply the workaround every time a TSB is executed. The work around is to issue two TSB consecutively. NOTE: This errata is defined as LOCAL_CPU_ERRATUM, implying that a late CPU could be blocked from booting if it is the first CPU that requires the workaround. This is because we do not allow setting a cpu_hwcaps after the SMP boot. The other alternative is to use "this_cpu_has_cap()" instead of the faster system wide check, which may be a bit of an overhead, given we may have to do this in nvhe KVM host before a guest entry. Cc: Will Deacon <[email protected]> Cc: Catalin Marinas <[email protected]> Cc: Mathieu Poirier <[email protected]> Cc: Mike Leach <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Anshuman Khandual <[email protected]> Cc: Marc Zyngier <[email protected]> Acked-by: Catalin Marinas <[email protected]> Reviewed-by: Mathieu Poirier <[email protected]> Reviewed-by: Anshuman Khandual <[email protected]> Signed-off-by: Suzuki K Poulose <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Will Deacon <[email protected]>
1 parent b9d216f commit fa82d0b

File tree

5 files changed

+72
-1
lines changed

5 files changed

+72
-1
lines changed

Documentation/arm64/silicon-errata.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ stable kernels.
9494
+----------------+-----------------+-----------------+-----------------------------+
9595
| ARM | Cortex-A710 | #2119858 | ARM64_ERRATUM_2119858 |
9696
+----------------+-----------------+-----------------+-----------------------------+
97+
| ARM | Cortex-A710 | #2054223 | ARM64_ERRATUM_2054223 |
98+
+----------------+-----------------+-----------------+-----------------------------+
9799
| ARM | Neoverse-N1 | #1188873,1418040| ARM64_ERRATUM_1418040 |
98100
+----------------+-----------------+-----------------+-----------------------------+
99101
| ARM | Neoverse-N1 | #1349291 | N/A |
@@ -102,6 +104,8 @@ stable kernels.
102104
+----------------+-----------------+-----------------+-----------------------------+
103105
| ARM | Neoverse-N2 | #2139208 | ARM64_ERRATUM_2139208 |
104106
+----------------+-----------------+-----------------+-----------------------------+
107+
| ARM | Neoverse-N2 | #2067961 | ARM64_ERRATUM_2067961 |
108+
+----------------+-----------------+-----------------+-----------------------------+
105109
| ARM | MMU-500 | #841119,826419 | N/A |
106110
+----------------+-----------------+-----------------+-----------------------------+
107111
+----------------+-----------------+-----------------+-----------------------------+

arch/arm64/Kconfig

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -707,6 +707,39 @@ config ARM64_ERRATUM_2139208
707707

708708
If unsure, say Y.
709709

710+
config ARM64_WORKAROUND_TSB_FLUSH_FAILURE
711+
bool
712+
713+
config ARM64_ERRATUM_2054223
714+
bool "Cortex-A710: 2054223: workaround TSB instruction failing to flush trace"
715+
default y
716+
select ARM64_WORKAROUND_TSB_FLUSH_FAILURE
717+
help
718+
Enable workaround for ARM Cortex-A710 erratum 2054223
719+
720+
Affected cores may fail to flush the trace data on a TSB instruction, when
721+
the PE is in trace prohibited state. This will cause losing a few bytes
722+
of the trace cached.
723+
724+
Workaround is to issue two TSB consecutively on affected cores.
725+
726+
If unsure, say Y.
727+
728+
config ARM64_ERRATUM_2067961
729+
bool "Neoverse-N2: 2067961: workaround TSB instruction failing to flush trace"
730+
default y
731+
select ARM64_WORKAROUND_TSB_FLUSH_FAILURE
732+
help
733+
Enable workaround for ARM Neoverse-N2 erratum 2067961
734+
735+
Affected cores may fail to flush the trace data on a TSB instruction, when
736+
the PE is in trace prohibited state. This will cause losing a few bytes
737+
of the trace cached.
738+
739+
Workaround is to issue two TSB consecutively on affected cores.
740+
741+
If unsure, say Y.
742+
710743
config CAVIUM_ERRATUM_22375
711744
bool "Cavium erratum 22375, 24313"
712745
default y

arch/arm64/include/asm/barrier.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
#define dsb(opt) asm volatile("dsb " #opt : : : "memory")
2424

2525
#define psb_csync() asm volatile("hint #17" : : : "memory")
26-
#define tsb_csync() asm volatile("hint #18" : : : "memory")
26+
#define __tsb_csync() asm volatile("hint #18" : : : "memory")
2727
#define csdb() asm volatile("hint #20" : : : "memory")
2828

2929
#ifdef CONFIG_ARM64_PSEUDO_NMI
@@ -46,6 +46,20 @@
4646
#define dma_rmb() dmb(oshld)
4747
#define dma_wmb() dmb(oshst)
4848

49+
50+
#define tsb_csync() \
51+
do { \
52+
/* \
53+
* CPUs affected by Arm Erratum 2054223 or 2067961 needs \
54+
* another TSB to ensure the trace is flushed. The barriers \
55+
* don't have to be strictly back to back, as long as the \
56+
* CPU is in trace prohibited state. \
57+
*/ \
58+
if (cpus_have_final_cap(ARM64_WORKAROUND_TSB_FLUSH_FAILURE)) \
59+
__tsb_csync(); \
60+
__tsb_csync(); \
61+
} while (0)
62+
4963
/*
5064
* Generate a mask for array_index__nospec() that is ~0UL when 0 <= idx < sz
5165
* and 0 otherwise.

arch/arm64/kernel/cpu_errata.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,18 @@ static const struct midr_range trbe_overwrite_fill_mode_cpus[] = {
352352
};
353353
#endif /* CONFIG_ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE */
354354

355+
#ifdef CONFIG_ARM64_WORKAROUND_TSB_FLUSH_FAILURE
356+
static const struct midr_range tsb_flush_fail_cpus[] = {
357+
#ifdef CONFIG_ARM64_ERRATUM_2067961
358+
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
359+
#endif
360+
#ifdef CONFIG_ARM64_ERRATUM_2054223
361+
MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
362+
#endif
363+
{},
364+
};
365+
#endif /* CONFIG_ARM64_WORKAROUND_TSB_FLUSH_FAILURE */
366+
355367
const struct arm64_cpu_capabilities arm64_errata[] = {
356368
#ifdef CONFIG_ARM64_WORKAROUND_CLEAN_CACHE
357369
{
@@ -558,6 +570,13 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
558570
.type = ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE,
559571
CAP_MIDR_RANGE_LIST(trbe_overwrite_fill_mode_cpus),
560572
},
573+
#endif
574+
#ifdef CONFIG_ARM64_WORKAROUND_TSB_FLUSH_FAILURE
575+
{
576+
.desc = "ARM erratum 2067961 or 2054223",
577+
.capability = ARM64_WORKAROUND_TSB_FLUSH_FAILURE,
578+
ERRATA_MIDR_RANGE_LIST(tsb_flush_fail_cpus),
579+
},
561580
#endif
562581
{
563582
}

arch/arm64/tools/cpucaps

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ WORKAROUND_1463225
5454
WORKAROUND_1508412
5555
WORKAROUND_1542419
5656
WORKAROUND_TRBE_OVERWRITE_FILL_MODE
57+
WORKAROUND_TSB_FLUSH_FAILURE
5758
WORKAROUND_CAVIUM_23154
5859
WORKAROUND_CAVIUM_27456
5960
WORKAROUND_CAVIUM_30115

0 commit comments

Comments
 (0)