提交 c1191e5c 编写于 作者: J James Morse 提交者: Caspar Zhang

arm64: errata: Hide CTR_EL0.DIC on systems affected by Neoverse-N1 #1542419

task #28924046

[ Upstream commit 05460849c3b5 ]
Cores affected by Neoverse-N1 #1542419 could execute a stale instruction
when a branch is updated to point to freshly generated instructions.

To workaround this issue we need user-space to issue unnecessary
icache maintenance that we can trap. Start by hiding CTR_EL0.DIC.

Backport change:
Modify the ARM64_WORKAROUND_1542419 from 45 to 37
Reviewed-by: NSuzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: NJames Morse <james.morse@arm.com>
Signed-off-by: NCatalin Marinas <catalin.marinas@arm.com>
Signed-off-by: NBin Yu <jkchen@linux.alibaba.com>
Reviewed-by: NBaolin Wang <baolin.wang@linux.alibaba.com>
Reviewed-by: Nzou cao <zoucao@linux.alibaba.com>
上级 63447ec2
...@@ -520,6 +520,22 @@ config ARM64_ERRATUM_1418040 ...@@ -520,6 +520,22 @@ config ARM64_ERRATUM_1418040
If unsure, say Y. If unsure, say Y.
config ARM64_ERRATUM_1542419
bool "Neoverse-N1: workaround mis-ordering of instruction fetches"
default y
help
This option adds a workaround for ARM Neoverse-N1 erratum
1542419.
Affected Neoverse-N1 cores could execute a stale instruction when
modified by another CPU. The workaround depends on a firmware
counterpart.
Workaround the issue by hiding the DIC feature from EL0. This
forces user-space to perform cache maintenance.
If unsure, say Y.
config CAVIUM_ERRATUM_22375 config CAVIUM_ERRATUM_22375
bool "Cavium erratum 22375, 24313" bool "Cavium erratum 22375, 24313"
default y default y
......
...@@ -55,7 +55,8 @@ ...@@ -55,7 +55,8 @@
#define ARM64_SSBS 34 #define ARM64_SSBS 34
#define ARM64_HAS_CRC32 35 #define ARM64_HAS_CRC32 35
#define ARM64_WORKAROUND_1418040 36 #define ARM64_WORKAROUND_1418040 36
#define ARM64_WORKAROUND_1542419 37
#define ARM64_NCAPS 37 #define ARM64_NCAPS 38
#endif /* __ASM_CPUCAPS_H */ #endif /* __ASM_CPUCAPS_H */
...@@ -82,13 +82,21 @@ has_mismatched_cache_type(const struct arm64_cpu_capabilities *entry, ...@@ -82,13 +82,21 @@ has_mismatched_cache_type(const struct arm64_cpu_capabilities *entry,
} }
static void static void
cpu_enable_trap_ctr_access(const struct arm64_cpu_capabilities *__unused) cpu_enable_trap_ctr_access(const struct arm64_cpu_capabilities *cap)
{ {
u64 mask = arm64_ftr_reg_ctrel0.strict_mask; u64 mask = arm64_ftr_reg_ctrel0.strict_mask;
bool enable_uct_trap = false;
/* Trap CTR_EL0 access on this CPU, only if it has a mismatch */ /* Trap CTR_EL0 access on this CPU, only if it has a mismatch */
if ((read_cpuid_cachetype() & mask) != if ((read_cpuid_cachetype() & mask) !=
(arm64_ftr_reg_ctrel0.sys_val & mask)) (arm64_ftr_reg_ctrel0.sys_val & mask))
enable_uct_trap = true;
/* ... or if the system is affected by an erratum */
if (cap->capability == ARM64_WORKAROUND_1542419)
enable_uct_trap = true;
if (enable_uct_trap)
sysreg_clear_set(sctlr_el1, SCTLR_EL1_UCT, 0); sysreg_clear_set(sctlr_el1, SCTLR_EL1_UCT, 0);
} }
...@@ -648,6 +656,18 @@ needs_tx2_tvm_workaround(const struct arm64_cpu_capabilities *entry, ...@@ -648,6 +656,18 @@ needs_tx2_tvm_workaround(const struct arm64_cpu_capabilities *entry,
return false; return false;
} }
static bool __maybe_unused
has_neoverse_n1_erratum_1542419(const struct arm64_cpu_capabilities *entry,
int scope)
{
u32 midr = read_cpuid_id();
bool has_dic = read_cpuid_cachetype() & BIT(CTR_DIC_SHIFT);
const struct midr_range range = MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1);
WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
return is_midr_in_range(midr, &range) && has_dic;
}
#ifdef CONFIG_HARDEN_EL2_VECTORS #ifdef CONFIG_HARDEN_EL2_VECTORS
static const struct midr_range arm64_harden_el2_vectors[] = { static const struct midr_range arm64_harden_el2_vectors[] = {
...@@ -861,6 +881,17 @@ const struct arm64_cpu_capabilities arm64_errata[] = { ...@@ -861,6 +881,17 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
ERRATA_MIDR_RANGE_LIST(erratum_1418040_list), ERRATA_MIDR_RANGE_LIST(erratum_1418040_list),
}, },
#endif #endif
#ifdef CONFIG_ARM64_ERRATUM_1542419
{
/* we depend on the firmware portion for correctness */
.desc = "ARM erratum 1542419 (kernel portion)",
.capability = ARM64_WORKAROUND_1542419,
.type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM,
.matches = has_neoverse_n1_erratum_1542419,
.cpu_enable = cpu_enable_trap_ctr_access,
},
#endif
{ {
} }
}; };
......
...@@ -481,6 +481,9 @@ static void ctr_read_handler(unsigned int esr, struct pt_regs *regs) ...@@ -481,6 +481,9 @@ static void ctr_read_handler(unsigned int esr, struct pt_regs *regs)
int rt = (esr & ESR_ELx_SYS64_ISS_RT_MASK) >> ESR_ELx_SYS64_ISS_RT_SHIFT; int rt = (esr & ESR_ELx_SYS64_ISS_RT_MASK) >> ESR_ELx_SYS64_ISS_RT_SHIFT;
unsigned long val = arm64_ftr_reg_user_value(&arm64_ftr_reg_ctrel0); unsigned long val = arm64_ftr_reg_user_value(&arm64_ftr_reg_ctrel0);
if (cpus_have_const_cap(ARM64_WORKAROUND_1542419))
val &= ~BIT(CTR_DIC_SHIFT);
pt_regs_write_reg(regs, rt, val); pt_regs_write_reg(regs, rt, val);
arm64_skip_faulting_instruction(regs, AARCH64_INSN_SIZE); arm64_skip_faulting_instruction(regs, AARCH64_INSN_SIZE);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册