From: Jan Kiszka <jan.kis...@siemens.com> First of all, this erratum hook is called from __switch_to, thus potentially also from the primary domain. Some of the functions it calls check if preemption was disabled under Linux - which may not be the case when invoked from primary domain. Rather than adding a costly check for ipipe_root_p to this hot-path, simply turn the check off if I-pipe is enabled.
As the hook can be called from primary context, we need to protect its setup for new execs against those contexts via hard_preempt_disable. Signed-off-by: Jan Kiszka <jan.kis...@siemens.com> --- This is for 5.4-only, older kernels do no have the erratum fix. Philippe, the hardening of erratum_1418040_new_exec() could be a topic for dovetail as well. preemptible() is fully oob-aware there, though. arch/arm64/kernel/cpu_errata.c | 3 ++- arch/arm64/kernel/cpufeature.c | 3 ++- arch/arm64/kernel/process.c | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c index 1e16c4e00e771..7fd7d1c8b9fcc 100644 --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c @@ -37,7 +37,8 @@ static bool __maybe_unused is_affected_midr_range_list(const struct arm64_cpu_capabilities *entry, int scope) { - WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible()); + WARN_ON(scope != SCOPE_LOCAL_CPU || + (preemptible() && !IS_ENABLED(CONFIG_IPIPE))); return is_midr_in_range_list(read_cpuid_id(), entry->midr_range_list); } diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index acdef8d76c64d..d65287cc2148b 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -2023,7 +2023,8 @@ static void __init mark_const_caps_ready(void) bool this_cpu_has_cap(unsigned int n) { - if (!WARN_ON(preemptible()) && n < ARM64_NCAPS) { + if (!WARN_ON(!IS_ENABLED(CONFIG_IPIPE) && preemptible()) && + n < ARM64_NCAPS) { const struct arm64_cpu_capabilities *cap = cpu_hwcaps_ptrs[n]; if (cap) diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index 68c078ab0250c..879ecf0237c88 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c @@ -517,9 +517,9 @@ static void erratum_1418040_thread_switch(struct task_struct *next) static void erratum_1418040_new_exec(void) { - preempt_disable(); + unsigned long flags = hard_preempt_disable(); erratum_1418040_thread_switch(current); - preempt_enable(); + hard_preempt_enable(flags); } /* -- 2.34.1