fpu_save() would be used later by KVM. Signed-off-by: Sheng Yang <sheng@xxxxxxxxxxxxxxx> --- arch/x86/include/asm/i387.h | 71 ++++++++++++++++++++++++++----------------- 1 files changed, 43 insertions(+), 28 deletions(-) diff --git a/arch/x86/include/asm/i387.h b/arch/x86/include/asm/i387.h index 1a8cca3..989d3b7 100644 --- a/arch/x86/include/asm/i387.h +++ b/arch/x86/include/asm/i387.h @@ -180,13 +180,17 @@ static inline void fpu_fxsave(struct fpu *fpu) #endif } -static inline void fpu_save_init(struct fpu *fpu) +static inline void fpu_save(struct fpu *fpu) { if (use_xsave()) fpu_xsave(fpu); else fpu_fxsave(fpu); +} +static inline void fpu_save_init(struct fpu *fpu) +{ + fpu_save(fpu); fpu_clear(fpu); } @@ -237,19 +241,41 @@ static inline int fxrstor_checking(struct i387_fxsave_struct *fx) /* * These must be called with preempt disabled */ -static inline void fpu_save_init(struct fpu *fpu) +static inline void fpu_fxsave(struct fpu *fpu) { - if (use_xsave()) { - struct xsave_struct *xstate = &fpu->state->xsave; - struct i387_fxsave_struct *fx = &fpu->state->fxsave; + /* Use more nops than strictly needed in case the compiler + varies code */ + alternative_input( + "fnsave %[fx] ;fwait;" GENERIC_NOP8 GENERIC_NOP4, + "fxsave %[fx]\n" + "bt $7,%[fsw] ; jnc 1f ; fnclex\n1:", + X86_FEATURE_FXSR, + [fx] "m" (fpu->state->fxsave), + [fsw] "m" (fpu->state->fxsave.swd) : "memory"); +} +static inline void fpu_save(struct fpu *fpu) +{ + if (use_xsave()) fpu_xsave(fpu); + else + fpu_fxsave(fpu); +} + +/* 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. safe_address is a random variable that should be in L1 */ +static inline void fpu_clear(struct fpu *fpu) +{ + struct xsave_struct *xstate = &fpu->state->xsave; + struct i387_fxsave_struct *fx = &fpu->state->fxsave; + if (use_xsave()) { /* * xsave header may indicate the init state of the FP. */ if (!(xstate->xsave_hdr.xstate_bv & XSTATE_FP)) - goto end; + return; if (unlikely(fx->swd & X87_FSW_ES)) asm volatile("fnclex"); @@ -257,30 +283,19 @@ static inline void fpu_save_init(struct fpu *fpu) /* * we can do a simple return here or be paranoid :) */ - goto clear_state; } + alternative_input( + GENERIC_NOP8 GENERIC_NOP2, + "emms\n\t" /* clear stack tags */ + "fildl %[addr]", /* set F?P to defined value */ + X86_FEATURE_FXSAVE_LEAK, + [addr] "m" (safe_address)); +} - /* Use more nops than strictly needed in case the compiler - varies code */ - alternative_input( - "fnsave %[fx] ;fwait;" GENERIC_NOP8 GENERIC_NOP4, - "fxsave %[fx]\n" - "bt $7,%[fsw] ; jnc 1f ; fnclex\n1:", - X86_FEATURE_FXSR, - [fx] "m" (fpu->state->fxsave), - [fsw] "m" (fpu->state->fxsave.swd) : "memory"); -clear_state: - /* 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. safe_address is a random variable that should be in L1 */ - alternative_input( - GENERIC_NOP8 GENERIC_NOP2, - "emms\n\t" /* clear stack tags */ - "fildl %[addr]", /* set F?P to defined value */ - X86_FEATURE_FXSAVE_LEAK, - [addr] "m" (safe_address)); -end: - ; +static inline void fpu_save_init(struct fpu *fpu) +{ + fpu_save(fpu); + fpu_clear(fpu); } static inline void __save_init_fpu(struct task_struct *tsk) -- 1.7.0.1 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html