Re: Sanitize CPU-state when switching tasks (was sanitize CPU-statewhen switching from virtual-8086 mode to other task)

From: Linus Torvalds
Date: Thu Jan 09 2014 - 19:42:43 EST


On Fri, Jan 10, 2014 at 6:58 AM, Borislav Petkov <bp@xxxxxxxxx> wrote:
>
> Ok, I was able to reproduce

Looking at this, I think this is just a bug in our
restore_fpu_checking() hackery for X86_FEATURE_FXSAVE_LEAK..

Which also explains why it only triggers on E-350 - it's only relevant
for those K7/K8 CPU's that use this.

Maybe just add a fcnlex to before the emms? Something like this
(TOTALLY UNTESTED!!) attached patch.

Linus
arch/x86/include/asm/fpu-internal.h | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/arch/x86/include/asm/fpu-internal.h b/arch/x86/include/asm/fpu-internal.h
index c49a613c6452..cea1c76d49bf 100644
--- a/arch/x86/include/asm/fpu-internal.h
+++ b/arch/x86/include/asm/fpu-internal.h
@@ -293,12 +293,13 @@ static inline int restore_fpu_checking(struct task_struct *tsk)
/* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception
is pending. Clear the x87 state here by setting it to fixed
values. "m" is a random variable that should be in L1 */
- alternative_input(
- ASM_NOP8 ASM_NOP2,
- "emms\n\t" /* clear stack tags */
- "fildl %P[addr]", /* set F?P to defined value */
- X86_FEATURE_FXSAVE_LEAK,
- [addr] "m" (tsk->thread.fpu.has_fpu));
+ if (unlikely(static_cpu_has(X86_FEATURE_FXSAVE_LEAK))) {
+ asm volatile(
+ "fnclex\n\t"
+ "emms\n\t"
+ "fildl %P[addr]" /* set F?P to defined value */
+ : : [addr] "m" (tsk->thread.fpu.has_fpu));
+ }

return fpu_restore_checking(&tsk->thread.fpu);
}