8 #include <linux/personality.h>
9 #include <linux/ptrace.h>
10 #include <linux/kernel.h>
11 #include <asm/unistd.h>
12 #include <asm/uaccess.h>
13 #include <asm/ucontext.h>
23 static inline unsigned short twd_i387_to_fxsr(
unsigned short twd)
29 tmp = (tmp | (tmp>>1)) & 0x5555;
31 tmp = (tmp | (tmp >> 1)) & 0x3333;
32 tmp = (tmp | (tmp >> 2)) & 0x0f0f;
33 tmp = (tmp | (tmp >> 4)) & 0x00ff;
37 static inline unsigned long twd_fxsr_to_i387(
struct user_fxsr_struct *fxsave)
40 unsigned long twd = (
unsigned long) fxsave->
twd;
42 unsigned long ret = 0xffff0000;
45 #define FPREG_ADDR(
f,
n) ((
char *)&(
f)->st_space + (
n) * 16)
47 for (
i = 0;
i < 8;
i++) {
49 st = (
struct _fpxreg *) FPREG_ADDR(fxsave,
i);
82 static int convert_fxsr_to_user(
struct _fpstate __user *
buf,
90 env[0] = (
unsigned long)fxsave->
cwd | 0xffff0000ul;
91 env[1] = (
unsigned long)fxsave->
swd | 0xffff0000ul;
92 env[2] = twd_fxsr_to_i387(fxsave);
94 env[4] = fxsave->
fcs | ((
unsigned long)fxsave->
fop << 16);
103 for (i = 0; i < 8; i++, to++, from++) {
105 unsigned long *
f = (
unsigned long *)from;
118 unsigned long env[7];
126 fxsave->
cwd = (
unsigned short)(env[0] & 0xffff);
127 fxsave->
swd = (
unsigned short)(env[1] & 0xffff);
128 fxsave->
twd = twd_i387_to_fxsr((
unsigned short)(env[2] & 0xffff));
129 fxsave->
fip = env[3];
130 fxsave->
fop = (
unsigned short)((env[4] & 0xffff0000ul) >> 16);
131 fxsave->
fcs = (env[4] & 0xffff);
132 fxsave->
foo = env[5];
133 fxsave->
fos = env[6];
137 for (i = 0; i < 8; i++, to++, from++) {
138 unsigned long *t = (
unsigned long *)to;
149 extern int have_fpx_regs;
166 #define GETREG(regno, regname) regs->regs.gp[HOST_##regno] = sc.regname
209 &((
struct _fpstate __user *)
sc.fpstate)->_fxsr_env[0],
214 err = convert_fxsr_from_user(&fpx,
sc.fpstate);
221 "restore_fpx_registers failed, errno = %d\n",
238 "restore_fp_registers failed, errno = %d\n",
246 static int copy_sc_to_user(
struct sigcontext __user *to,
255 #define PUTREG(regno, regname) sc.regname = regs->regs.gp[HOST_##regno]
309 "failed, errno = %d\n", err);
313 err = convert_fxsr_to_user(to_fp, &fpx);
339 static int copy_ucontext_to_user(
struct ucontext __user *
uc,
346 err |=
put_user(sas_ss_flags(sp), &uc->uc_stack.ss_flags);
348 err |= copy_sc_to_user(&uc->uc_mcontext, fp, &
current->thread.regs, 0);
349 err |=
copy_to_user(&uc->uc_sigmask,
set,
sizeof(*
set));
384 stack_top = ((stack_top + 4) & -16
UL) - 4;
391 restorer = ka->
sa.sa_restorer;
395 err |= copy_sc_to_user(&frame->
sc, &frame->fpstate, regs, mask->
sig[0]);
437 restorer = ka->
sa.sa_restorer;
444 err |= copy_ucontext_to_user(&frame->
uc, &frame->
fpstate, mask,
477 int sig_size = (
_NSIG_WORDS - 1) *
sizeof(
unsigned long);
485 if (copy_sc_from_user(&
current->thread.regs, sc))
518 frame = (
struct rt_sigframe __user *) ((
unsigned long) frame - 128 - 8);
534 &frame->
uc.uc_stack.ss_flags);
536 err |= copy_sc_to_user(&frame->
uc.uc_mcontext, &frame->
fpstate, regs,
539 if (
sizeof(*
set) == 16) {
611 long ptregs_sigreturn(
void)
615 long ptregs_rt_sigreturn(
void)