forked from Minki/linux
x86-64: Clean up 'save/restore_i387()' usage
Suresh Siddha wants to fix a possible FPU leakage in error conditions, but the fact that save/restore_i387() are inlines in a header file makes that harder to do than necessary. So start off with an obvious cleanup. This just moves the x86-64 version of save/restore_i387() out of the header file, and moves it to the only file that it is actually used in: arch/x86/kernel/signal_64.c. So exposing it in a header file was wrong to begin with. [ Side note: I'd like to fix up some of the games we play with the 32-bit version of these functions too, but that's a separate matter. The 32-bit versions are shared - under different names at that! - by both the native x86-32 code and the x86-64 32-bit compatibility code ] Acked-by: Suresh Siddha <suresh.b.siddha@intel.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
b5684b83b1
commit
b30f3ae50c
@ -53,6 +53,59 @@ sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
|
||||
return do_sigaltstack(uss, uoss, regs->sp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Signal frame handlers.
|
||||
*/
|
||||
|
||||
static inline int save_i387(struct _fpstate __user *buf)
|
||||
{
|
||||
struct task_struct *tsk = current;
|
||||
int err = 0;
|
||||
|
||||
BUILD_BUG_ON(sizeof(struct user_i387_struct) !=
|
||||
sizeof(tsk->thread.xstate->fxsave));
|
||||
|
||||
if ((unsigned long)buf % 16)
|
||||
printk("save_i387: bad fpstate %p\n", buf);
|
||||
|
||||
if (!used_math())
|
||||
return 0;
|
||||
clear_used_math(); /* trigger finit */
|
||||
if (task_thread_info(tsk)->status & TS_USEDFPU) {
|
||||
err = save_i387_checking((struct i387_fxsave_struct __user *)
|
||||
buf);
|
||||
if (err)
|
||||
return err;
|
||||
task_thread_info(tsk)->status &= ~TS_USEDFPU;
|
||||
stts();
|
||||
} else {
|
||||
if (__copy_to_user(buf, &tsk->thread.xstate->fxsave,
|
||||
sizeof(struct i387_fxsave_struct)))
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* This restores directly out of user space. Exceptions are handled.
|
||||
*/
|
||||
static inline int restore_i387(struct _fpstate __user *buf)
|
||||
{
|
||||
struct task_struct *tsk = current;
|
||||
int err;
|
||||
|
||||
if (!used_math()) {
|
||||
err = init_fpu(tsk);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
if (!(task_thread_info(current)->status & TS_USEDFPU)) {
|
||||
clts();
|
||||
task_thread_info(current)->status |= TS_USEDFPU;
|
||||
}
|
||||
return restore_fpu_checking((__force struct i387_fxsave_struct *)buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Do a signal return; undo the signal stack.
|
||||
|
@ -137,60 +137,6 @@ static inline void __save_init_fpu(struct task_struct *tsk)
|
||||
task_thread_info(tsk)->status &= ~TS_USEDFPU;
|
||||
}
|
||||
|
||||
/*
|
||||
* Signal frame handlers.
|
||||
*/
|
||||
|
||||
static inline int save_i387(struct _fpstate __user *buf)
|
||||
{
|
||||
struct task_struct *tsk = current;
|
||||
int err = 0;
|
||||
|
||||
BUILD_BUG_ON(sizeof(struct user_i387_struct) !=
|
||||
sizeof(tsk->thread.xstate->fxsave));
|
||||
|
||||
if ((unsigned long)buf % 16)
|
||||
printk("save_i387: bad fpstate %p\n", buf);
|
||||
|
||||
if (!used_math())
|
||||
return 0;
|
||||
clear_used_math(); /* trigger finit */
|
||||
if (task_thread_info(tsk)->status & TS_USEDFPU) {
|
||||
err = save_i387_checking((struct i387_fxsave_struct __user *)
|
||||
buf);
|
||||
if (err)
|
||||
return err;
|
||||
task_thread_info(tsk)->status &= ~TS_USEDFPU;
|
||||
stts();
|
||||
} else {
|
||||
if (__copy_to_user(buf, &tsk->thread.xstate->fxsave,
|
||||
sizeof(struct i387_fxsave_struct)))
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* This restores directly out of user space. Exceptions are handled.
|
||||
*/
|
||||
static inline int restore_i387(struct _fpstate __user *buf)
|
||||
{
|
||||
struct task_struct *tsk = current;
|
||||
int err;
|
||||
|
||||
if (!used_math()) {
|
||||
err = init_fpu(tsk);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
if (!(task_thread_info(current)->status & TS_USEDFPU)) {
|
||||
clts();
|
||||
task_thread_info(current)->status |= TS_USEDFPU;
|
||||
}
|
||||
return restore_fpu_checking((__force struct i387_fxsave_struct *)buf);
|
||||
}
|
||||
|
||||
#else /* CONFIG_X86_32 */
|
||||
|
||||
extern void finit(void);
|
||||
|
Loading…
Reference in New Issue
Block a user