x86: mach-default setup.c cleanups
[deliverable/linux.git] / arch / x86 / ia32 / ia32_signal.c
CommitLineData
1da177e4
LT
1/*
2 * linux/arch/x86_64/ia32/ia32_signal.c
3 *
4 * Copyright (C) 1991, 1992 Linus Torvalds
5 *
6 * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson
7 * 2000-06-20 Pentium III FXSR, SSE support by Gareth Hughes
8 * 2000-12-* x86-64 compatibility mode signal handling by Andi Kleen
1da177e4
LT
9 */
10
11#include <linux/sched.h>
12#include <linux/mm.h>
13#include <linux/smp.h>
1da177e4
LT
14#include <linux/kernel.h>
15#include <linux/signal.h>
16#include <linux/errno.h>
17#include <linux/wait.h>
18#include <linux/ptrace.h>
19#include <linux/unistd.h>
20#include <linux/stddef.h>
21#include <linux/personality.h>
22#include <linux/compat.h>
9fbbd4dd 23#include <linux/binfmts.h>
1da177e4
LT
24#include <asm/ucontext.h>
25#include <asm/uaccess.h>
26#include <asm/i387.h>
27#include <asm/ia32.h>
28#include <asm/ptrace.h>
29#include <asm/ia32_unistd.h>
30#include <asm/user32.h>
31#include <asm/sigcontext32.h>
1da177e4 32#include <asm/proto.h>
af65d648 33#include <asm/vdso.h>
1da177e4 34
d98f9d84
HS
35#include <asm/sigframe.h>
36
1da177e4
LT
37#define DEBUG_SIG 0
38
39#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
40
fbdb7da9
HS
41#define FIX_EFLAGS (X86_EFLAGS_AC | X86_EFLAGS_OF | \
42 X86_EFLAGS_DF | X86_EFLAGS_TF | X86_EFLAGS_SF | \
43 X86_EFLAGS_ZF | X86_EFLAGS_AF | X86_EFLAGS_PF | \
44 X86_EFLAGS_CF)
45
1da177e4
LT
46void signal_fault(struct pt_regs *regs, void __user *frame, char *where);
47
48int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
49{
50 int err;
99b9cdf7
TG
51
52 if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
1da177e4
LT
53 return -EFAULT;
54
55 /* If you change siginfo_t structure, please make sure that
56 this code is fixed accordingly.
57 It should never copy any pad contained in the structure
58 to avoid security leaks, but must copy the generic
59 3 ints plus the relevant union member. */
60 err = __put_user(from->si_signo, &to->si_signo);
61 err |= __put_user(from->si_errno, &to->si_errno);
99b9cdf7 62 err |= __put_user((short)from->si_code, &to->si_code);
1da177e4
LT
63
64 if (from->si_code < 0) {
65 err |= __put_user(from->si_pid, &to->si_pid);
99b9cdf7
TG
66 err |= __put_user(from->si_uid, &to->si_uid);
67 err |= __put_user(ptr_to_compat(from->si_ptr), &to->si_ptr);
1da177e4 68 } else {
99b9cdf7
TG
69 /*
70 * First 32bits of unions are always present:
71 * si_pid === si_band === si_tid === si_addr(LS half)
72 */
73 err |= __put_user(from->_sifields._pad[0],
74 &to->_sifields._pad[0]);
1da177e4
LT
75 switch (from->si_code >> 16) {
76 case __SI_FAULT >> 16:
77 break;
78 case __SI_CHLD >> 16:
79 err |= __put_user(from->si_utime, &to->si_utime);
80 err |= __put_user(from->si_stime, &to->si_stime);
81 err |= __put_user(from->si_status, &to->si_status);
82 /* FALL THROUGH */
83 default:
84 case __SI_KILL >> 16:
85 err |= __put_user(from->si_uid, &to->si_uid);
86 break;
87 case __SI_POLL >> 16:
99b9cdf7 88 err |= __put_user(from->si_fd, &to->si_fd);
1da177e4
LT
89 break;
90 case __SI_TIMER >> 16:
99b9cdf7 91 err |= __put_user(from->si_overrun, &to->si_overrun);
1da177e4 92 err |= __put_user(ptr_to_compat(from->si_ptr),
99b9cdf7 93 &to->si_ptr);
1da177e4 94 break;
99b9cdf7
TG
95 /* This is not generated by the kernel as of now. */
96 case __SI_RT >> 16:
1da177e4
LT
97 case __SI_MESGQ >> 16:
98 err |= __put_user(from->si_uid, &to->si_uid);
99 err |= __put_user(from->si_int, &to->si_int);
100 break;
101 }
102 }
103 return err;
104}
105
106int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
107{
108 int err;
109 u32 ptr32;
99b9cdf7
TG
110
111 if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))
1da177e4
LT
112 return -EFAULT;
113
114 err = __get_user(to->si_signo, &from->si_signo);
115 err |= __get_user(to->si_errno, &from->si_errno);
116 err |= __get_user(to->si_code, &from->si_code);
117
118 err |= __get_user(to->si_pid, &from->si_pid);
119 err |= __get_user(to->si_uid, &from->si_uid);
120 err |= __get_user(ptr32, &from->si_ptr);
121 to->si_ptr = compat_ptr(ptr32);
122
123 return err;
124}
125
99b9cdf7 126asmlinkage long sys32_sigsuspend(int history0, int history1, old_sigset_t mask)
1da177e4 127{
1da177e4
LT
128 mask &= _BLOCKABLE;
129 spin_lock_irq(&current->sighand->siglock);
1d001df1 130 current->saved_sigmask = current->blocked;
1da177e4
LT
131 siginitset(&current->blocked, mask);
132 recalc_sigpending();
133 spin_unlock_irq(&current->sighand->siglock);
134
1d001df1
AK
135 current->state = TASK_INTERRUPTIBLE;
136 schedule();
5a8da0ea 137 set_restore_sigmask();
1d001df1 138 return -ERESTARTNOHAND;
1da177e4
LT
139}
140
99b9cdf7
TG
141asmlinkage long sys32_sigaltstack(const stack_ia32_t __user *uss_ptr,
142 stack_ia32_t __user *uoss_ptr,
143 struct pt_regs *regs)
1da177e4 144{
99b9cdf7 145 stack_t uss, uoss;
1da177e4 146 int ret;
99b9cdf7
TG
147 mm_segment_t seg;
148
149 if (uss_ptr) {
1da177e4 150 u32 ptr;
99b9cdf7
TG
151
152 memset(&uss, 0, sizeof(stack_t));
153 if (!access_ok(VERIFY_READ, uss_ptr, sizeof(stack_ia32_t)) ||
1da177e4
LT
154 __get_user(ptr, &uss_ptr->ss_sp) ||
155 __get_user(uss.ss_flags, &uss_ptr->ss_flags) ||
156 __get_user(uss.ss_size, &uss_ptr->ss_size))
157 return -EFAULT;
158 uss.ss_sp = compat_ptr(ptr);
159 }
99b9cdf7
TG
160 seg = get_fs();
161 set_fs(KERNEL_DS);
65ea5b03 162 ret = do_sigaltstack(uss_ptr ? &uss : NULL, &uoss, regs->sp);
99b9cdf7 163 set_fs(seg);
1da177e4 164 if (ret >= 0 && uoss_ptr) {
99b9cdf7 165 if (!access_ok(VERIFY_WRITE, uoss_ptr, sizeof(stack_ia32_t)) ||
1da177e4
LT
166 __put_user(ptr_to_compat(uoss.ss_sp), &uoss_ptr->ss_sp) ||
167 __put_user(uoss.ss_flags, &uoss_ptr->ss_flags) ||
168 __put_user(uoss.ss_size, &uoss_ptr->ss_size))
169 ret = -EFAULT;
99b9cdf7
TG
170 }
171 return ret;
1da177e4
LT
172}
173
174/*
175 * Do a signal return; undo the signal stack.
176 */
b78a5b52
HS
177#define COPY(x) { \
178 err |= __get_user(regs->x, &sc->x); \
1da177e4 179}
1da177e4 180
d71a68dc
HS
181#define COPY_SEG_CPL3(seg) { \
182 unsigned short tmp; \
183 err |= __get_user(tmp, &sc->seg); \
184 regs->seg = tmp | 3; \
1da177e4
LT
185}
186
8c6e5ce0
HS
187#define RELOAD_SEG(seg) { \
188 unsigned int cur, pre; \
189 err |= __get_user(pre, &sc->seg); \
190 savesegment(seg, cur); \
191 pre |= 3; \
192 if (pre != cur) \
193 loadsegment(seg, pre); \
194}
99b9cdf7
TG
195
196static int ia32_restore_sigcontext(struct pt_regs *regs,
197 struct sigcontext_ia32 __user *sc,
047ce935 198 unsigned int *pax)
99b9cdf7
TG
199{
200 unsigned int tmpflags, gs, oldgs, err = 0;
ab513701 201 void __user *buf;
99b9cdf7
TG
202 u32 tmp;
203
204 /* Always make any pending restarted system calls return -EINTR */
205 current_thread_info()->restart_block.fn = do_no_restart_syscall;
206
207#if DEBUG_SIG
208 printk(KERN_DEBUG "SIG restore_sigcontext: "
209 "sc=%p err(%x) eip(%x) cs(%x) flg(%x)\n",
65ea5b03 210 sc, sc->err, sc->ip, sc->cs, sc->flags);
99b9cdf7
TG
211#endif
212
213 /*
214 * Reload fs and gs if they have changed in the signal
215 * handler. This does not handle long fs/gs base changes in
216 * the handler, but does not clobber them at least in the
217 * normal case.
218 */
219 err |= __get_user(gs, &sc->gs);
220 gs |= 3;
b6edbb1e 221 savesegment(gs, oldgs);
99b9cdf7
TG
222 if (gs != oldgs)
223 load_gs_index(gs);
224
8c6e5ce0
HS
225 RELOAD_SEG(fs);
226 RELOAD_SEG(ds);
227 RELOAD_SEG(es);
1da177e4
LT
228
229 COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
230 COPY(dx); COPY(cx); COPY(ip);
99b9cdf7
TG
231 /* Don't touch extended registers */
232
d71a68dc
HS
233 COPY_SEG_CPL3(cs);
234 COPY_SEG_CPL3(ss);
99b9cdf7 235
742fa54a 236 err |= __get_user(tmpflags, &sc->flags);
fbdb7da9 237 regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
99b9cdf7 238 /* disable syscall checks */
65ea5b03 239 regs->orig_ax = -1;
99b9cdf7
TG
240
241 err |= __get_user(tmp, &sc->fpstate);
242 buf = compat_ptr(tmp);
ab513701 243 err |= restore_i387_xstate_ia32(buf);
1da177e4 244
047ce935 245 err |= __get_user(*pax, &sc->ax);
1da177e4 246 return err;
1da177e4
LT
247}
248
249asmlinkage long sys32_sigreturn(struct pt_regs *regs)
250{
3b0d29ee 251 struct sigframe_ia32 __user *frame = (struct sigframe_ia32 __user *)(regs->sp-8);
1da177e4 252 sigset_t set;
65ea5b03 253 unsigned int ax;
1da177e4
LT
254
255 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
256 goto badframe;
257 if (__get_user(set.sig[0], &frame->sc.oldmask)
258 || (_COMPAT_NSIG_WORDS > 1
99b9cdf7
TG
259 && __copy_from_user((((char *) &set.sig) + 4),
260 &frame->extramask,
1da177e4
LT
261 sizeof(frame->extramask))))
262 goto badframe;
263
264 sigdelsetmask(&set, ~_BLOCKABLE);
265 spin_lock_irq(&current->sighand->siglock);
266 current->blocked = set;
267 recalc_sigpending();
268 spin_unlock_irq(&current->sighand->siglock);
99b9cdf7 269
65ea5b03 270 if (ia32_restore_sigcontext(regs, &frame->sc, &ax))
1da177e4 271 goto badframe;
65ea5b03 272 return ax;
1da177e4
LT
273
274badframe:
275 signal_fault(regs, frame, "32bit sigreturn");
276 return 0;
99b9cdf7 277}
1da177e4
LT
278
279asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs)
280{
3b0d29ee 281 struct rt_sigframe_ia32 __user *frame;
1da177e4 282 sigset_t set;
65ea5b03 283 unsigned int ax;
1da177e4
LT
284 struct pt_regs tregs;
285
3b0d29ee 286 frame = (struct rt_sigframe_ia32 __user *)(regs->sp - 4);
1da177e4
LT
287
288 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
289 goto badframe;
290 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
291 goto badframe;
292
293 sigdelsetmask(&set, ~_BLOCKABLE);
294 spin_lock_irq(&current->sighand->siglock);
295 current->blocked = set;
296 recalc_sigpending();
297 spin_unlock_irq(&current->sighand->siglock);
99b9cdf7 298
65ea5b03 299 if (ia32_restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
1da177e4
LT
300 goto badframe;
301
302 tregs = *regs;
303 if (sys32_sigaltstack(&frame->uc.uc_stack, NULL, &tregs) == -EFAULT)
304 goto badframe;
305
65ea5b03 306 return ax;
1da177e4
LT
307
308badframe:
99b9cdf7 309 signal_fault(regs, frame, "32bit rt sigreturn");
1da177e4 310 return 0;
99b9cdf7 311}
1da177e4
LT
312
313/*
314 * Set up a signal frame.
315 */
316
99b9cdf7 317static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc,
ab513701 318 void __user *fpstate,
99b9cdf7 319 struct pt_regs *regs, unsigned int mask)
1da177e4
LT
320{
321 int tmp, err = 0;
1da177e4 322
b6edbb1e 323 savesegment(gs, tmp);
1da177e4 324 err |= __put_user(tmp, (unsigned int __user *)&sc->gs);
b6edbb1e 325 savesegment(fs, tmp);
1da177e4 326 err |= __put_user(tmp, (unsigned int __user *)&sc->fs);
b6edbb1e 327 savesegment(ds, tmp);
1da177e4 328 err |= __put_user(tmp, (unsigned int __user *)&sc->ds);
b6edbb1e 329 savesegment(es, tmp);
1da177e4
LT
330 err |= __put_user(tmp, (unsigned int __user *)&sc->es);
331
bff0aa4b
HS
332 err |= __put_user(regs->di, &sc->di);
333 err |= __put_user(regs->si, &sc->si);
334 err |= __put_user(regs->bp, &sc->bp);
335 err |= __put_user(regs->sp, &sc->sp);
336 err |= __put_user(regs->bx, &sc->bx);
337 err |= __put_user(regs->dx, &sc->dx);
338 err |= __put_user(regs->cx, &sc->cx);
339 err |= __put_user(regs->ax, &sc->ax);
1da177e4
LT
340 err |= __put_user(current->thread.trap_no, &sc->trapno);
341 err |= __put_user(current->thread.error_code, &sc->err);
bff0aa4b 342 err |= __put_user(regs->ip, &sc->ip);
64977609 343 err |= __put_user(regs->cs, (unsigned int __user *)&sc->cs);
bff0aa4b
HS
344 err |= __put_user(regs->flags, &sc->flags);
345 err |= __put_user(regs->sp, &sc->sp_at_signal);
64977609 346 err |= __put_user(regs->ss, (unsigned int __user *)&sc->ss);
1da177e4 347
99ea1b93 348 err |= __put_user(ptr_to_compat(fpstate), &sc->fpstate);
1da177e4
LT
349
350 /* non-iBCS2 extensions.. */
351 err |= __put_user(mask, &sc->oldmask);
352 err |= __put_user(current->thread.cr2, &sc->cr2);
353
354 return err;
355}
356
357/*
358 * Determine which stack to use..
359 */
99b9cdf7 360static void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
3c1c7f10 361 size_t frame_size,
ab513701 362 void **fpstate)
1da177e4 363{
65ea5b03 364 unsigned long sp;
1da177e4
LT
365
366 /* Default to using normal stack */
65ea5b03 367 sp = regs->sp;
1da177e4
LT
368
369 /* This is the X/Open sanctioned signal stack switching. */
370 if (ka->sa.sa_flags & SA_ONSTACK) {
65ea5b03
PA
371 if (sas_ss_flags(sp) == 0)
372 sp = current->sas_ss_sp + current->sas_ss_size;
1da177e4
LT
373 }
374
375 /* This is the legacy signal stack switching. */
8bee3f0a 376 else if ((regs->ss & 0xffff) != __USER32_DS &&
1da177e4 377 !(ka->sa.sa_flags & SA_RESTORER) &&
99b9cdf7 378 ka->sa.sa_restorer)
65ea5b03 379 sp = (unsigned long) ka->sa.sa_restorer;
1da177e4 380
3c1c7f10
SS
381 if (used_math()) {
382 sp = sp - sig_xstate_ia32_size;
383 *fpstate = (struct _fpstate_ia32 *) sp;
99ea1b93
HS
384 if (save_i387_xstate_ia32(*fpstate) < 0)
385 return (void __user *) -1L;
3c1c7f10
SS
386 }
387
65ea5b03 388 sp -= frame_size;
d347f372
MO
389 /* Align the stack pointer according to the i386 ABI,
390 * i.e. so that on function entry ((sp + 4) & 15) == 0. */
65ea5b03
PA
391 sp = ((sp + 4) & -16ul) - 4;
392 return (void __user *) sp;
1da177e4
LT
393}
394
0928d6ef 395int ia32_setup_frame(int sig, struct k_sigaction *ka,
99b9cdf7 396 compat_sigset_t *set, struct pt_regs *regs)
1da177e4 397{
3b0d29ee 398 struct sigframe_ia32 __user *frame;
99b9cdf7 399 void __user *restorer;
1da177e4 400 int err = 0;
ab513701 401 void __user *fpstate = NULL;
1da177e4 402
99b9cdf7
TG
403 /* copy_to_user optimizes that into a single 8 byte store */
404 static const struct {
405 u16 poplmovl;
406 u32 val;
407 u16 int80;
99b9cdf7
TG
408 } __attribute__((packed)) code = {
409 0xb858, /* popl %eax ; movl $...,%eax */
410 __NR_ia32_sigreturn,
411 0x80cd, /* int $0x80 */
99b9cdf7
TG
412 };
413
3c1c7f10 414 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
1da177e4
LT
415
416 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
3d0aedd9 417 return -EFAULT;
1da177e4 418
2ba48e16 419 if (__put_user(sig, &frame->sig))
3d0aedd9 420 return -EFAULT;
1da177e4 421
2ba48e16 422 if (ia32_setup_sigcontext(&frame->sc, fpstate, regs, set->sig[0]))
3d0aedd9 423 return -EFAULT;
1da177e4
LT
424
425 if (_COMPAT_NSIG_WORDS > 1) {
2ba48e16
HS
426 if (__copy_to_user(frame->extramask, &set->sig[1],
427 sizeof(frame->extramask)))
3d0aedd9 428 return -EFAULT;
1da177e4 429 }
1da177e4 430
af65d648 431 if (ka->sa.sa_flags & SA_RESTORER) {
99b9cdf7 432 restorer = ka->sa.sa_restorer;
af65d648
RM
433 } else {
434 /* Return stub is in 32bit vsyscall page */
1a3e4ca4 435 if (current->mm->context.vdso)
af65d648
RM
436 restorer = VDSO32_SYMBOL(current->mm->context.vdso,
437 sigreturn);
438 else
ade1af77 439 restorer = &frame->retcode;
af65d648 440 }
99b9cdf7
TG
441 err |= __put_user(ptr_to_compat(restorer), &frame->pretcode);
442
443 /*
444 * These are actually not used anymore, but left because some
445 * gdb versions depend on them as a marker.
446 */
d0b48ca1 447 err |= __put_user(*((u64 *)&code), (u64 *)frame->retcode);
1da177e4 448 if (err)
3d0aedd9 449 return -EFAULT;
1da177e4
LT
450
451 /* Set up registers for signal handler */
65ea5b03
PA
452 regs->sp = (unsigned long) frame;
453 regs->ip = (unsigned long) ka->sa.sa_handler;
1da177e4 454
536e3ee4 455 /* Make -mregparm=3 work */
65ea5b03
PA
456 regs->ax = sig;
457 regs->dx = 0;
458 regs->cx = 0;
536e3ee4 459
b6edbb1e
JF
460 loadsegment(ds, __USER32_DS);
461 loadsegment(es, __USER32_DS);
1da177e4 462
99b9cdf7
TG
463 regs->cs = __USER32_CS;
464 regs->ss = __USER32_DS;
1da177e4 465
1da177e4 466#if DEBUG_SIG
99b9cdf7 467 printk(KERN_DEBUG "SIG deliver (%s:%d): sp=%p pc=%lx ra=%u\n",
65ea5b03 468 current->comm, current->pid, frame, regs->ip, frame->pretcode);
1da177e4
LT
469#endif
470
1d001df1 471 return 0;
1da177e4
LT
472}
473
0928d6ef 474int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
99b9cdf7 475 compat_sigset_t *set, struct pt_regs *regs)
1da177e4 476{
3b0d29ee 477 struct rt_sigframe_ia32 __user *frame;
af65d648 478 void __user *restorer;
1da177e4 479 int err = 0;
ab513701 480 void __user *fpstate = NULL;
1da177e4 481
99b9cdf7
TG
482 /* __copy_to_user optimizes that into a single 8 byte store */
483 static const struct {
484 u8 movl;
485 u32 val;
486 u16 int80;
9cc3c49e 487 u8 pad;
99b9cdf7
TG
488 } __attribute__((packed)) code = {
489 0xb8,
490 __NR_ia32_rt_sigreturn,
491 0x80cd,
492 0,
493 };
494
3c1c7f10 495 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
1da177e4
LT
496
497 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
3d0aedd9 498 return -EFAULT;
1da177e4 499
812b121d 500 err |= __put_user(sig, &frame->sig);
1da177e4
LT
501 err |= __put_user(ptr_to_compat(&frame->info), &frame->pinfo);
502 err |= __put_user(ptr_to_compat(&frame->uc), &frame->puc);
503 err |= copy_siginfo_to_user32(&frame->info, info);
504 if (err)
3d0aedd9 505 return -EFAULT;
1da177e4
LT
506
507 /* Create the ucontext. */
c37b5efe
SS
508 if (cpu_has_xsave)
509 err |= __put_user(UC_FP_XSTATE, &frame->uc.uc_flags);
510 else
511 err |= __put_user(0, &frame->uc.uc_flags);
1da177e4
LT
512 err |= __put_user(0, &frame->uc.uc_link);
513 err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
65ea5b03 514 err |= __put_user(sas_ss_flags(regs->sp),
1da177e4
LT
515 &frame->uc.uc_stack.ss_flags);
516 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
3c1c7f10 517 err |= ia32_setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
99b9cdf7 518 regs, set->sig[0]);
1da177e4
LT
519 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
520 if (err)
3d0aedd9 521 return -EFAULT;
1da177e4 522
99b9cdf7
TG
523 if (ka->sa.sa_flags & SA_RESTORER)
524 restorer = ka->sa.sa_restorer;
af65d648
RM
525 else
526 restorer = VDSO32_SYMBOL(current->mm->context.vdso,
527 rt_sigreturn);
99b9cdf7 528 err |= __put_user(ptr_to_compat(restorer), &frame->pretcode);
1da177e4 529
99b9cdf7
TG
530 /*
531 * Not actually used anymore, but left because some gdb
532 * versions need it.
533 */
d0b48ca1 534 err |= __put_user(*((u64 *)&code), (u64 *)frame->retcode);
1da177e4 535 if (err)
3d0aedd9 536 return -EFAULT;
1da177e4
LT
537
538 /* Set up registers for signal handler */
65ea5b03
PA
539 regs->sp = (unsigned long) frame;
540 regs->ip = (unsigned long) ka->sa.sa_handler;
1da177e4 541
a7aacdf9 542 /* Make -mregparm=3 work */
65ea5b03
PA
543 regs->ax = sig;
544 regs->dx = (unsigned long) &frame->info;
545 regs->cx = (unsigned long) &frame->uc;
a7aacdf9 546
b6edbb1e
JF
547 loadsegment(ds, __USER32_DS);
548 loadsegment(es, __USER32_DS);
99b9cdf7
TG
549
550 regs->cs = __USER32_CS;
551 regs->ss = __USER32_DS;
1da177e4 552
1da177e4 553#if DEBUG_SIG
99b9cdf7 554 printk(KERN_DEBUG "SIG deliver (%s:%d): sp=%p pc=%lx ra=%u\n",
65ea5b03 555 current->comm, current->pid, frame, regs->ip, frame->pretcode);
1da177e4
LT
556#endif
557
1d001df1 558 return 0;
1da177e4 559}
This page took 0.570665 seconds and 5 git commands to generate.