Skip to content

Commit 27b5d61

Browse files
committed
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
2 parents ea82593 + 59f5ede commit 27b5d61

File tree

2 files changed

+31
-46
lines changed

2 files changed

+31
-46
lines changed

MAINTAINERS

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7499,7 +7499,7 @@ F: Documentation/hwmon/f71805f.rst
74997499
F: drivers/hwmon/f71805f.c
75007500

75017501
FADDR2LINE
7502-
M: Josh Poimboeuf <jpoimboe@redhat.com>
7502+
M: Josh Poimboeuf <jpoimboe@kernel.org>
75037503
S: Maintained
75047504
F: scripts/faddr2line
75057505

@@ -11348,7 +11348,7 @@ F: drivers/mmc/host/litex_mmc.c
1134811348
N: litex
1134911349

1135011350
LIVE PATCHING
11351-
M: Josh Poimboeuf <jpoimboe@redhat.com>
11351+
M: Josh Poimboeuf <jpoimboe@kernel.org>
1135211352
M: Jiri Kosina <[email protected]>
1135311353
M: Miroslav Benes <[email protected]>
1135411354
M: Petr Mladek <[email protected]>
@@ -14224,7 +14224,7 @@ F: lib/objagg.c
1422414224
F: lib/test_objagg.c
1422514225

1422614226
OBJTOOL
14227-
M: Josh Poimboeuf <jpoimboe@redhat.com>
14227+
M: Josh Poimboeuf <jpoimboe@kernel.org>
1422814228
M: Peter Zijlstra <[email protected]>
1422914229
S: Supported
1423014230
F: tools/objtool/
@@ -18792,7 +18792,7 @@ F: include/dt-bindings/reset/starfive-jh7100.h
1879218792

1879318793
STATIC BRANCH/CALL
1879418794
M: Peter Zijlstra <[email protected]>
18795-
M: Josh Poimboeuf <jpoimboe@redhat.com>
18795+
M: Josh Poimboeuf <jpoimboe@kernel.org>
1879618796
M: Jason Baron <[email protected]>
1879718797
R: Steven Rostedt <[email protected]>
1879818798
R: Ard Biesheuvel <[email protected]>
@@ -21444,7 +21444,7 @@ F: arch/x86/kernel/apic/x2apic_uv_x.c
2144421444
F: arch/x86/platform/uv/
2144521445

2144621446
X86 STACK UNWINDING
21447-
M: Josh Poimboeuf <jpoimboe@redhat.com>
21447+
M: Josh Poimboeuf <jpoimboe@kernel.org>
2144821448
M: Peter Zijlstra <[email protected]>
2144921449
S: Supported
2145021450
F: arch/x86/include/asm/unwind*.h

arch/x86/kernel/fpu/core.c

Lines changed: 26 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -41,60 +41,45 @@ struct fpu_state_config fpu_user_cfg __ro_after_init;
4141
*/
4242
struct fpstate init_fpstate __ro_after_init;
4343

44-
/*
45-
* Track whether the kernel is using the FPU state
46-
* currently.
47-
*
48-
* This flag is used:
49-
*
50-
* - by IRQ context code to potentially use the FPU
51-
* if it's unused.
52-
*
53-
* - to debug kernel_fpu_begin()/end() correctness
54-
*/
44+
/* Track in-kernel FPU usage */
5545
static DEFINE_PER_CPU(bool, in_kernel_fpu);
5646

5747
/*
5848
* Track which context is using the FPU on the CPU:
5949
*/
6050
DEFINE_PER_CPU(struct fpu *, fpu_fpregs_owner_ctx);
6151

62-
static bool kernel_fpu_disabled(void)
63-
{
64-
return this_cpu_read(in_kernel_fpu);
65-
}
66-
67-
static bool interrupted_kernel_fpu_idle(void)
68-
{
69-
return !kernel_fpu_disabled();
70-
}
71-
72-
/*
73-
* Were we in user mode (or vm86 mode) when we were
74-
* interrupted?
75-
*
76-
* Doing kernel_fpu_begin/end() is ok if we are running
77-
* in an interrupt context from user mode - we'll just
78-
* save the FPU state as required.
79-
*/
80-
static bool interrupted_user_mode(void)
81-
{
82-
struct pt_regs *regs = get_irq_regs();
83-
return regs && user_mode(regs);
84-
}
85-
8652
/*
8753
* Can we use the FPU in kernel mode with the
8854
* whole "kernel_fpu_begin/end()" sequence?
89-
*
90-
* It's always ok in process context (ie "not interrupt")
91-
* but it is sometimes ok even from an irq.
9255
*/
9356
bool irq_fpu_usable(void)
9457
{
95-
return !in_interrupt() ||
96-
interrupted_user_mode() ||
97-
interrupted_kernel_fpu_idle();
58+
if (WARN_ON_ONCE(in_nmi()))
59+
return false;
60+
61+
/* In kernel FPU usage already active? */
62+
if (this_cpu_read(in_kernel_fpu))
63+
return false;
64+
65+
/*
66+
* When not in NMI or hard interrupt context, FPU can be used in:
67+
*
68+
* - Task context except from within fpregs_lock()'ed critical
69+
* regions.
70+
*
71+
* - Soft interrupt processing context which cannot happen
72+
* while in a fpregs_lock()'ed critical region.
73+
*/
74+
if (!in_hardirq())
75+
return true;
76+
77+
/*
78+
* In hard interrupt context it's safe when soft interrupts
79+
* are enabled, which means the interrupt did not hit in
80+
* a fpregs_lock()'ed critical region.
81+
*/
82+
return !softirq_count();
9883
}
9984
EXPORT_SYMBOL(irq_fpu_usable);
10085

0 commit comments

Comments
 (0)