Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 85191ed0 authored by Andy Lutomirski's avatar Andy Lutomirski Committed by Greg Kroah-Hartman
Browse files

x86/fpu: Fix math emulation in eager fpu mode



commit 4ecd16ec7059390b430af34bd8bc3ca2b5dcef9a upstream.

Systems without an FPU are generally old and therefore use lazy FPU
switching. Unsurprisingly, math emulation in eager FPU mode is a
bit buggy. Fix it.

There were two bugs involving kernel code trying to use the FPU
registers in eager mode even if they didn't exist and one BUG_ON()
that was incorrect.

Signed-off-by: default avatarAndy Lutomirski <luto@kernel.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.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: Rik van Riel <riel@redhat.com>
Cc: Sai Praneeth Prakhya <sai.praneeth.prakhya@intel.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: yu-cheng yu <yu-cheng.yu@intel.com>
Link: http://lkml.kernel.org/r/b4b8d112436bd6fab866e1b4011131507e8d7fbe.1453675014.git.luto@kernel.org


Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent a2dd2844
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -596,7 +596,8 @@ switch_fpu_prepare(struct fpu *old_fpu, struct fpu *new_fpu, int cpu)
	 * If the task has used the math, pre-load the FPU on xsave processors
	 * or if the past 5 consecutive context-switches used math.
	 */
	fpu.preload = new_fpu->fpstate_active &&
	fpu.preload = static_cpu_has(X86_FEATURE_FPU) &&
		      new_fpu->fpstate_active &&
		      (use_eager_fpu() || new_fpu->counter > 5);

	if (old_fpu->fpregs_active) {
+1 −1
Original line number Diff line number Diff line
@@ -437,7 +437,7 @@ void fpu__clear(struct fpu *fpu)
{
	WARN_ON_FPU(fpu != &current->thread.fpu); /* Almost certainly an anomaly */

	if (!use_eager_fpu()) {
	if (!use_eager_fpu() || !static_cpu_has(X86_FEATURE_FPU)) {
		/* FPU state will be reallocated lazily at the first use. */
		fpu__drop(fpu);
	} else {
+0 −1
Original line number Diff line number Diff line
@@ -751,7 +751,6 @@ dotraplinkage void
do_device_not_available(struct pt_regs *regs, long error_code)
{
	RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU");
	BUG_ON(use_eager_fpu());

#ifdef CONFIG_MATH_EMULATION
	if (read_cr0() & X86_CR0_EM) {