diff options
Diffstat (limited to 'include/asm-x86/i387.h')
-rw-r--r-- | include/asm-x86/i387.h | 35 |
1 files changed, 17 insertions, 18 deletions
diff --git a/include/asm-x86/i387.h b/include/asm-x86/i387.h index 54522b814f1c..382a5fa9d492 100644 --- a/include/asm-x86/i387.h +++ b/include/asm-x86/i387.h | |||
@@ -23,6 +23,7 @@ extern void fpu_init(void); | |||
23 | extern void mxcsr_feature_mask_init(void); | 23 | extern void mxcsr_feature_mask_init(void); |
24 | extern void init_fpu(struct task_struct *child); | 24 | extern void init_fpu(struct task_struct *child); |
25 | extern asmlinkage void math_state_restore(void); | 25 | extern asmlinkage void math_state_restore(void); |
26 | extern void init_thread_xstate(void); | ||
26 | 27 | ||
27 | extern user_regset_active_fn fpregs_active, xfpregs_active; | 28 | extern user_regset_active_fn fpregs_active, xfpregs_active; |
28 | extern user_regset_get_fn fpregs_get, xfpregs_get, fpregs_soft_get; | 29 | extern user_regset_get_fn fpregs_get, xfpregs_get, fpregs_soft_get; |
@@ -117,24 +118,22 @@ static inline void __save_init_fpu(struct task_struct *tsk) | |||
117 | /* Using "fxsaveq %0" would be the ideal choice, but is only supported | 118 | /* Using "fxsaveq %0" would be the ideal choice, but is only supported |
118 | starting with gas 2.16. */ | 119 | starting with gas 2.16. */ |
119 | __asm__ __volatile__("fxsaveq %0" | 120 | __asm__ __volatile__("fxsaveq %0" |
120 | : "=m" (tsk->thread.i387.fxsave)); | 121 | : "=m" (tsk->thread.xstate->fxsave)); |
121 | #elif 0 | 122 | #elif 0 |
122 | /* Using, as a workaround, the properly prefixed form below isn't | 123 | /* Using, as a workaround, the properly prefixed form below isn't |
123 | accepted by any binutils version so far released, complaining that | 124 | accepted by any binutils version so far released, complaining that |
124 | the same type of prefix is used twice if an extended register is | 125 | the same type of prefix is used twice if an extended register is |
125 | needed for addressing (fix submitted to mainline 2005-11-21). */ | 126 | needed for addressing (fix submitted to mainline 2005-11-21). */ |
126 | __asm__ __volatile__("rex64/fxsave %0" | 127 | __asm__ __volatile__("rex64/fxsave %0" |
127 | : "=m" (tsk->thread.i387.fxsave)); | 128 | : "=m" (tsk->thread.xstate->fxsave)); |
128 | #else | 129 | #else |
129 | /* This, however, we can work around by forcing the compiler to select | 130 | /* This, however, we can work around by forcing the compiler to select |
130 | an addressing mode that doesn't require extended registers. */ | 131 | an addressing mode that doesn't require extended registers. */ |
131 | __asm__ __volatile__("rex64/fxsave %P2(%1)" | 132 | __asm__ __volatile__("rex64/fxsave (%1)" |
132 | : "=m" (tsk->thread.i387.fxsave) | 133 | : "=m" (tsk->thread.xstate->fxsave) |
133 | : "cdaSDb" (tsk), | 134 | : "cdaSDb" (&tsk->thread.xstate->fxsave)); |
134 | "i" (offsetof(__typeof__(*tsk), | ||
135 | thread.i387.fxsave))); | ||
136 | #endif | 135 | #endif |
137 | clear_fpu_state(&tsk->thread.i387.fxsave); | 136 | clear_fpu_state(&tsk->thread.xstate->fxsave); |
138 | task_thread_info(tsk)->status &= ~TS_USEDFPU; | 137 | task_thread_info(tsk)->status &= ~TS_USEDFPU; |
139 | } | 138 | } |
140 | 139 | ||
@@ -148,7 +147,7 @@ static inline int save_i387(struct _fpstate __user *buf) | |||
148 | int err = 0; | 147 | int err = 0; |
149 | 148 | ||
150 | BUILD_BUG_ON(sizeof(struct user_i387_struct) != | 149 | BUILD_BUG_ON(sizeof(struct user_i387_struct) != |
151 | sizeof(tsk->thread.i387.fxsave)); | 150 | sizeof(tsk->thread.xstate->fxsave)); |
152 | 151 | ||
153 | if ((unsigned long)buf % 16) | 152 | if ((unsigned long)buf % 16) |
154 | printk("save_i387: bad fpstate %p\n", buf); | 153 | printk("save_i387: bad fpstate %p\n", buf); |
@@ -164,7 +163,7 @@ static inline int save_i387(struct _fpstate __user *buf) | |||
164 | task_thread_info(tsk)->status &= ~TS_USEDFPU; | 163 | task_thread_info(tsk)->status &= ~TS_USEDFPU; |
165 | stts(); | 164 | stts(); |
166 | } else { | 165 | } else { |
167 | if (__copy_to_user(buf, &tsk->thread.i387.fxsave, | 166 | if (__copy_to_user(buf, &tsk->thread.xstate->fxsave, |
168 | sizeof(struct i387_fxsave_struct))) | 167 | sizeof(struct i387_fxsave_struct))) |
169 | return -1; | 168 | return -1; |
170 | } | 169 | } |
@@ -201,7 +200,7 @@ static inline void restore_fpu(struct task_struct *tsk) | |||
201 | "nop ; frstor %1", | 200 | "nop ; frstor %1", |
202 | "fxrstor %1", | 201 | "fxrstor %1", |
203 | X86_FEATURE_FXSR, | 202 | X86_FEATURE_FXSR, |
204 | "m" ((tsk)->thread.i387.fxsave)); | 203 | "m" (tsk->thread.xstate->fxsave)); |
205 | } | 204 | } |
206 | 205 | ||
207 | /* We need a safe address that is cheap to find and that is already | 206 | /* We need a safe address that is cheap to find and that is already |
@@ -225,8 +224,8 @@ static inline void __save_init_fpu(struct task_struct *tsk) | |||
225 | "fxsave %[fx]\n" | 224 | "fxsave %[fx]\n" |
226 | "bt $7,%[fsw] ; jnc 1f ; fnclex\n1:", | 225 | "bt $7,%[fsw] ; jnc 1f ; fnclex\n1:", |
227 | X86_FEATURE_FXSR, | 226 | X86_FEATURE_FXSR, |
228 | [fx] "m" (tsk->thread.i387.fxsave), | 227 | [fx] "m" (tsk->thread.xstate->fxsave), |
229 | [fsw] "m" (tsk->thread.i387.fxsave.swd) : "memory"); | 228 | [fsw] "m" (tsk->thread.xstate->fxsave.swd) : "memory"); |
230 | /* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception | 229 | /* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception |
231 | is pending. Clear the x87 state here by setting it to fixed | 230 | is pending. Clear the x87 state here by setting it to fixed |
232 | values. safe_address is a random variable that should be in L1 */ | 231 | values. safe_address is a random variable that should be in L1 */ |
@@ -327,25 +326,25 @@ static inline void clear_fpu(struct task_struct *tsk) | |||
327 | static inline unsigned short get_fpu_cwd(struct task_struct *tsk) | 326 | static inline unsigned short get_fpu_cwd(struct task_struct *tsk) |
328 | { | 327 | { |
329 | if (cpu_has_fxsr) { | 328 | if (cpu_has_fxsr) { |
330 | return tsk->thread.i387.fxsave.cwd; | 329 | return tsk->thread.xstate->fxsave.cwd; |
331 | } else { | 330 | } else { |
332 | return (unsigned short)tsk->thread.i387.fsave.cwd; | 331 | return (unsigned short) tsk->thread.xstate->fsave.cwd; |
333 | } | 332 | } |
334 | } | 333 | } |
335 | 334 | ||
336 | static inline unsigned short get_fpu_swd(struct task_struct *tsk) | 335 | static inline unsigned short get_fpu_swd(struct task_struct *tsk) |
337 | { | 336 | { |
338 | if (cpu_has_fxsr) { | 337 | if (cpu_has_fxsr) { |
339 | return tsk->thread.i387.fxsave.swd; | 338 | return tsk->thread.xstate->fxsave.swd; |
340 | } else { | 339 | } else { |
341 | return (unsigned short)tsk->thread.i387.fsave.swd; | 340 | return (unsigned short) tsk->thread.xstate->fsave.swd; |
342 | } | 341 | } |
343 | } | 342 | } |
344 | 343 | ||
345 | static inline unsigned short get_fpu_mxcsr(struct task_struct *tsk) | 344 | static inline unsigned short get_fpu_mxcsr(struct task_struct *tsk) |
346 | { | 345 | { |
347 | if (cpu_has_xmm) { | 346 | if (cpu_has_xmm) { |
348 | return tsk->thread.i387.fxsave.mxcsr; | 347 | return tsk->thread.xstate->fxsave.mxcsr; |
349 | } else { | 348 | } else { |
350 | return MXCSR_DEFAULT; | 349 | return MXCSR_DEFAULT; |
351 | } | 350 | } |