2 * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL
6 #include <linux/ptrace.h>
7 #include <asm/unistd.h>
8 #include <asm/uaccess.h>
9 #include <asm/ucontext.h>
10 #include "frame_kern.h"
13 void copy_sc(struct uml_pt_regs
*regs
, void *from
)
15 struct sigcontext
*sc
= from
;
17 REGS_GS(regs
->gp
) = sc
->gs
;
18 REGS_FS(regs
->gp
) = sc
->fs
;
19 REGS_ES(regs
->gp
) = sc
->es
;
20 REGS_DS(regs
->gp
) = sc
->ds
;
21 REGS_EDI(regs
->gp
) = sc
->di
;
22 REGS_ESI(regs
->gp
) = sc
->si
;
23 REGS_EBP(regs
->gp
) = sc
->bp
;
24 REGS_SP(regs
->gp
) = sc
->sp
;
25 REGS_EBX(regs
->gp
) = sc
->bx
;
26 REGS_EDX(regs
->gp
) = sc
->dx
;
27 REGS_ECX(regs
->gp
) = sc
->cx
;
28 REGS_EAX(regs
->gp
) = sc
->ax
;
29 REGS_IP(regs
->gp
) = sc
->ip
;
30 REGS_CS(regs
->gp
) = sc
->cs
;
31 REGS_EFLAGS(regs
->gp
) = sc
->flags
;
32 REGS_SS(regs
->gp
) = sc
->ss
;
36 * FPU tag word conversions.
39 static inline unsigned short twd_i387_to_fxsr(unsigned short twd
)
41 unsigned int tmp
; /* to avoid 16 bit prefixes in the code */
43 /* Transform each pair of bits into 01 (valid) or 00 (empty) */
45 tmp
= (tmp
| (tmp
>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */
46 /* and move the valid bits to the lower byte. */
47 tmp
= (tmp
| (tmp
>> 1)) & 0x3333; /* 00VV00VV00VV00VV */
48 tmp
= (tmp
| (tmp
>> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */
49 tmp
= (tmp
| (tmp
>> 4)) & 0x00ff; /* 00000000VVVVVVVV */
53 static inline unsigned long twd_fxsr_to_i387(struct user_fxsr_struct
*fxsave
)
55 struct _fpxreg
*st
= NULL
;
56 unsigned long twd
= (unsigned long) fxsave
->twd
;
58 unsigned long ret
= 0xffff0000;
61 #define FPREG_ADDR(f, n) ((char *)&(f)->st_space + (n) * 16)
63 for (i
= 0; i
< 8; i
++) {
65 st
= (struct _fpxreg
*) FPREG_ADDR(fxsave
, i
);
67 switch (st
->exponent
& 0x7fff) {
69 tag
= 2; /* Special */
72 if ( !st
->significand
[0] &&
73 !st
->significand
[1] &&
74 !st
->significand
[2] &&
75 !st
->significand
[3] ) {
78 tag
= 2; /* Special */
82 if (st
->significand
[3] & 0x8000) {
85 tag
= 2; /* Special */
92 ret
|= (tag
<< (2 * i
));
98 static int convert_fxsr_to_user(struct _fpstate __user
*buf
,
99 struct user_fxsr_struct
*fxsave
)
101 unsigned long env
[7];
102 struct _fpreg __user
*to
;
103 struct _fpxreg
*from
;
106 env
[0] = (unsigned long)fxsave
->cwd
| 0xffff0000ul
;
107 env
[1] = (unsigned long)fxsave
->swd
| 0xffff0000ul
;
108 env
[2] = twd_fxsr_to_i387(fxsave
);
109 env
[3] = fxsave
->fip
;
110 env
[4] = fxsave
->fcs
| ((unsigned long)fxsave
->fop
<< 16);
111 env
[5] = fxsave
->foo
;
112 env
[6] = fxsave
->fos
;
114 if (__copy_to_user(buf
, env
, 7 * sizeof(unsigned long)))
118 from
= (struct _fpxreg
*) &fxsave
->st_space
[0];
119 for (i
= 0; i
< 8; i
++, to
++, from
++) {
120 unsigned long __user
*t
= (unsigned long __user
*)to
;
121 unsigned long *f
= (unsigned long *)from
;
123 if (__put_user(*f
, t
) ||
124 __put_user(*(f
+ 1), t
+ 1) ||
125 __put_user(from
->exponent
, &to
->exponent
))
131 static int convert_fxsr_from_user(struct user_fxsr_struct
*fxsave
,
132 struct _fpstate __user
*buf
)
134 unsigned long env
[7];
136 struct _fpreg __user
*from
;
139 if (copy_from_user( env
, buf
, 7 * sizeof(long)))
142 fxsave
->cwd
= (unsigned short)(env
[0] & 0xffff);
143 fxsave
->swd
= (unsigned short)(env
[1] & 0xffff);
144 fxsave
->twd
= twd_i387_to_fxsr((unsigned short)(env
[2] & 0xffff));
145 fxsave
->fip
= env
[3];
146 fxsave
->fop
= (unsigned short)((env
[4] & 0xffff0000ul
) >> 16);
147 fxsave
->fcs
= (env
[4] & 0xffff);
148 fxsave
->foo
= env
[5];
149 fxsave
->fos
= env
[6];
151 to
= (struct _fpxreg
*) &fxsave
->st_space
[0];
153 for (i
= 0; i
< 8; i
++, to
++, from
++) {
154 unsigned long *t
= (unsigned long *)to
;
155 unsigned long __user
*f
= (unsigned long __user
*)from
;
157 if (__get_user(*t
, f
) ||
158 __get_user(*(t
+ 1), f
+ 1) ||
159 __get_user(to
->exponent
, &from
->exponent
))
165 extern int have_fpx_regs
;
167 static int copy_sc_from_user(struct pt_regs
*regs
,
168 struct sigcontext __user
*from
)
170 struct sigcontext sc
;
173 err
= copy_from_user(&sc
, from
, sizeof(sc
));
177 pid
= userspace_pid
[current_thread_info()->cpu
];
178 copy_sc(®s
->regs
, &sc
);
180 struct user_fxsr_struct fpx
;
182 err
= copy_from_user(&fpx
,
183 &((struct _fpstate __user
*)sc
.fpstate
)->_fxsr_env
[0],
184 sizeof(struct user_fxsr_struct
));
188 err
= convert_fxsr_from_user(&fpx
, sc
.fpstate
);
192 err
= restore_fpx_registers(pid
, (unsigned long *) &fpx
);
194 printk(KERN_ERR
"copy_sc_from_user - "
195 "restore_fpx_registers failed, errno = %d\n",
201 struct user_i387_struct fp
;
203 err
= copy_from_user(&fp
, sc
.fpstate
,
204 sizeof(struct user_i387_struct
));
208 err
= restore_fp_registers(pid
, (unsigned long *) &fp
);
210 printk(KERN_ERR
"copy_sc_from_user - "
211 "restore_fp_registers failed, errno = %d\n",
220 static int copy_sc_to_user(struct sigcontext __user
*to
,
221 struct _fpstate __user
*to_fp
, struct pt_regs
*regs
,
224 struct sigcontext sc
;
225 struct faultinfo
* fi
= ¤t
->thread
.arch
.faultinfo
;
228 sc
.gs
= REGS_GS(regs
->regs
.gp
);
229 sc
.fs
= REGS_FS(regs
->regs
.gp
);
230 sc
.es
= REGS_ES(regs
->regs
.gp
);
231 sc
.ds
= REGS_DS(regs
->regs
.gp
);
232 sc
.di
= REGS_EDI(regs
->regs
.gp
);
233 sc
.si
= REGS_ESI(regs
->regs
.gp
);
234 sc
.bp
= REGS_EBP(regs
->regs
.gp
);
236 sc
.bx
= REGS_EBX(regs
->regs
.gp
);
237 sc
.dx
= REGS_EDX(regs
->regs
.gp
);
238 sc
.cx
= REGS_ECX(regs
->regs
.gp
);
239 sc
.ax
= REGS_EAX(regs
->regs
.gp
);
240 sc
.ip
= REGS_IP(regs
->regs
.gp
);
241 sc
.cs
= REGS_CS(regs
->regs
.gp
);
242 sc
.flags
= REGS_EFLAGS(regs
->regs
.gp
);
243 sc
.sp_at_signal
= regs
->regs
.gp
[UESP
];
244 sc
.ss
= regs
->regs
.gp
[SS
];
246 sc
.err
= fi
->error_code
;
247 sc
.trapno
= fi
->trap_no
;
249 to_fp
= (to_fp
? to_fp
: (struct _fpstate __user
*) (to
+ 1));
252 pid
= userspace_pid
[current_thread_info()->cpu
];
254 struct user_fxsr_struct fpx
;
256 err
= save_fpx_registers(pid
, (unsigned long *) &fpx
);
258 printk(KERN_ERR
"copy_sc_to_user - save_fpx_registers "
259 "failed, errno = %d\n", err
);
263 err
= convert_fxsr_to_user(to_fp
, &fpx
);
267 err
|= __put_user(fpx
.swd
, &to_fp
->status
);
268 err
|= __put_user(X86_FXSR_MAGIC
, &to_fp
->magic
);
272 if (copy_to_user(&to_fp
->_fxsr_env
[0], &fpx
,
273 sizeof(struct user_fxsr_struct
)))
277 struct user_i387_struct fp
;
279 err
= save_fp_registers(pid
, (unsigned long *) &fp
);
280 if (copy_to_user(to_fp
, &fp
, sizeof(struct user_i387_struct
)))
284 return copy_to_user(to
, &sc
, sizeof(sc
));
287 static int copy_ucontext_to_user(struct ucontext __user
*uc
,
288 struct _fpstate __user
*fp
, sigset_t
*set
,
293 err
|= put_user(current
->sas_ss_sp
, &uc
->uc_stack
.ss_sp
);
294 err
|= put_user(sas_ss_flags(sp
), &uc
->uc_stack
.ss_flags
);
295 err
|= put_user(current
->sas_ss_size
, &uc
->uc_stack
.ss_size
);
296 err
|= copy_sc_to_user(&uc
->uc_mcontext
, fp
, ¤t
->thread
.regs
, sp
);
297 err
|= copy_to_user(&uc
->uc_sigmask
, set
, sizeof(*set
));
303 char __user
*pretcode
;
305 struct sigcontext sc
;
306 struct _fpstate fpstate
;
307 unsigned long extramask
[_NSIG_WORDS
-1];
313 char __user
*pretcode
;
315 struct siginfo __user
*pinfo
;
319 struct _fpstate fpstate
;
323 int setup_signal_stack_sc(unsigned long stack_top
, int sig
,
324 struct k_sigaction
*ka
, struct pt_regs
*regs
,
327 struct sigframe __user
*frame
;
328 void __user
*restorer
;
329 unsigned long save_sp
= PT_REGS_SP(regs
);
332 /* This is the same calculation as i386 - ((sp + 4) & 15) == 0 */
333 stack_top
= ((stack_top
+ 4) & -16UL) - 4;
334 frame
= (struct sigframe __user
*) stack_top
- 1;
335 if (!access_ok(VERIFY_WRITE
, frame
, sizeof(*frame
)))
338 restorer
= frame
->retcode
;
339 if (ka
->sa
.sa_flags
& SA_RESTORER
)
340 restorer
= ka
->sa
.sa_restorer
;
342 /* Update SP now because the page fault handler refuses to extend
343 * the stack if the faulting address is too far below the current
344 * SP, which frame now certainly is. If there's an error, the original
345 * value is restored on the way out.
346 * When writing the sigcontext to the stack, we have to write the
347 * original value, so that's passed to copy_sc_to_user, which does
348 * the right thing with it.
350 PT_REGS_SP(regs
) = (unsigned long) frame
;
352 err
|= __put_user(restorer
, &frame
->pretcode
);
353 err
|= __put_user(sig
, &frame
->sig
);
354 err
|= copy_sc_to_user(&frame
->sc
, NULL
, regs
, save_sp
);
355 err
|= __put_user(mask
->sig
[0], &frame
->sc
.oldmask
);
357 err
|= __copy_to_user(&frame
->extramask
, &mask
->sig
[1],
358 sizeof(frame
->extramask
));
361 * This is popl %eax ; movl $,%eax ; int $0x80
363 * WE DO NOT USE IT ANY MORE! It's only left here for historical
364 * reasons and because gdb uses it as a signature to notice
365 * signal handler stack frames.
367 err
|= __put_user(0xb858, (short __user
*)(frame
->retcode
+0));
368 err
|= __put_user(__NR_sigreturn
, (int __user
*)(frame
->retcode
+2));
369 err
|= __put_user(0x80cd, (short __user
*)(frame
->retcode
+6));
374 PT_REGS_SP(regs
) = (unsigned long) frame
;
375 PT_REGS_IP(regs
) = (unsigned long) ka
->sa
.sa_handler
;
376 PT_REGS_EAX(regs
) = (unsigned long) sig
;
377 PT_REGS_EDX(regs
) = (unsigned long) 0;
378 PT_REGS_ECX(regs
) = (unsigned long) 0;
380 if ((current
->ptrace
& PT_DTRACE
) && (current
->ptrace
& PT_PTRACED
))
381 ptrace_notify(SIGTRAP
);
385 PT_REGS_SP(regs
) = save_sp
;
389 int setup_signal_stack_si(unsigned long stack_top
, int sig
,
390 struct k_sigaction
*ka
, struct pt_regs
*regs
,
391 siginfo_t
*info
, sigset_t
*mask
)
393 struct rt_sigframe __user
*frame
;
394 void __user
*restorer
;
395 unsigned long save_sp
= PT_REGS_SP(regs
);
399 frame
= (struct rt_sigframe __user
*) stack_top
- 1;
400 if (!access_ok(VERIFY_WRITE
, frame
, sizeof(*frame
)))
403 restorer
= frame
->retcode
;
404 if (ka
->sa
.sa_flags
& SA_RESTORER
)
405 restorer
= ka
->sa
.sa_restorer
;
407 /* See comment above about why this is here */
408 PT_REGS_SP(regs
) = (unsigned long) frame
;
410 err
|= __put_user(restorer
, &frame
->pretcode
);
411 err
|= __put_user(sig
, &frame
->sig
);
412 err
|= __put_user(&frame
->info
, &frame
->pinfo
);
413 err
|= __put_user(&frame
->uc
, &frame
->puc
);
414 err
|= copy_siginfo_to_user(&frame
->info
, info
);
415 err
|= copy_ucontext_to_user(&frame
->uc
, &frame
->fpstate
, mask
,
419 * This is movl $,%eax ; int $0x80
421 * WE DO NOT USE IT ANY MORE! It's only left here for historical
422 * reasons and because gdb uses it as a signature to notice
423 * signal handler stack frames.
425 err
|= __put_user(0xb8, (char __user
*)(frame
->retcode
+0));
426 err
|= __put_user(__NR_rt_sigreturn
, (int __user
*)(frame
->retcode
+1));
427 err
|= __put_user(0x80cd, (short __user
*)(frame
->retcode
+5));
432 PT_REGS_IP(regs
) = (unsigned long) ka
->sa
.sa_handler
;
433 PT_REGS_EAX(regs
) = (unsigned long) sig
;
434 PT_REGS_EDX(regs
) = (unsigned long) &frame
->info
;
435 PT_REGS_ECX(regs
) = (unsigned long) &frame
->uc
;
437 if ((current
->ptrace
& PT_DTRACE
) && (current
->ptrace
& PT_PTRACED
))
438 ptrace_notify(SIGTRAP
);
442 PT_REGS_SP(regs
) = save_sp
;
446 long sys_sigreturn(struct pt_regs regs
)
448 unsigned long sp
= PT_REGS_SP(¤t
->thread
.regs
);
449 struct sigframe __user
*frame
= (struct sigframe __user
*)(sp
- 8);
451 struct sigcontext __user
*sc
= &frame
->sc
;
452 unsigned long __user
*oldmask
= &sc
->oldmask
;
453 unsigned long __user
*extramask
= frame
->extramask
;
454 int sig_size
= (_NSIG_WORDS
- 1) * sizeof(unsigned long);
456 if (copy_from_user(&set
.sig
[0], oldmask
, sizeof(set
.sig
[0])) ||
457 copy_from_user(&set
.sig
[1], extramask
, sig_size
))
460 sigdelsetmask(&set
, ~_BLOCKABLE
);
462 spin_lock_irq(¤t
->sighand
->siglock
);
463 current
->blocked
= set
;
465 spin_unlock_irq(¤t
->sighand
->siglock
);
467 if (copy_sc_from_user(¤t
->thread
.regs
, sc
))
470 /* Avoid ERESTART handling */
471 PT_REGS_SYSCALL_NR(¤t
->thread
.regs
) = -1;
472 return PT_REGS_SYSCALL_RET(¤t
->thread
.regs
);
475 force_sig(SIGSEGV
, current
);
479 long sys_rt_sigreturn(struct pt_regs regs
)
481 unsigned long sp
= PT_REGS_SP(¤t
->thread
.regs
);
482 struct rt_sigframe __user
*frame
=
483 (struct rt_sigframe __user
*) (sp
- 4);
485 struct ucontext __user
*uc
= &frame
->uc
;
486 int sig_size
= _NSIG_WORDS
* sizeof(unsigned long);
488 if (copy_from_user(&set
, &uc
->uc_sigmask
, sig_size
))
491 sigdelsetmask(&set
, ~_BLOCKABLE
);
493 spin_lock_irq(¤t
->sighand
->siglock
);
494 current
->blocked
= set
;
496 spin_unlock_irq(¤t
->sighand
->siglock
);
498 if (copy_sc_from_user(¤t
->thread
.regs
, &uc
->uc_mcontext
))
501 /* Avoid ERESTART handling */
502 PT_REGS_SYSCALL_NR(¤t
->thread
.regs
) = -1;
503 return PT_REGS_SYSCALL_RET(¤t
->thread
.regs
);
506 force_sig(SIGSEGV
, current
);