diff options
author | Sebastian Andrzej Siewior <bigeasy@linutronix.de> | 2021-07-29 11:36:30 +0300 |
---|---|---|
committer | Minda Chen <minda.chen@starfivetech.com> | 2023-11-06 14:24:52 +0300 |
commit | b00b3ea5c737160dd829077636c0f5554e41ef2e (patch) | |
tree | b5963207d37371d8bb7f0369aa9f6e4698ed3106 | |
parent | dcc75fc8b5cf7334fc212c72538827796803c35a (diff) | |
download | linux-b00b3ea5c737160dd829077636c0f5554e41ef2e.tar.xz |
arm64/sve: Make kernel FPU protection RT friendly
Non RT kernels need to protect FPU against preemption and bottom half
processing. This is achieved by disabling bottom halves via
local_bh_disable() which implictly disables preemption.
On RT kernels this protection mechanism is not sufficient because
local_bh_disable() does not disable preemption. It serializes bottom half
related processing via a CPU local lock.
As bottom halves are running always in thread context on RT kernels
disabling preemption is the proper choice as it implicitly prevents bottom
half processing.
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
-rw-r--r-- | arch/arm64/kernel/fpsimd.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c index 5e5a869b1f3a..99484e8bbade 100644 --- a/arch/arm64/kernel/fpsimd.c +++ b/arch/arm64/kernel/fpsimd.c @@ -179,10 +179,19 @@ static void __get_cpu_fpsimd_context(void) * * The double-underscore version must only be called if you know the task * can't be preempted. + * + * On RT kernels local_bh_disable() is not sufficient because it only + * serializes soft interrupt related sections via a local lock, but stays + * preemptible. Disabling preemption is the right choice here as bottom + * half processing is always in thread context on RT kernels so it + * implicitly prevents bottom half processing as well. */ static void get_cpu_fpsimd_context(void) { - local_bh_disable(); + if (!IS_ENABLED(CONFIG_PREEMPT_RT)) + local_bh_disable(); + else + preempt_disable(); __get_cpu_fpsimd_context(); } @@ -203,7 +212,10 @@ static void __put_cpu_fpsimd_context(void) static void put_cpu_fpsimd_context(void) { __put_cpu_fpsimd_context(); - local_bh_enable(); + if (!IS_ENABLED(CONFIG_PREEMPT_RT)) + local_bh_enable(); + else + preempt_enable(); } static bool have_cpu_fpsimd_context(void) |