Skip to content

Commit

Permalink
x86-64: Clean up 'save/restore_i387()' usage
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Linus Torvalds committed Jul 24, 2008
1 parent b5684b8 commit b30f3ae
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 54 deletions.
53 changes: 53 additions & 0 deletions arch/x86/kernel/signal_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
54 changes: 0 additions & 54 deletions include/asm-x86/i387.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit b30f3ae

Please sign in to comment.