mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2025-01-24 14:54:49 +08:00
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 -----BEGIN PGP SIGNATURE----- iQJHBAABCgAxFiEEQp8+kY+LLUocC4bMphj1TA10mKEFAmJ3sb0THHRnbHhAbGlu dXRyb25peC5kZQAKCRCmGPVMDXSYoRR9EACOcJAkO4ZjHvQf8RDw4ZaC/d0PgEC1 rEcxL7Tq9qAjdY+VmoRdzAia1FbKWrSNzENiBaTwdM2dxsZN0cl5fEQAy5ffHKXr IadRIHICu6INKQ0iuf4VdOt8HuMC+Ams9sFoVDId1avRoejsjIHeCpgBen+0/LQf D4i+nvUL9hMcZDsWiQW9mTe8J4fqr7rrg+p7tD0300DbZ6/PFx+zWP58TE8K7vQ8 dsmfMXxDrJW3d9FOHHvPQXa/Okdm2fHxXuxs3Quc+7HG6cMcwefCYugf8HK3E14F q0O6IAOfiYzCL+8aNo4J3H5jPEGLMJ7JlY5Yoygc1mcx0uGyVraMbFOsK8WuRFvP eAmx31Wh6EIYOwaboSG+74k/b3hPa6Hx3R7aQDS+SnQQI6I9fdi3ZZtQ+DGnZBZG Ipq/f+EjaROh1atUwhE4zM80UKSU6RWEWAlMO4K07uO8a3RnR8qV7N8tl44i+Q7k KZUbN5/aV4ccZNwMbazcpZ32fe3SB9cD4e/aLqpMp0uOl9TVxcOA3hIkQ0wflh94 6XO+gPdvr5VxWayc9tljMXUGPxwjTN4zDKUIlZP2EzYHt6SyZpdwi2+8moEfvU+a qcIWPLeXb+972LaY+rTicT4cQxCKe0CZEXCOq1ns+Ni5f5TdKkvyxpeMIOrGtjYG /4RqWncPKIyuEw== =PpOB -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
27b5d61c0c
10
MAINTAINERS
10
MAINTAINERS
@ -7499,7 +7499,7 @@ F: Documentation/hwmon/f71805f.rst
|
||||
F: drivers/hwmon/f71805f.c
|
||||
|
||||
FADDR2LINE
|
||||
M: Josh Poimboeuf <jpoimboe@redhat.com>
|
||||
M: Josh Poimboeuf <jpoimboe@kernel.org>
|
||||
S: Maintained
|
||||
F: scripts/faddr2line
|
||||
|
||||
@ -11348,7 +11348,7 @@ F: drivers/mmc/host/litex_mmc.c
|
||||
N: litex
|
||||
|
||||
LIVE PATCHING
|
||||
M: Josh Poimboeuf <jpoimboe@redhat.com>
|
||||
M: Josh Poimboeuf <jpoimboe@kernel.org>
|
||||
M: Jiri Kosina <jikos@kernel.org>
|
||||
M: Miroslav Benes <mbenes@suse.cz>
|
||||
M: Petr Mladek <pmladek@suse.com>
|
||||
@ -14224,7 +14224,7 @@ F: lib/objagg.c
|
||||
F: lib/test_objagg.c
|
||||
|
||||
OBJTOOL
|
||||
M: Josh Poimboeuf <jpoimboe@redhat.com>
|
||||
M: Josh Poimboeuf <jpoimboe@kernel.org>
|
||||
M: Peter Zijlstra <peterz@infradead.org>
|
||||
S: Supported
|
||||
F: tools/objtool/
|
||||
@ -18792,7 +18792,7 @@ F: include/dt-bindings/reset/starfive-jh7100.h
|
||||
|
||||
STATIC BRANCH/CALL
|
||||
M: Peter Zijlstra <peterz@infradead.org>
|
||||
M: Josh Poimboeuf <jpoimboe@redhat.com>
|
||||
M: Josh Poimboeuf <jpoimboe@kernel.org>
|
||||
M: Jason Baron <jbaron@akamai.com>
|
||||
R: Steven Rostedt <rostedt@goodmis.org>
|
||||
R: Ard Biesheuvel <ardb@kernel.org>
|
||||
@ -21444,7 +21444,7 @@ F: arch/x86/kernel/apic/x2apic_uv_x.c
|
||||
F: arch/x86/platform/uv/
|
||||
|
||||
X86 STACK UNWINDING
|
||||
M: Josh Poimboeuf <jpoimboe@redhat.com>
|
||||
M: Josh Poimboeuf <jpoimboe@kernel.org>
|
||||
M: Peter Zijlstra <peterz@infradead.org>
|
||||
S: Supported
|
||||
F: arch/x86/include/asm/unwind*.h
|
||||
|
@ -41,17 +41,7 @@ struct fpu_state_config fpu_user_cfg __ro_after_init;
|
||||
*/
|
||||
struct fpstate init_fpstate __ro_after_init;
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
/* Track in-kernel FPU usage */
|
||||
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);
|
||||
|
||||
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
|
||||
* 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)
|
||||
{
|
||||
return !in_interrupt() ||
|
||||
interrupted_user_mode() ||
|
||||
interrupted_kernel_fpu_idle();
|
||||
if (WARN_ON_ONCE(in_nmi()))
|
||||
return false;
|
||||
|
||||
/* 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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user