extern unsigned int mxcsr_feature_mask;
extern void mxcsr_feature_mask_init(void);
extern void init_fpu(struct task_struct *child);
-extern int save_i387(struct _fpstate *buf);
-
-static inline int need_signal_i387(struct task_struct *me)
-{
- if (!me->used_math)
- return 0;
- me->used_math = 0;
- if (me->thread_info->status & TS_USEDFPU)
- return 0;
- return 1;
-}
+extern int save_i387(struct _fpstate __user *buf);
/*
* FPU lazy state save handling...
*/
-#define kernel_fpu_end() stts()
-
#define unlazy_fpu(tsk) do { \
if ((tsk)->thread_info->status & TS_USEDFPU) \
save_init_fpu(tsk); \
} while (0)
+/* Ignore delayed exceptions from user space */
+static inline void tolerant_fwait(void)
+{
+ asm volatile("1: fwait\n"
+ "2:\n"
+ " .section __ex_table,\"a\"\n"
+ " .align 8\n"
+ " .quad 1b,2b\n"
+ " .previous\n");
+}
+
#define clear_fpu(tsk) do { \
if ((tsk)->thread_info->status & TS_USEDFPU) { \
- asm volatile("fwait"); \
+ tolerant_fwait(); \
(tsk)->thread_info->status &= ~TS_USEDFPU; \
stts(); \
} \
/*
* ptrace request handers...
*/
-extern int get_fpregs(struct user_i387_struct *buf,
+extern int get_fpregs(struct user_i387_struct __user *buf,
struct task_struct *tsk);
extern int set_fpregs(struct task_struct *tsk,
- struct user_i387_struct *buf);
+ struct user_i387_struct __user *buf);
/*
* i387 state interaction
return err;
}
-static inline int save_i387_checking(struct i387_fxsave_struct *fx)
+static inline int save_i387_checking(struct i387_fxsave_struct __user *fx)
{
int err;
asm volatile("1: rex64 ; fxsave (%[fx])\n\t"
static inline void kernel_fpu_begin(void)
{
struct thread_info *me = current_thread_info();
+ preempt_disable();
if (me->status & TS_USEDFPU) {
asm volatile("rex64 ; fxsave %0 ; fnclex"
: "=m" (me->task->thread.i387.fxsave));
clts();
}
+static inline void kernel_fpu_end(void)
+{
+ stts();
+ preempt_enable();
+}
+
static inline void save_init_fpu( struct task_struct *tsk )
{
- asm volatile( "fxsave %0 ; fnclex"
+ asm volatile( "rex64 ; fxsave %0 ; fnclex"
: "=m" (tsk->thread.i387.fxsave));
tsk->thread_info->status &= ~TS_USEDFPU;
stts();
/*
* This restores directly out of user space. Exceptions are handled.
*/
-static inline int restore_i387(struct _fpstate *buf)
+static inline int restore_i387(struct _fpstate __user *buf)
{
- return restore_fpu_checking((struct i387_fxsave_struct *)buf);
+ return restore_fpu_checking((__force struct i387_fxsave_struct *)buf);
}
#endif /* __ASM_X86_64_I387_H */