OSDN Git Service

i387: move AMD K7/K8 fpu fxsave/fxrstor workaround from save to restore
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 17 Feb 2012 03:11:15 +0000 (19:11 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 1 Mar 2012 00:34:25 +0000 (16:34 -0800)
commit70b5ef05d889e2be250fd1d963e89f7ca1dd1965
treee131318603a98b4dd9fcb3a24d3af89926648756
parent06f4bbda338e6aa42497b76a16cf38e2fdd29885
i387: move AMD K7/K8 fpu fxsave/fxrstor workaround from save to restore

commit 4903062b5485f0e2c286a23b44c9b59d9b017d53 upstream.

The AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception is
pending.  In order to not leak FIP state from one process to another, we
need to do a floating point load after the fxsave of the old process,
and before the fxrstor of the new FPU state.  That resets the state to
the (uninteresting) kernel load, rather than some potentially sensitive
user information.

We used to do this directly after the FPU state save, but that is
actually very inconvenient, since it

 (a) corrupts what is potentially perfectly good FPU state that we might
     want to lazy avoid restoring later and

 (b) on x86-64 it resulted in a very annoying ordering constraint, where
     "__unlazy_fpu()" in the task switch needs to be delayed until after
     the DS segment has been reloaded just to get the new DS value.

Coupling it to the fxrstor instead of the fxsave automatically avoids
both of these issues, and also ensures that we only do it when actually
necessary (the FP state after a save may never actually get used).  It's
simply a much more natural place for the leaked state cleanup.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/x86/include/asm/i387.h
arch/x86/kernel/process_64.c
arch/x86/kernel/traps.c