Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+31 -46
+5 -5
MAINTAINERS
··· 7499 7499 F: drivers/hwmon/f71805f.c 7500 7500 7501 7501 FADDR2LINE 7502 - M: Josh Poimboeuf <jpoimboe@redhat.com> 7502 + M: Josh Poimboeuf <jpoimboe@kernel.org> 7503 7503 S: Maintained 7504 7504 F: scripts/faddr2line 7505 7505 ··· 11348 11348 N: litex 11349 11349 11350 11350 LIVE PATCHING 11351 - M: Josh Poimboeuf <jpoimboe@redhat.com> 11351 + M: Josh Poimboeuf <jpoimboe@kernel.org> 11352 11352 M: Jiri Kosina <jikos@kernel.org> 11353 11353 M: Miroslav Benes <mbenes@suse.cz> 11354 11354 M: Petr Mladek <pmladek@suse.com> ··· 14224 14224 F: lib/test_objagg.c 14225 14225 14226 14226 OBJTOOL 14227 - M: Josh Poimboeuf <jpoimboe@redhat.com> 14227 + M: Josh Poimboeuf <jpoimboe@kernel.org> 14228 14228 M: Peter Zijlstra <peterz@infradead.org> 14229 14229 S: Supported 14230 14230 F: tools/objtool/ ··· 18792 18792 18793 18793 STATIC BRANCH/CALL 18794 18794 M: Peter Zijlstra <peterz@infradead.org> 18795 - M: Josh Poimboeuf <jpoimboe@redhat.com> 18795 + M: Josh Poimboeuf <jpoimboe@kernel.org> 18796 18796 M: Jason Baron <jbaron@akamai.com> 18797 18797 R: Steven Rostedt <rostedt@goodmis.org> 18798 18798 R: Ard Biesheuvel <ardb@kernel.org> ··· 21444 21444 F: arch/x86/platform/uv/ 21445 21445 21446 21446 X86 STACK UNWINDING 21447 - M: Josh Poimboeuf <jpoimboe@redhat.com> 21447 + M: Josh Poimboeuf <jpoimboe@kernel.org> 21448 21448 M: Peter Zijlstra <peterz@infradead.org> 21449 21449 S: Supported 21450 21450 F: arch/x86/include/asm/unwind*.h
+26 -41
arch/x86/kernel/fpu/core.c
··· 41 41 */ 42 42 struct fpstate init_fpstate __ro_after_init; 43 43 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 */ 55 45 static DEFINE_PER_CPU(bool, in_kernel_fpu); 56 46 57 47 /* ··· 49 59 */ 50 60 DEFINE_PER_CPU(struct fpu *, fpu_fpregs_owner_ctx); 51 61 52 - static bool kernel_fpu_disabled(void) 53 - { 54 - return this_cpu_read(in_kernel_fpu); 55 - } 56 - 57 - static bool interrupted_kernel_fpu_idle(void) 58 - { 59 - return !kernel_fpu_disabled(); 60 - } 61 - 62 - /* 63 - * Were we in user mode (or vm86 mode) when we were 64 - * interrupted? 65 - * 66 - * Doing kernel_fpu_begin/end() is ok if we are running 67 - * in an interrupt context from user mode - we'll just 68 - * save the FPU state as required. 69 - */ 70 - static bool interrupted_user_mode(void) 71 - { 72 - struct pt_regs *regs = get_irq_regs(); 73 - return regs && user_mode(regs); 74 - } 75 - 76 62 /* 77 63 * Can we use the FPU in kernel mode with the 78 64 * whole "kernel_fpu_begin/end()" sequence? 79 - * 80 - * It's always ok in process context (ie "not interrupt") 81 - * but it is sometimes ok even from an irq. 82 65 */ 83 66 bool irq_fpu_usable(void) 84 67 { 85 - return !in_interrupt() || 86 - interrupted_user_mode() || 87 - interrupted_kernel_fpu_idle(); 68 + if (WARN_ON_ONCE(in_nmi())) 69 + return false; 70 + 71 + /* In kernel FPU usage already active? */ 72 + if (this_cpu_read(in_kernel_fpu)) 73 + return false; 74 + 75 + /* 76 + * When not in NMI or hard interrupt context, FPU can be used in: 77 + * 78 + * - Task context except from within fpregs_lock()'ed critical 79 + * regions. 80 + * 81 + * - Soft interrupt processing context which cannot happen 82 + * while in a fpregs_lock()'ed critical region. 83 + */ 84 + if (!in_hardirq()) 85 + return true; 86 + 87 + /* 88 + * In hard interrupt context it's safe when soft interrupts 89 + * are enabled, which means the interrupt did not hit in 90 + * a fpregs_lock()'ed critical region. 91 + */ 92 + return !softirq_count(); 88 93 } 89 94 EXPORT_SYMBOL(irq_fpu_usable); 90 95