mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
xen/arm: Add workaround for Cortex-A76/Neoverse-N1 erratum #1286807
On the affected Cortex-A76/Neoverse-N1 cores (r0p0 to r3p0), if a virtual address for a cacheable mapping of a location is being accessed by a core while another core is remapping the virtual address to a new physical page using the recommended break-before-make sequence, then under very rare circumstances TLBI+DSB completes before a read using the translation being invalidated has been observed by other observers. The workaround repeats the TLBI+DSB operation for all the TLB flush operations. While this is stricly not necessary, we don't want to take any risk. Signed-off-by: Michal Orzel <michal.orzel@arm.com> Reviewed-by: Bertrand Marquis <bertrand.marquis@arm.com> Reviewed-by: Stefano Stabellini <sstabellini@kernel.org> Reviewed-by: Julien Grall <jgrall@amazon.com>
This commit is contained in:
1 parent
5200fba9ce
commit
22e323d115
5 files changed
+62
-10
No files matched your search
@@ -53,5 +53,7 @@ stable hypervisors.
|
||||
| ARM | Cortex-A72 | #853709 | N/A |
|
||||
| ARM | Cortex-A73 | #858921 | ARM_ERRATUM_858921 |
|
||||
| ARM | Cortex-A76 | #1165522 | N/A |
|
||||
| ARM | Cortex-A76 | #1286807 | ARM64_ERRATUM_1286807 |
|
||||
| ARM | Neoverse-N1 | #1165522 | N/A
|
||||
| ARM | Neoverse-N1 | #1286807 | ARM64_ERRATUM_1286807 |
|
||||
| ARM | MMU-500 | #842869 | N/A |
|
||||
@@ -244,6 +244,29 @@ config ARM_ERRATUM_858921
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
config ARM64_WORKAROUND_REPEAT_TLBI
|
||||
bool
|
||||
|
||||
config ARM64_ERRATUM_1286807
|
||||
bool "Cortex-A76/Neoverse-N1: 1286807: Modification of the translation table for a virtual address might lead to read-after-read ordering violation"
|
||||
default y
|
||||
select ARM64_WORKAROUND_REPEAT_TLBI
|
||||
depends on ARM_64
|
||||
help
|
||||
This option adds a workaround for ARM Cortex-A76/Neoverse-N1 erratum 1286807.
|
||||
|
||||
On the affected Cortex-A76/Neoverse-N1 cores (r0p0 to r3p0), if a virtual
|
||||
address for a cacheable mapping of a location is being
|
||||
accessed by a core while another core is remapping the virtual
|
||||
address to a new physical page using the recommended
|
||||
break-before-make sequence, then under very rare circumstances
|
||||
TLBI+DSB completes before a read using the translation being
|
||||
invalidated has been observed by other observers. The
|
||||
workaround repeats the TLBI+DSB operation for all the TLB flush
|
||||
operations.
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
endmenu
|
||||
|
||||
config ARM64_HARDEN_BRANCH_PREDICTOR
|
||||
|
||||
@@ -424,6 +424,20 @@ static const struct arm_cpu_capabilities arm_errata[] = {
|
||||
(1 << MIDR_VARIANT_SHIFT) | 2),
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_ARM64_ERRATUM_1286807
|
||||
{
|
||||
/* Cortex-A76 r0p0 - r3p0 */
|
||||
.desc = "ARM erratum 1286807",
|
||||
.capability = ARM64_WORKAROUND_REPEAT_TLBI,
|
||||
MIDR_RANGE(MIDR_CORTEX_A76, 0, 3 << MIDR_VARIANT_SHIFT),
|
||||
},
|
||||
{
|
||||
/* Neoverse-N1 r0p0 - r3p0 */
|
||||
.desc = "ARM erratum 1286807",
|
||||
.capability = ARM64_WORKAROUND_REPEAT_TLBI,
|
||||
MIDR_RANGE(MIDR_NEOVERSE_N1, 0, 3 << MIDR_VARIANT_SHIFT),
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_ARM64_HARDEN_BRANCH_PREDICTOR
|
||||
{
|
||||
.capability = ARM_HARDEN_BRANCH_PREDICTOR,
|
||||
|
||||
@@ -9,6 +9,12 @@
|
||||
* DSB ISH // Ensure the TLB invalidation has completed
|
||||
* ISB // See explanation below
|
||||
*
|
||||
* ARM64_WORKAROUND_REPEAT_TLBI:
|
||||
* Modification of the translation table for a virtual address might lead to
|
||||
* read-after-read ordering violation.
|
||||
* The workaround repeats TLBI+DSB operation for all the TLB flush operations.
|
||||
* While this is stricly not necessary, we don't want to take any risk.
|
||||
*
|
||||
* For Xen page-tables the ISB will discard any instructions fetched
|
||||
* from the old mappings.
|
||||
*
|
||||
@@ -16,15 +22,21 @@
|
||||
* (and therefore the TLB invalidation) before continuing. So we know
|
||||
* the TLBs cannot contain an entry for a mapping we may have removed.
|
||||
*/
|
||||
#define TLB_HELPER(name, tlbop) \
|
||||
static inline void name(void) \
|
||||
{ \
|
||||
asm volatile( \
|
||||
"dsb ishst;" \
|
||||
"tlbi " # tlbop ";" \
|
||||
"dsb ish;" \
|
||||
"isb;" \
|
||||
: : : "memory"); \
|
||||
#define TLB_HELPER(name, tlbop) \
|
||||
static inline void name(void) \
|
||||
{ \
|
||||
asm volatile( \
|
||||
"dsb ishst;" \
|
||||
"tlbi " # tlbop ";" \
|
||||
ALTERNATIVE( \
|
||||
"nop; nop;", \
|
||||
"dsb ish;" \
|
||||
"tlbi " # tlbop ";", \
|
||||
ARM64_WORKAROUND_REPEAT_TLBI, \
|
||||
CONFIG_ARM64_WORKAROUND_REPEAT_TLBI) \
|
||||
"dsb ish;" \
|
||||
"isb;" \
|
||||
: : : "memory"); \
|
||||
}
|
||||
|
||||
/* Flush local TLBs, current VMID only. */
|
||||
|
||||
@@ -46,8 +46,9 @@
|
||||
#define ARM_SMCCC_1_1 8
|
||||
#define ARM64_WORKAROUND_AT_SPECULATE 9
|
||||
#define ARM_WORKAROUND_858921 10
|
||||
#define ARM64_WORKAROUND_REPEAT_TLBI 11
|
||||
|
||||
#define ARM_NCAPS 11
|
||||
#define ARM_NCAPS 12
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
|
||||