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

Reply via email to