Commit 27b5d61c authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'x86-urgent-2022-05-08' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 fix from Thomas Gleixner:
 "A fix and an email address update:

   - Prevent FPU state corruption.

     The condition in irq_fpu_usable() grants FPU usage when the FPU is
     not used in the kernel. That's just wrong as it does not take the
     fpregs_lock()'ed regions into account. If FPU usage happens within
     such a region from interrupt context, then the FPU state gets
     corrupted.

     That's a long standing bug, which got unearthed by the recent
     changes to the random code.

   - Josh wants to use his kernel.org email address"

* tag 'x86-urgent-2022-05-08' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/fpu: Prevent FPU state corruption
  MAINTAINERS: Update Josh Poimboeuf's email address
parents ea82593b 59f5ede3
...@@ -7499,7 +7499,7 @@ F: Documentation/hwmon/f71805f.rst ...@@ -7499,7 +7499,7 @@ F: Documentation/hwmon/f71805f.rst
F: drivers/hwmon/f71805f.c F: drivers/hwmon/f71805f.c
FADDR2LINE FADDR2LINE
M: Josh Poimboeuf <jpoimboe@redhat.com> M: Josh Poimboeuf <jpoimboe@kernel.org>
S: Maintained S: Maintained
F: scripts/faddr2line F: scripts/faddr2line
...@@ -11348,7 +11348,7 @@ F: drivers/mmc/host/litex_mmc.c ...@@ -11348,7 +11348,7 @@ F: drivers/mmc/host/litex_mmc.c
N: litex N: litex
LIVE PATCHING LIVE PATCHING
M: Josh Poimboeuf <jpoimboe@redhat.com> M: Josh Poimboeuf <jpoimboe@kernel.org>
M: Jiri Kosina <jikos@kernel.org> M: Jiri Kosina <jikos@kernel.org>
M: Miroslav Benes <mbenes@suse.cz> M: Miroslav Benes <mbenes@suse.cz>
M: Petr Mladek <pmladek@suse.com> M: Petr Mladek <pmladek@suse.com>
...@@ -14224,7 +14224,7 @@ F: lib/objagg.c ...@@ -14224,7 +14224,7 @@ F: lib/objagg.c
F: lib/test_objagg.c F: lib/test_objagg.c
OBJTOOL OBJTOOL
M: Josh Poimboeuf <jpoimboe@redhat.com> M: Josh Poimboeuf <jpoimboe@kernel.org>
M: Peter Zijlstra <peterz@infradead.org> M: Peter Zijlstra <peterz@infradead.org>
S: Supported S: Supported
F: tools/objtool/ F: tools/objtool/
...@@ -18792,7 +18792,7 @@ F: include/dt-bindings/reset/starfive-jh7100.h ...@@ -18792,7 +18792,7 @@ F: include/dt-bindings/reset/starfive-jh7100.h
STATIC BRANCH/CALL STATIC BRANCH/CALL
M: Peter Zijlstra <peterz@infradead.org> M: Peter Zijlstra <peterz@infradead.org>
M: Josh Poimboeuf <jpoimboe@redhat.com> M: Josh Poimboeuf <jpoimboe@kernel.org>
M: Jason Baron <jbaron@akamai.com> M: Jason Baron <jbaron@akamai.com>
R: Steven Rostedt <rostedt@goodmis.org> R: Steven Rostedt <rostedt@goodmis.org>
R: Ard Biesheuvel <ardb@kernel.org> R: Ard Biesheuvel <ardb@kernel.org>
...@@ -21444,7 +21444,7 @@ F: arch/x86/kernel/apic/x2apic_uv_x.c ...@@ -21444,7 +21444,7 @@ F: arch/x86/kernel/apic/x2apic_uv_x.c
F: arch/x86/platform/uv/ F: arch/x86/platform/uv/
X86 STACK UNWINDING X86 STACK UNWINDING
M: Josh Poimboeuf <jpoimboe@redhat.com> M: Josh Poimboeuf <jpoimboe@kernel.org>
M: Peter Zijlstra <peterz@infradead.org> M: Peter Zijlstra <peterz@infradead.org>
S: Supported S: Supported
F: arch/x86/include/asm/unwind*.h F: arch/x86/include/asm/unwind*.h
......
...@@ -41,17 +41,7 @@ struct fpu_state_config fpu_user_cfg __ro_after_init; ...@@ -41,17 +41,7 @@ struct fpu_state_config fpu_user_cfg __ro_after_init;
*/ */
struct fpstate init_fpstate __ro_after_init; struct fpstate init_fpstate __ro_after_init;
/* /* Track in-kernel FPU usage */
* Track whether the kernel is using the FPU state
* currently.
*
* This flag is used:
*
* - by IRQ context code to potentially use the FPU
* if it's unused.
*
* - to debug kernel_fpu_begin()/end() correctness
*/
static DEFINE_PER_CPU(bool, in_kernel_fpu); static DEFINE_PER_CPU(bool, in_kernel_fpu);
/* /*
...@@ -59,42 +49,37 @@ static DEFINE_PER_CPU(bool, in_kernel_fpu); ...@@ -59,42 +49,37 @@ static DEFINE_PER_CPU(bool, in_kernel_fpu);
*/ */
DEFINE_PER_CPU(struct fpu *, fpu_fpregs_owner_ctx); DEFINE_PER_CPU(struct fpu *, fpu_fpregs_owner_ctx);
static bool kernel_fpu_disabled(void)
{
return this_cpu_read(in_kernel_fpu);
}
static bool interrupted_kernel_fpu_idle(void)
{
return !kernel_fpu_disabled();
}
/*
* Were we in user mode (or vm86 mode) when we were
* interrupted?
*
* Doing kernel_fpu_begin/end() is ok if we are running
* in an interrupt context from user mode - we'll just
* save the FPU state as required.
*/
static bool interrupted_user_mode(void)
{
struct pt_regs *regs = get_irq_regs();
return regs && user_mode(regs);
}
/* /*
* Can we use the FPU in kernel mode with the * Can we use the FPU in kernel mode with the
* whole "kernel_fpu_begin/end()" sequence? * whole "kernel_fpu_begin/end()" sequence?
*
* It's always ok in process context (ie "not interrupt")
* but it is sometimes ok even from an irq.
*/ */
bool irq_fpu_usable(void) bool irq_fpu_usable(void)
{ {
return !in_interrupt() || if (WARN_ON_ONCE(in_nmi()))
interrupted_user_mode() || return false;
interrupted_kernel_fpu_idle();
/* In kernel FPU usage already active? */
if (this_cpu_read(in_kernel_fpu))
return false;
/*
* When not in NMI or hard interrupt context, FPU can be used in:
*
* - Task context except from within fpregs_lock()'ed critical
* regions.
*
* - Soft interrupt processing context which cannot happen
* while in a fpregs_lock()'ed critical region.
*/
if (!in_hardirq())
return true;
/*
* In hard interrupt context it's safe when soft interrupts
* are enabled, which means the interrupt did not hit in
* a fpregs_lock()'ed critical region.
*/
return !softirq_count();
} }
EXPORT_SYMBOL(irq_fpu_usable); EXPORT_SYMBOL(irq_fpu_usable);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment