aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/include/asm/i387.h
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/include/asm/i387.h')
-rw-r--r--arch/x86/include/asm/i387.h48
1 files changed, 4 insertions, 44 deletions
diff --git a/arch/x86/include/asm/i387.h b/arch/x86/include/asm/i387.h
index b45abefb89f2..70626ed96cb5 100644
--- a/arch/x86/include/asm/i387.h
+++ b/arch/x86/include/asm/i387.h
@@ -105,36 +105,6 @@ static inline int fxrstor_checking(struct i387_fxsave_struct *fx)
105 return err; 105 return err;
106} 106}
107 107
108/* AMD CPUs don't save/restore FDP/FIP/FOP unless an exception
109 is pending. Clear the x87 state here by setting it to fixed
110 values. The kernel data segment can be sometimes 0 and sometimes
111 new user value. Both should be ok.
112 Use the PDA as safe address because it should be already in L1. */
113static inline void fpu_clear(struct fpu *fpu)
114{
115 struct xsave_struct *xstate = &fpu->state->xsave;
116 struct i387_fxsave_struct *fx = &fpu->state->fxsave;
117
118 /*
119 * xsave header may indicate the init state of the FP.
120 */
121 if (use_xsave() &&
122 !(xstate->xsave_hdr.xstate_bv & XSTATE_FP))
123 return;
124
125 if (unlikely(fx->swd & X87_FSW_ES))
126 asm volatile("fnclex");
127 alternative_input(ASM_NOP8 ASM_NOP2,
128 " emms\n" /* clear stack tags */
129 " fildl %%gs:0", /* load to clear state */
130 X86_FEATURE_FXSAVE_LEAK);
131}
132
133static inline void clear_fpu_state(struct task_struct *tsk)
134{
135 fpu_clear(&tsk->thread.fpu);
136}
137
138static inline int fxsave_user(struct i387_fxsave_struct __user *fx) 108static inline int fxsave_user(struct i387_fxsave_struct __user *fx)
139{ 109{
140 int err; 110 int err;
@@ -188,16 +158,6 @@ static inline void fpu_fxsave(struct fpu *fpu)
188 : [fx] "R" (&fpu->state->fxsave)); 158 : [fx] "R" (&fpu->state->fxsave));
189} 159}
190 160
191static inline void fpu_save_init(struct fpu *fpu)
192{
193 if (use_xsave())
194 fpu_xsave(fpu);
195 else
196 fpu_fxsave(fpu);
197
198 fpu_clear(fpu);
199}
200
201#else /* CONFIG_X86_32 */ 161#else /* CONFIG_X86_32 */
202 162
203/* perform fxrstor iff the processor has extended states, otherwise frstor */ 163/* perform fxrstor iff the processor has extended states, otherwise frstor */
@@ -222,6 +182,8 @@ static inline void fpu_fxsave(struct fpu *fpu)
222 : [fx] "=m" (fpu->state->fxsave)); 182 : [fx] "=m" (fpu->state->fxsave));
223} 183}
224 184
185#endif /* CONFIG_X86_64 */
186
225/* We need a safe address that is cheap to find and that is already 187/* We need a safe address that is cheap to find and that is already
226 in L1 during context switch. The best choices are unfortunately 188 in L1 during context switch. The best choices are unfortunately
227 different for UP and SMP */ 189 different for UP and SMP */
@@ -259,15 +221,13 @@ static inline void fpu_save_init(struct fpu *fpu)
259 is pending. Clear the x87 state here by setting it to fixed 221 is pending. Clear the x87 state here by setting it to fixed
260 values. safe_address is a random variable that should be in L1 */ 222 values. safe_address is a random variable that should be in L1 */
261 alternative_input( 223 alternative_input(
262 GENERIC_NOP8 GENERIC_NOP2, 224 ASM_NOP8 ASM_NOP2,
263 "emms\n\t" /* clear stack tags */ 225 "emms\n\t" /* clear stack tags */
264 "fildl %[addr]", /* set F?P to defined value */ 226 "fildl %P[addr]", /* set F?P to defined value */
265 X86_FEATURE_FXSAVE_LEAK, 227 X86_FEATURE_FXSAVE_LEAK,
266 [addr] "m" (safe_address)); 228 [addr] "m" (safe_address));
267} 229}
268 230
269#endif /* CONFIG_X86_64 */
270
271static inline void __save_init_fpu(struct task_struct *tsk) 231static inline void __save_init_fpu(struct task_struct *tsk)
272{ 232{
273 fpu_save_init(&tsk->thread.fpu); 233 fpu_save_init(&tsk->thread.fpu);