x86: ia32_signal: use __put_user() instead of __copy_to_user()
[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
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
b78a5b52
HS
200#define COPY(x) { \
201 err |= __get_user(regs->x, &sc->x); \
1da177e4
LT
202}
203
d71a68dc
HS
204#define COPY_SEG_CPL3(seg) { \
205 unsigned short tmp; \
206 err |= __get_user(tmp, &sc->seg); \
207 regs->seg = tmp | 3; \
208}
209
8c6e5ce0
HS
210#define RELOAD_SEG(seg) { \
211 unsigned int cur, pre; \
212 err |= __get_user(pre, &sc->seg); \
213 savesegment(seg, cur); \
214 pre |= 3; \
215 if (pre != cur) \
216 loadsegment(seg, pre); \
217}
99b9cdf7
TG
218
219static int ia32_restore_sigcontext(struct pt_regs *regs,
220 struct sigcontext_ia32 __user *sc,
047ce935 221 unsigned int *pax)
99b9cdf7
TG
222{
223 unsigned int tmpflags, gs, oldgs, err = 0;
ab513701 224 void __user *buf;
99b9cdf7
TG
225 u32 tmp;
226
227 /* Always make any pending restarted system calls return -EINTR */
228 current_thread_info()->restart_block.fn = do_no_restart_syscall;
229
230#if DEBUG_SIG
231 printk(KERN_DEBUG "SIG restore_sigcontext: "
232 "sc=%p err(%x) eip(%x) cs(%x) flg(%x)\n",
65ea5b03 233 sc, sc->err, sc->ip, sc->cs, sc->flags);
99b9cdf7
TG
234#endif
235
236 /*
237 * Reload fs and gs if they have changed in the signal
238 * handler. This does not handle long fs/gs base changes in
239 * the handler, but does not clobber them at least in the
240 * normal case.
241 */
242 err |= __get_user(gs, &sc->gs);
243 gs |= 3;
b6edbb1e 244 savesegment(gs, oldgs);
99b9cdf7
TG
245 if (gs != oldgs)
246 load_gs_index(gs);
247
8c6e5ce0
HS
248 RELOAD_SEG(fs);
249 RELOAD_SEG(ds);
250 RELOAD_SEG(es);
1da177e4
LT
251
252 COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
253 COPY(dx); COPY(cx); COPY(ip);
99b9cdf7
TG
254 /* Don't touch extended registers */
255
d71a68dc
HS
256 COPY_SEG_CPL3(cs);
257 COPY_SEG_CPL3(ss);
99b9cdf7 258
742fa54a 259 err |= __get_user(tmpflags, &sc->flags);
fbdb7da9 260 regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
99b9cdf7 261 /* disable syscall checks */
65ea5b03 262 regs->orig_ax = -1;
99b9cdf7
TG
263
264 err |= __get_user(tmp, &sc->fpstate);
265 buf = compat_ptr(tmp);
ab513701 266 err |= restore_i387_xstate_ia32(buf);
1da177e4 267
047ce935 268 err |= __get_user(*pax, &sc->ax);
1da177e4 269 return err;
1da177e4
LT
270}
271
272asmlinkage long sys32_sigreturn(struct pt_regs *regs)
273{
65ea5b03 274 struct sigframe __user *frame = (struct sigframe __user *)(regs->sp-8);
1da177e4 275 sigset_t set;
65ea5b03 276 unsigned int ax;
1da177e4
LT
277
278 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
279 goto badframe;
280 if (__get_user(set.sig[0], &frame->sc.oldmask)
281 || (_COMPAT_NSIG_WORDS > 1
99b9cdf7
TG
282 && __copy_from_user((((char *) &set.sig) + 4),
283 &frame->extramask,
1da177e4
LT
284 sizeof(frame->extramask))))
285 goto badframe;
286
287 sigdelsetmask(&set, ~_BLOCKABLE);
288 spin_lock_irq(&current->sighand->siglock);
289 current->blocked = set;
290 recalc_sigpending();
291 spin_unlock_irq(&current->sighand->siglock);
99b9cdf7 292
65ea5b03 293 if (ia32_restore_sigcontext(regs, &frame->sc, &ax))
1da177e4 294 goto badframe;
65ea5b03 295 return ax;
1da177e4
LT
296
297badframe:
298 signal_fault(regs, frame, "32bit sigreturn");
299 return 0;
99b9cdf7 300}
1da177e4
LT
301
302asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs)
303{
304 struct rt_sigframe __user *frame;
305 sigset_t set;
65ea5b03 306 unsigned int ax;
1da177e4
LT
307 struct pt_regs tregs;
308
65ea5b03 309 frame = (struct rt_sigframe __user *)(regs->sp - 4);
1da177e4
LT
310
311 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
312 goto badframe;
313 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
314 goto badframe;
315
316 sigdelsetmask(&set, ~_BLOCKABLE);
317 spin_lock_irq(&current->sighand->siglock);
318 current->blocked = set;
319 recalc_sigpending();
320 spin_unlock_irq(&current->sighand->siglock);
99b9cdf7 321
65ea5b03 322 if (ia32_restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
1da177e4
LT
323 goto badframe;
324
325 tregs = *regs;
326 if (sys32_sigaltstack(&frame->uc.uc_stack, NULL, &tregs) == -EFAULT)
327 goto badframe;
328
65ea5b03 329 return ax;
1da177e4
LT
330
331badframe:
99b9cdf7 332 signal_fault(regs, frame, "32bit rt sigreturn");
1da177e4 333 return 0;
99b9cdf7 334}
1da177e4
LT
335
336/*
337 * Set up a signal frame.
338 */
339
99b9cdf7 340static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc,
ab513701 341 void __user *fpstate,
99b9cdf7 342 struct pt_regs *regs, unsigned int mask)
1da177e4
LT
343{
344 int tmp, err = 0;
1da177e4 345
b6edbb1e 346 savesegment(gs, tmp);
1da177e4 347 err |= __put_user(tmp, (unsigned int __user *)&sc->gs);
b6edbb1e 348 savesegment(fs, tmp);
1da177e4 349 err |= __put_user(tmp, (unsigned int __user *)&sc->fs);
b6edbb1e 350 savesegment(ds, tmp);
1da177e4 351 err |= __put_user(tmp, (unsigned int __user *)&sc->ds);
b6edbb1e 352 savesegment(es, tmp);
1da177e4
LT
353 err |= __put_user(tmp, (unsigned int __user *)&sc->es);
354
bff0aa4b
HS
355 err |= __put_user(regs->di, &sc->di);
356 err |= __put_user(regs->si, &sc->si);
357 err |= __put_user(regs->bp, &sc->bp);
358 err |= __put_user(regs->sp, &sc->sp);
359 err |= __put_user(regs->bx, &sc->bx);
360 err |= __put_user(regs->dx, &sc->dx);
361 err |= __put_user(regs->cx, &sc->cx);
362 err |= __put_user(regs->ax, &sc->ax);
1da177e4
LT
363 err |= __put_user(current->thread.trap_no, &sc->trapno);
364 err |= __put_user(current->thread.error_code, &sc->err);
bff0aa4b 365 err |= __put_user(regs->ip, &sc->ip);
64977609 366 err |= __put_user(regs->cs, (unsigned int __user *)&sc->cs);
bff0aa4b
HS
367 err |= __put_user(regs->flags, &sc->flags);
368 err |= __put_user(regs->sp, &sc->sp_at_signal);
64977609 369 err |= __put_user(regs->ss, (unsigned int __user *)&sc->ss);
1da177e4 370
99ea1b93 371 err |= __put_user(ptr_to_compat(fpstate), &sc->fpstate);
1da177e4
LT
372
373 /* non-iBCS2 extensions.. */
374 err |= __put_user(mask, &sc->oldmask);
375 err |= __put_user(current->thread.cr2, &sc->cr2);
376
377 return err;
378}
379
380/*
381 * Determine which stack to use..
382 */
99b9cdf7 383static void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
3c1c7f10 384 size_t frame_size,
ab513701 385 void **fpstate)
1da177e4 386{
65ea5b03 387 unsigned long sp;
1da177e4
LT
388
389 /* Default to using normal stack */
65ea5b03 390 sp = regs->sp;
1da177e4
LT
391
392 /* This is the X/Open sanctioned signal stack switching. */
393 if (ka->sa.sa_flags & SA_ONSTACK) {
65ea5b03
PA
394 if (sas_ss_flags(sp) == 0)
395 sp = current->sas_ss_sp + current->sas_ss_size;
1da177e4
LT
396 }
397
398 /* This is the legacy signal stack switching. */
399 else if ((regs->ss & 0xffff) != __USER_DS &&
400 !(ka->sa.sa_flags & SA_RESTORER) &&
99b9cdf7 401 ka->sa.sa_restorer)
65ea5b03 402 sp = (unsigned long) ka->sa.sa_restorer;
1da177e4 403
3c1c7f10
SS
404 if (used_math()) {
405 sp = sp - sig_xstate_ia32_size;
406 *fpstate = (struct _fpstate_ia32 *) sp;
99ea1b93
HS
407 if (save_i387_xstate_ia32(*fpstate) < 0)
408 return (void __user *) -1L;
3c1c7f10
SS
409 }
410
65ea5b03 411 sp -= frame_size;
d347f372
MO
412 /* Align the stack pointer according to the i386 ABI,
413 * i.e. so that on function entry ((sp + 4) & 15) == 0. */
65ea5b03
PA
414 sp = ((sp + 4) & -16ul) - 4;
415 return (void __user *) sp;
1da177e4
LT
416}
417
0928d6ef 418int ia32_setup_frame(int sig, struct k_sigaction *ka,
99b9cdf7 419 compat_sigset_t *set, struct pt_regs *regs)
1da177e4
LT
420{
421 struct sigframe __user *frame;
99b9cdf7 422 void __user *restorer;
1da177e4 423 int err = 0;
ab513701 424 void __user *fpstate = NULL;
1da177e4 425
99b9cdf7
TG
426 /* copy_to_user optimizes that into a single 8 byte store */
427 static const struct {
428 u16 poplmovl;
429 u32 val;
430 u16 int80;
99b9cdf7
TG
431 } __attribute__((packed)) code = {
432 0xb858, /* popl %eax ; movl $...,%eax */
433 __NR_ia32_sigreturn,
434 0x80cd, /* int $0x80 */
99b9cdf7
TG
435 };
436
3c1c7f10 437 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
1da177e4
LT
438
439 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
3d0aedd9 440 return -EFAULT;
1da177e4 441
2ba48e16 442 if (__put_user(sig, &frame->sig))
3d0aedd9 443 return -EFAULT;
1da177e4 444
2ba48e16 445 if (ia32_setup_sigcontext(&frame->sc, fpstate, regs, set->sig[0]))
3d0aedd9 446 return -EFAULT;
1da177e4
LT
447
448 if (_COMPAT_NSIG_WORDS > 1) {
2ba48e16
HS
449 if (__copy_to_user(frame->extramask, &set->sig[1],
450 sizeof(frame->extramask)))
3d0aedd9 451 return -EFAULT;
1da177e4 452 }
1da177e4 453
af65d648 454 if (ka->sa.sa_flags & SA_RESTORER) {
99b9cdf7 455 restorer = ka->sa.sa_restorer;
af65d648
RM
456 } else {
457 /* Return stub is in 32bit vsyscall page */
1a3e4ca4 458 if (current->mm->context.vdso)
af65d648
RM
459 restorer = VDSO32_SYMBOL(current->mm->context.vdso,
460 sigreturn);
461 else
ade1af77 462 restorer = &frame->retcode;
af65d648 463 }
99b9cdf7
TG
464 err |= __put_user(ptr_to_compat(restorer), &frame->pretcode);
465
466 /*
467 * These are actually not used anymore, but left because some
468 * gdb versions depend on them as a marker.
469 */
d0b48ca1 470 err |= __put_user(*((u64 *)&code), (u64 *)frame->retcode);
1da177e4 471 if (err)
3d0aedd9 472 return -EFAULT;
1da177e4
LT
473
474 /* Set up registers for signal handler */
65ea5b03
PA
475 regs->sp = (unsigned long) frame;
476 regs->ip = (unsigned long) ka->sa.sa_handler;
1da177e4 477
536e3ee4 478 /* Make -mregparm=3 work */
65ea5b03
PA
479 regs->ax = sig;
480 regs->dx = 0;
481 regs->cx = 0;
536e3ee4 482
b6edbb1e
JF
483 loadsegment(ds, __USER32_DS);
484 loadsegment(es, __USER32_DS);
1da177e4 485
99b9cdf7
TG
486 regs->cs = __USER32_CS;
487 regs->ss = __USER32_DS;
1da177e4 488
1da177e4 489#if DEBUG_SIG
99b9cdf7 490 printk(KERN_DEBUG "SIG deliver (%s:%d): sp=%p pc=%lx ra=%u\n",
65ea5b03 491 current->comm, current->pid, frame, regs->ip, frame->pretcode);
1da177e4
LT
492#endif
493
1d001df1 494 return 0;
1da177e4
LT
495}
496
0928d6ef 497int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
99b9cdf7 498 compat_sigset_t *set, struct pt_regs *regs)
1da177e4
LT
499{
500 struct rt_sigframe __user *frame;
af65d648 501 void __user *restorer;
1da177e4 502 int err = 0;
ab513701 503 void __user *fpstate = NULL;
1da177e4 504
99b9cdf7
TG
505 /* __copy_to_user optimizes that into a single 8 byte store */
506 static const struct {
507 u8 movl;
508 u32 val;
509 u16 int80;
9cc3c49e 510 u8 pad;
99b9cdf7
TG
511 } __attribute__((packed)) code = {
512 0xb8,
513 __NR_ia32_rt_sigreturn,
514 0x80cd,
515 0,
516 };
517
3c1c7f10 518 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
1da177e4
LT
519
520 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
3d0aedd9 521 return -EFAULT;
1da177e4 522
812b121d 523 err |= __put_user(sig, &frame->sig);
1da177e4
LT
524 err |= __put_user(ptr_to_compat(&frame->info), &frame->pinfo);
525 err |= __put_user(ptr_to_compat(&frame->uc), &frame->puc);
526 err |= copy_siginfo_to_user32(&frame->info, info);
527 if (err)
3d0aedd9 528 return -EFAULT;
1da177e4
LT
529
530 /* Create the ucontext. */
c37b5efe
SS
531 if (cpu_has_xsave)
532 err |= __put_user(UC_FP_XSTATE, &frame->uc.uc_flags);
533 else
534 err |= __put_user(0, &frame->uc.uc_flags);
1da177e4
LT
535 err |= __put_user(0, &frame->uc.uc_link);
536 err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
65ea5b03 537 err |= __put_user(sas_ss_flags(regs->sp),
1da177e4
LT
538 &frame->uc.uc_stack.ss_flags);
539 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
3c1c7f10 540 err |= ia32_setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
99b9cdf7 541 regs, set->sig[0]);
1da177e4
LT
542 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
543 if (err)
3d0aedd9 544 return -EFAULT;
1da177e4 545
99b9cdf7
TG
546 if (ka->sa.sa_flags & SA_RESTORER)
547 restorer = ka->sa.sa_restorer;
af65d648
RM
548 else
549 restorer = VDSO32_SYMBOL(current->mm->context.vdso,
550 rt_sigreturn);
99b9cdf7 551 err |= __put_user(ptr_to_compat(restorer), &frame->pretcode);
1da177e4 552
99b9cdf7
TG
553 /*
554 * Not actually used anymore, but left because some gdb
555 * versions need it.
556 */
d0b48ca1 557 err |= __put_user(*((u64 *)&code), (u64 *)frame->retcode);
1da177e4 558 if (err)
3d0aedd9 559 return -EFAULT;
1da177e4
LT
560
561 /* Set up registers for signal handler */
65ea5b03
PA
562 regs->sp = (unsigned long) frame;
563 regs->ip = (unsigned long) ka->sa.sa_handler;
1da177e4 564
a7aacdf9 565 /* Make -mregparm=3 work */
65ea5b03
PA
566 regs->ax = sig;
567 regs->dx = (unsigned long) &frame->info;
568 regs->cx = (unsigned long) &frame->uc;
a7aacdf9 569
8e3de538 570 /* Make -mregparm=3 work */
65ea5b03
PA
571 regs->ax = sig;
572 regs->dx = (unsigned long) &frame->info;
573 regs->cx = (unsigned long) &frame->uc;
8e3de538 574
b6edbb1e
JF
575 loadsegment(ds, __USER32_DS);
576 loadsegment(es, __USER32_DS);
99b9cdf7
TG
577
578 regs->cs = __USER32_CS;
579 regs->ss = __USER32_DS;
1da177e4 580
1da177e4 581#if DEBUG_SIG
99b9cdf7 582 printk(KERN_DEBUG "SIG deliver (%s:%d): sp=%p pc=%lx ra=%u\n",
65ea5b03 583 current->comm, current->pid, frame, regs->ip, frame->pretcode);
1da177e4
LT
584#endif
585
1d001df1 586 return 0;
1da177e4 587}
This page took 0.447421 seconds and 5 git commands to generate.