Skip to content

Commit

Permalink
x86/fpu: Make kernel FPU protection RT friendly
Browse files Browse the repository at this point in the history
Non RT kernels need to protect FPU against preemption and bottom half
processing. This is achieved by disabling bottom halfs 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 halfs 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: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20201027101349.588965083@linutronix.de
  • Loading branch information
Thomas Gleixner committed Nov 11, 2020
1 parent 5f0c712 commit cba08c5
Showing 1 changed file with 16 additions and 2 deletions.
18 changes: 16 additions & 2 deletions arch/x86/include/asm/fpu/api.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,29 @@ extern void fpregs_mark_activate(void);
*
* local_bh_disable() protects against both preemption and soft interrupts
* on !RT kernels.
*
* 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.
*
* Disabling preemption also serializes against kernel_fpu_begin().
*/
static inline void fpregs_lock(void)
{
local_bh_disable();
if (!IS_ENABLED(CONFIG_PREEMPT_RT))
local_bh_disable();
else
preempt_disable();
}

static inline void fpregs_unlock(void)
{
local_bh_enable();
if (!IS_ENABLED(CONFIG_PREEMPT_RT))
local_bh_enable();
else
preempt_enable();
}

#ifdef CONFIG_X86_DEBUG_FPU
Expand Down

0 comments on commit cba08c5

Please sign in to comment.