Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 112776
b: refs/heads/master
c: ab51370
h: refs/heads/master
v: v3
  • Loading branch information
Suresh Siddha authored and Ingo Molnar committed Jul 30, 2008
1 parent ff3618a commit 01e284c
Show file tree
Hide file tree
Showing 7 changed files with 135 additions and 142 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 3c1c7f101426cb2ecc79d817a8a65928965fc860
refs/heads/master: ab5137015fed9b948fe835a2d99a4cfbd50a0c40
28 changes: 7 additions & 21 deletions trunk/arch/x86/ia32/ia32_signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ static int ia32_restore_sigcontext(struct pt_regs *regs,
unsigned int *peax)
{
unsigned int tmpflags, gs, oldgs, err = 0;
struct _fpstate_ia32 __user *buf;
void __user *buf;
u32 tmp;

/* Always make any pending restarted system calls return -EINTR */
Expand Down Expand Up @@ -260,26 +260,12 @@ static int ia32_restore_sigcontext(struct pt_regs *regs,

err |= __get_user(tmp, &sc->fpstate);
buf = compat_ptr(tmp);
if (buf) {
if (!access_ok(VERIFY_READ, buf, sizeof(*buf)))
goto badframe;
err |= restore_i387_ia32(buf);
} else {
struct task_struct *me = current;

if (used_math()) {
clear_fpu(me);
clear_used_math();
}
}
err |= restore_i387_xstate_ia32(buf);

err |= __get_user(tmp, &sc->ax);
*peax = tmp;

return err;

badframe:
return 1;
}

asmlinkage long sys32_sigreturn(struct pt_regs *regs)
Expand Down Expand Up @@ -351,7 +337,7 @@ asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs)
*/

