summaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2015-05-27 12:22:29 +0200
committerIngo Molnar <mingo@kernel.org>2015-08-22 10:23:03 +0200
commit827409b2f5b58573ae3774fe6bd2d6daeb335878 (patch)
tree78840a3e3ac0a9163bafaaf70a746ef5a184736f /arch/x86
parent5fc960380ea44ba529c78b558b6cd4250e5e1958 (diff)
downloadlinux-827409b2f5b58573ae3774fe6bd2d6daeb335878.tar.bz2
x86/fpu/math-emu: Fix crash in fork()
During later stages of math-emu bootup the following crash triggers: math_emulate: 0060:c100d0a8 Kernel panic - not syncing: Math emulation needed in kernel CPU: 0 PID: 1511 Comm: login Not tainted 4.2.0-rc7+ #1012 [...] Call Trace: [<c181d50d>] dump_stack+0x41/0x52 [<c181c918>] panic+0x77/0x189 [<c1003530>] ? math_error+0x140/0x140 [<c164c2d7>] math_emulate+0xba7/0xbd0 [<c100d0a8>] ? fpu__copy+0x138/0x1c0 [<c1109c3c>] ? __alloc_pages_nodemask+0x12c/0x870 [<c136ac20>] ? proc_clear_tty+0x40/0x70 [<c136ac6e>] ? session_clear_tty+0x1e/0x30 [<c1003530>] ? math_error+0x140/0x140 [<c1003575>] do_device_not_available+0x45/0x70 [<c100d0a8>] ? fpu__copy+0x138/0x1c0 [<c18258e6>] error_code+0x5a/0x60 [<c1003530>] ? math_error+0x140/0x140 [<c100d0a8>] ? fpu__copy+0x138/0x1c0 [<c100c205>] arch_dup_task_struct+0x25/0x30 [<c1048cea>] copy_process.part.51+0xea/0x1480 [<c115a8e5>] ? dput+0x175/0x200 [<c136af70>] ? no_tty+0x30/0x30 [<c1157242>] ? do_vfs_ioctl+0x322/0x540 [<c104a21a>] _do_fork+0xca/0x340 [<c1057b06>] ? SyS_rt_sigaction+0x66/0x90 [<c104a557>] SyS_clone+0x27/0x30 [<c1824a80>] sysenter_do_call+0x12/0x12 The reason is the incorrect assumption in fpu_copy(), that FNSAVE can be executed from math-emu kernels as well. Don't try to copy the registers, the soft state will be copied by fork anyway, so the child task inherits the parent task's soft math state. With this fix applied math-emu kernels boot up fine on modern hardware and the 'no387 nofxsr' boot options. Cc: Andy Lutomirski <luto@amacapital.net> Cc: Bobby Powers <bobbypowers@gmail.com> Cc: Borislav Petkov <bp@alien8.de> Cc: Brian Gerst <brgerst@gmail.com> Cc: Dave Hansen <dave.hansen@linux.intel.com> Cc: Denys Vlasenko <dvlasenk@redhat.com> Cc: Fenghua Yu <fenghua.yu@intel.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Quentin Casasnovas <quentin.casasnovas@oracle.com> Cc: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/kernel/fpu/core.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c
index 79de954626fd..d25097c3fc1d 100644
--- a/arch/x86/kernel/fpu/core.c
+++ b/arch/x86/kernel/fpu/core.c
@@ -270,7 +270,7 @@ int fpu__copy(struct fpu *dst_fpu, struct fpu *src_fpu)
dst_fpu->fpregs_active = 0;
dst_fpu->last_cpu = -1;
- if (src_fpu->fpstate_active)
+ if (src_fpu->fpstate_active && cpu_has_fpu)
fpu_copy(dst_fpu, src_fpu);
return 0;