11 #include <linux/sched.h>
14 #include <linux/kernel.h>
15 #include <linux/errno.h>
16 #include <linux/wait.h>
18 #include <linux/stddef.h>
19 #include <linux/personality.h>
21 #include <linux/binfmts.h>
22 #include <asm/ucontext.h>
23 #include <asm/uaccess.h>
26 #include <asm/ptrace.h>
32 #include <asm/sigframe.h>
37 #define FIX_EFLAGS __FIX_EFLAGS
42 bool ia32 = test_thread_flag(
TIF_IA32);
60 put_user_ex(ptr_to_compat(from->si_ptr), &to->si_ptr);
67 &to->_sifields._pad[0]);
126 to->si_ptr = compat_ptr(ptr32);
135 siginitset(&blocked, mask);
140 stack_ia32_t __user *uoss_ptr,
162 uss.
ss_sp = compat_ptr(ptr);
169 if (ret >= 0 && uoss_ptr) {
188 #define loadsegment_gs(v) load_gs_index(v)
189 #define loadsegment_fs(v) loadsegment(fs, v)
190 #define loadsegment_ds(v) loadsegment(ds, v)
191 #define loadsegment_es(v) loadsegment(es, v)
193 #define get_user_seg(seg) ({ unsigned int v; savesegment(seg, v); v; })
194 #define set_user_seg(seg, v) loadsegment_##seg(v)
197 get_user_ex(regs->x, &sc->x); \
200 #define GET_SEG(seg) ({ \
201 unsigned short tmp; \
202 get_user_ex(tmp, &sc->seg); \
206 #define COPY_SEG_CPL3(seg) do { \
207 regs->seg = GET_SEG(seg) | 3; \
210 #define RELOAD_SEG(seg) { \
211 unsigned int pre = GET_SEG(seg); \
212 unsigned int cur = get_user_seg(seg); \
215 set_user_seg(seg, pre); \
218 static int ia32_restore_sigcontext(
struct pt_regs *
regs,
222 unsigned int tmpflags,
err = 0;
254 buf = compat_ptr(tmp);
259 err |= restore_xstate_sig(buf, 1);
266 struct sigframe_ia32 __user *
frame = (
struct sigframe_ia32 __user *)(regs->
sp-8);
273 || (_COMPAT_NSIG_WORDS > 1
276 sizeof(frame->extramask))))
281 if (ia32_restore_sigcontext(regs, &frame->sc, &ax))
292 struct rt_sigframe_ia32 __user *
frame;
297 frame = (
struct rt_sigframe_ia32 __user *)(regs->
sp - 4);
306 if (ia32_restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
325 void __user *fpstate,
367 void __user **fpstate)
376 if (sas_ss_flags(sp) == 0)
384 sp = (
unsigned long) ka->
sa.sa_restorer;
387 unsigned long fx_aligned, math_size;
389 sp = alloc_mathframe(sp, 1, &fx_aligned, &math_size);
393 return (
void __user *) -1
L;
399 sp = ((sp + 4) & -16ul) - 4;
400 return (
void __user *)
sp;
404 compat_sigset_t *
set,
struct pt_regs *regs)
406 struct sigframe_ia32 __user *
frame;
407 void __user *restorer;
409 void __user *fpstate =
NULL;
412 static const struct {
422 frame =
get_sigframe(ka, regs,
sizeof(*frame), &fpstate);
430 if (ia32_setup_sigcontext(&frame->sc, fpstate, regs,
set->sig[0]))
433 if (_COMPAT_NSIG_WORDS > 1) {
435 sizeof(frame->extramask)))
440 restorer = ka->
sa.sa_restorer;
444 restorer = VDSO32_SYMBOL(
current->mm->context.vdso,
447 restorer = &frame->retcode;
451 put_user_ex(ptr_to_compat(restorer), &frame->pretcode);
464 regs->
sp = (
unsigned long) frame;
465 regs->ip = (
unsigned long) ka->
sa.sa_handler;
482 compat_sigset_t *
set,
struct pt_regs *regs)
484 struct rt_sigframe_ia32 __user *
frame;
485 void __user *restorer;
487 void __user *fpstate =
NULL;
490 static const struct {
497 __NR_ia32_rt_sigreturn,
502 frame =
get_sigframe(ka, regs,
sizeof(*frame), &fpstate);
509 put_user_ex(ptr_to_compat(&frame->info), &frame->pinfo);
510 put_user_ex(ptr_to_compat(&frame->uc), &frame->puc);
520 &frame->uc.uc_stack.ss_flags);
524 restorer = ka->
sa.sa_restorer;
526 restorer = VDSO32_SYMBOL(
current->mm->context.vdso,
528 put_user_ex(ptr_to_compat(restorer), &frame->pretcode);
538 err |= ia32_setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
546 regs->
sp = (
unsigned long) frame;
547 regs->ip = (
unsigned long) ka->
sa.sa_handler;
551 regs->dx = (
unsigned long) &frame->info;
552 regs->cx = (
unsigned long) &frame->uc;