static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc,
struct _fpstate_ia32 __user *fpstate,
void __user *fpstate,
struct pt_regs *regs, unsigned int mask)
{
int tmp, err = 0;
Expand Down Expand Up @@ -382,7 +368,7 @@ static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc,
err |= __put_user((u32)regs->flags, &sc->flags);
err |= __put_user((u32)regs->sp, &sc->sp_at_signal);

tmp = save_i387_ia32(fpstate);
tmp = save_i387_xstate_ia32(fpstate);
if (tmp < 0)
err = -EFAULT;
else {
Expand All @@ -404,7 +390,7 @@ static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc,
*/
static void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
size_t frame_size,
struct _fpstate_ia32 **fpstate)
void **fpstate)
{
unsigned long sp;

Expand Down Expand Up @@ -441,7 +427,7 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka,
struct sigframe __user *frame;
void __user *restorer;
int err = 0;
struct _fpstate_ia32 __user *fpstate = NULL;
void __user *fpstate = NULL;

/* copy_to_user optimizes that into a single 8 byte store */
static const struct {
Expand Down Expand Up @@ -529,7 +515,7 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
struct rt_sigframe __user *frame;
void __user *restorer;
int err = 0;
struct _fpstate_ia32 __user *fpstate = NULL;
void __user *fpstate = NULL;

/* __copy_to_user optimizes that into a single 8 byte store */
static const struct {
Expand Down
44 changes: 31 additions & 13 deletions trunk/arch/x86/kernel/i387.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@
# include <asm/sigcontext32.h>
# include <asm/user32.h>
#else
# define save_i387_ia32 save_i387
# define restore_i387_ia32 restore_i387
# define save_i387_xstate_ia32 save_i387_xstate
# define restore_i387_xstate_ia32 restore_i387_xstate
# define _fpstate_ia32 _fpstate
# define _xstate_ia32 _xstate
# define sig_xstate_ia32_size sig_xstate_size
# define user_i387_ia32_struct user_i387_struct
# define user32_fxsr_struct user_fxsr_struct
Expand Down Expand Up @@ -424,7 +425,6 @@ static inline int save_i387_fsave(struct _fpstate_ia32 __user *buf)
struct task_struct *tsk = current;
struct i387_fsave_struct *fp = &tsk->thread.xstate->fsave;

unlazy_fpu(tsk);
fp->status = fp->swd;
if (__copy_to_user(buf, fp, sizeof(struct i387_fsave_struct)))
return -1;
Expand All @@ -438,8 +438,6 @@ static int save_i387_fxsave(struct _fpstate_ia32 __user *buf)
struct user_i387_ia32_struct env;
int err = 0;

unlazy_fpu(tsk);

convert_from_fxsr(&env, tsk);
if (__copy_to_user(buf, &env, sizeof(env)))
return -1;
Expand All @@ -455,10 +453,16 @@ static int save_i387_fxsave(struct _fpstate_ia32 __user *buf)
return 1;
}

int save_i387_ia32(struct _fpstate_ia32 __user *buf)
int save_i387_xstate_ia32(void __user *buf)
{
struct _fpstate_ia32 __user *fp = (struct _fpstate_ia32 __user *) buf;
struct task_struct *tsk = current;

if (!used_math())
return 0;

if (!access_ok(VERIFY_WRITE, buf, sig_xstate_ia32_size))
return -EACCES;
/*
* This will cause a "finit" to be triggered by the next
* attempted FPU operation by the 'current' process.
Expand All @@ -468,13 +472,15 @@ int save_i387_ia32(struct _fpstate_ia32 __user *buf)
if (!HAVE_HWFP) {
return fpregs_soft_get(current, NULL,
0, sizeof(struct user_i387_ia32_struct),
NULL, buf) ? -1 : 1;
NULL, fp) ? -1 : 1;
}

unlazy_fpu(tsk);

if (cpu_has_fxsr)
return save_i387_fxsave(buf);
return save_i387_fxsave(fp);
else
return save_i387_fsave(buf);
return save_i387_fsave(fp);
}

static inline int restore_i387_fsave(struct _fpstate_ia32 __user *buf)
Expand Down Expand Up @@ -502,14 +508,26 @@ static int restore_i387_fxsave(struct _fpstate_ia32 __user *buf)
return 0;
}

int restore_i387_ia32(struct _fpstate_ia32 __user *buf)
int restore_i387_xstate_ia32(void __user *buf)
{
int err;
struct task_struct *tsk = current;
struct _fpstate_ia32 __user *fp = (struct _fpstate_ia32 __user *) buf;

if (HAVE_HWFP)
clear_fpu(tsk);

if (!buf) {
if (used_math()) {
clear_fpu(tsk);
clear_used_math();
}

return 0;
} else
if (!access_ok(VERIFY_READ, buf, sig_xstate_ia32_size))
return -EACCES;

if (!used_math()) {
err = init_fpu(tsk);
if (err)
Expand All @@ -518,13 +536,13 @@ int restore_i387_ia32(struct _fpstate_ia32 __user *buf)

if (HAVE_HWFP) {
if (cpu_has_fxsr)
err = restore_i387_fxsave(buf);
err = restore_i387_fxsave(fp);
else
err = restore_i387_fsave(buf);
err = restore_i387_fsave(fp);
} else {
err = fpregs_soft_set(current, NULL,
0, sizeof(struct user_i387_ia32_struct),
NULL, buf) != 0;
NULL, fp) != 0;
}
set_used_math();

Expand Down
28 changes: 7 additions & 21 deletions trunk/arch/x86/kernel/signal_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,28 +159,14 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
}

{
struct _fpstate __user *buf;
void __user *buf;

err |= __get_user(buf, &sc->fpstate);
if (buf) {
if (!access_ok(VERIFY_READ, buf, sizeof(*buf)))
goto badframe;
err |= restore_i387(buf);
} else {
struct task_struct *me = current;

if (used_math()) {
clear_fpu(me);
clear_used_math();
}
}
err |= restore_i387_xstate(buf);
}

err |= __get_user(*pax, &sc->ax);
return err;

badframe:
return 1;
}

asmlinkage unsigned long sys_sigreturn(unsigned long __unused)
Expand Down Expand Up @@ -262,7 +248,7 @@ asmlinkage int sys_rt_sigreturn(unsigned long __unused)
* Set up a signal frame.
*/
static int
setup_sigcontext(struct sigcontext __user *sc, struct _fpstate __user *fpstate,
setup_sigcontext(struct sigcontext __user *sc, void __user *fpstate,
struct pt_regs *regs, unsigned long mask)
{
int tmp, err = 0;
Expand All @@ -289,7 +275,7 @@ setup_sigcontext(struct sigcontext __user *sc, struct _fpstate __user *fpstate,
err |= __put_user(regs->sp, &sc->sp_at_signal);
err |= __put_user(regs->ss, (unsigned int __user *)&sc->ss);

tmp = save_i387(fpstate);
tmp = save_i387_xstate(fpstate);
if (tmp < 0)
err = 1;
else
Expand All @@ -307,7 +293,7 @@ setup_sigcontext(struct sigcontext __user *sc, struct _fpstate __user *fpstate,
*/
static inline void __user *
get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size,
struct _fpstate **fpstate)
void **fpstate)
{
unsigned long sp;

Expand Down Expand Up @@ -356,7 +342,7 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
void __user *restorer;
int err = 0;
int usig;
struct _fpstate __user *fpstate = NULL;
void __user *fpstate = NULL;

frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);

Expand Down Expand Up @@ -434,7 +420,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
void __user *restorer;
int err = 0;
int usig;
struct _fpstate __user *fpstate = NULL;
void __user *fpstate = NULL;

frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);

Expand Down
83 changes: 3 additions & 80 deletions trunk/arch/x86/kernel/signal_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,69 +53,6 @@ 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;
}
err = restore_fpu_checking((__force struct i387_fxsave_struct *)buf);
if (unlikely(err)) {
/*
* Encountered an error while doing the restore from the
* user buffer, clear the fpu state.
*/
clear_fpu(tsk);
clear_used_math();
}
return err;
}

/*
* Do a signal return; undo the signal stack.
*/
Expand Down Expand Up @@ -160,25 +97,11 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
{
struct _fpstate __user * buf;
err |= __get_user(buf, &sc->fpstate);

if (buf) {
if (!access_ok(VERIFY_READ, buf, sizeof(*buf)))
goto badframe;
err |= restore_i387(buf);
} else {
struct task_struct *me = current;
if (used_math()) {
clear_fpu(me);
clear_used_math();
}
}
err |= restore_i387_xstate(buf);
}

err |= __get_user(*pax, &sc->ax);
return err;

badframe:
return 1;
}

asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
Expand Down Expand Up @@ -276,7 +199,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
sigset_t *set, struct pt_regs * regs)
{
struct rt_sigframe __user *frame;
struct _fpstate __user *fp = NULL;
void __user *fp = NULL;
int err = 0;
struct task_struct *me = current;

Expand All @@ -288,7 +211,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate)))
goto give_sigsegv;

if (save_i387(fp) < 0)
if (save_i387_xstate(fp) < 0)
err |= -1;
} else
frame = get_stack(ka, regs, sizeof(struct rt_sigframe)) - 8;
Expand Down
Loading

0 comments on commit 01e284c

Please sign in to comment.