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