blob: e8c380dceb86e2a4ad62786bbb644134e8cd7515 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 1991, 1992 Linus Torvalds
7 * Copyright (C) 1994 - 2000 Ralf Baechle
8 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
9 */
10#include <linux/sched.h>
11#include <linux/mm.h>
12#include <linux/smp.h>
13#include <linux/smp_lock.h>
14#include <linux/kernel.h>
15#include <linux/signal.h>
16#include <linux/syscalls.h>
17#include <linux/errno.h>
18#include <linux/wait.h>
19#include <linux/ptrace.h>
20#include <linux/compat.h>
21#include <linux/suspend.h>
22#include <linux/compiler.h>
23
24#include <asm/asm.h>
25#include <linux/bitops.h>
26#include <asm/cacheflush.h>
27#include <asm/sim.h>
28#include <asm/uaccess.h>
29#include <asm/ucontext.h>
30#include <asm/system.h>
31#include <asm/fpu.h>
32
33#define SI_PAD_SIZE32 ((SI_MAX_SIZE/sizeof(int)) - 3)
34
35typedef struct compat_siginfo {
36 int si_signo;
37 int si_code;
38 int si_errno;
39
40 union {
41 int _pad[SI_PAD_SIZE32];
42
43 /* kill() */
44 struct {
45 compat_pid_t _pid; /* sender's pid */
46 compat_uid_t _uid; /* sender's uid */
47 } _kill;
48
49 /* SIGCHLD */
50 struct {
51 compat_pid_t _pid; /* which child */
52 compat_uid_t _uid; /* sender's uid */
53 int _status; /* exit code */
54 compat_clock_t _utime;
55 compat_clock_t _stime;
56 } _sigchld;
57
58 /* IRIX SIGCHLD */
59 struct {
60 compat_pid_t _pid; /* which child */
61 compat_clock_t _utime;
62 int _status; /* exit code */
63 compat_clock_t _stime;
64 } _irix_sigchld;
65
66 /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
67 struct {
68 s32 _addr; /* faulting insn/memory ref. */
69 } _sigfault;
70
71 /* SIGPOLL, SIGXFSZ (To do ...) */
72 struct {
73 int _band; /* POLL_IN, POLL_OUT, POLL_MSG */
74 int _fd;
75 } _sigpoll;
76
77 /* POSIX.1b timers */
78 struct {
Ralf Baechlea9820992005-02-16 21:24:16 +000079 timer_t _tid; /* timer id */
80 int _overrun; /* overrun count */
Ralf Baechle209ac8d2005-03-18 17:36:42 +000081 compat_sigval_t _sigval;/* same as below */
Ralf Baechlea9820992005-02-16 21:24:16 +000082 int _sys_private; /* not to be passed to user */
Linus Torvalds1da177e2005-04-16 15:20:36 -070083 } _timer;
84
85 /* POSIX.1b signals */
86 struct {
87 compat_pid_t _pid; /* sender's pid */
88 compat_uid_t _uid; /* sender's uid */
89 compat_sigval_t _sigval;
90 } _rt;
91
92 } _sifields;
93} compat_siginfo_t;
94
95/*
96 * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
97 */
98#define __NR_O32_sigreturn 4119
99#define __NR_O32_rt_sigreturn 4193
100#define __NR_O32_restart_syscall 4253
101
102#define DEBUG_SIG 0
103
104#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
105
106extern int do_signal32(sigset_t *oldset, struct pt_regs *regs);
107
108/* 32-bit compatibility types */
109
110#define _NSIG_BPW32 32
111#define _NSIG_WORDS32 (_NSIG / _NSIG_BPW32)
112
113typedef struct {
114 unsigned int sig[_NSIG_WORDS32];
115} sigset_t32;
116
117typedef unsigned int __sighandler32_t;
118typedef void (*vfptr_t)(void);
119
120struct sigaction32 {
121 unsigned int sa_flags;
122 __sighandler32_t sa_handler;
123 compat_sigset_t sa_mask;
124};
125
126/* IRIX compatible stack_t */
127typedef struct sigaltstack32 {
128 s32 ss_sp;
129 compat_size_t ss_size;
130 int ss_flags;
131} stack32_t;
132
133struct ucontext32 {
134 u32 uc_flags;
135 s32 uc_link;
136 stack32_t uc_stack;
137 struct sigcontext32 uc_mcontext;
138 sigset_t32 uc_sigmask; /* mask last for extensibility */
139};
140
141extern void __put_sigset_unknown_nsig(void);
142extern void __get_sigset_unknown_nsig(void);
143
144static inline int put_sigset(const sigset_t *kbuf, compat_sigset_t *ubuf)
145{
146 int err = 0;
147
148 if (!access_ok(VERIFY_WRITE, ubuf, sizeof(*ubuf)))
149 return -EFAULT;
150
151 switch (_NSIG_WORDS) {
152 default:
153 __put_sigset_unknown_nsig();
154 case 2:
155 err |= __put_user (kbuf->sig[1] >> 32, &ubuf->sig[3]);
156 err |= __put_user (kbuf->sig[1] & 0xffffffff, &ubuf->sig[2]);
157 case 1:
158 err |= __put_user (kbuf->sig[0] >> 32, &ubuf->sig[1]);
159 err |= __put_user (kbuf->sig[0] & 0xffffffff, &ubuf->sig[0]);
160 }
161
162 return err;
163}
164
165static inline int get_sigset(sigset_t *kbuf, const compat_sigset_t *ubuf)
166{
167 int err = 0;
168 unsigned long sig[4];
169
170 if (!access_ok(VERIFY_READ, ubuf, sizeof(*ubuf)))
171 return -EFAULT;
172
173 switch (_NSIG_WORDS) {
174 default:
175 __get_sigset_unknown_nsig();
176 case 2:
177 err |= __get_user (sig[3], &ubuf->sig[3]);
178 err |= __get_user (sig[2], &ubuf->sig[2]);
179 kbuf->sig[1] = sig[2] | (sig[3] << 32);
180 case 1:
181 err |= __get_user (sig[1], &ubuf->sig[1]);
182 err |= __get_user (sig[0], &ubuf->sig[0]);
183 kbuf->sig[0] = sig[0] | (sig[1] << 32);
184 }
185
186 return err;
187}
188
189/*
190 * Atomically swap in the new signal mask, and wait for a signal.
191 */
192
193save_static_function(sys32_sigsuspend);
194__attribute_used__ noinline static int
195_sys32_sigsuspend(nabi_no_regargs struct pt_regs regs)
196{
197 compat_sigset_t *uset;
198 sigset_t newset, saveset;
199
200 uset = (compat_sigset_t *) regs.regs[4];
201 if (get_sigset(&newset, uset))
202 return -EFAULT;
203 sigdelsetmask(&newset, ~_BLOCKABLE);
204
205 spin_lock_irq(&current->sighand->siglock);
206 saveset = current->blocked;
207 current->blocked = newset;
208 recalc_sigpending();
209 spin_unlock_irq(&current->sighand->siglock);
210
211 regs.regs[2] = EINTR;
212 regs.regs[7] = 1;
213 while (1) {
214 current->state = TASK_INTERRUPTIBLE;
215 schedule();
216 if (do_signal32(&saveset, &regs))
217 return -EINTR;
218 }
219}
220
221save_static_function(sys32_rt_sigsuspend);
222__attribute_used__ noinline static int
223_sys32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
224{
225 compat_sigset_t *uset;
226 sigset_t newset, saveset;
227 size_t sigsetsize;
228
229 /* XXX Don't preclude handling different sized sigset_t's. */
230 sigsetsize = regs.regs[5];
231 if (sigsetsize != sizeof(compat_sigset_t))
232 return -EINVAL;
233
234 uset = (compat_sigset_t *) regs.regs[4];
235 if (get_sigset(&newset, uset))
236 return -EFAULT;
237 sigdelsetmask(&newset, ~_BLOCKABLE);
238
239 spin_lock_irq(&current->sighand->siglock);
240 saveset = current->blocked;
241 current->blocked = newset;
242 recalc_sigpending();
243 spin_unlock_irq(&current->sighand->siglock);
244
245 regs.regs[2] = EINTR;
246 regs.regs[7] = 1;
247 while (1) {
248 current->state = TASK_INTERRUPTIBLE;
249 schedule();
250 if (do_signal32(&saveset, &regs))
251 return -EINTR;
252 }
253}
254
255asmlinkage int sys32_sigaction(int sig, const struct sigaction32 *act,
256 struct sigaction32 *oact)
257{
258 struct k_sigaction new_ka, old_ka;
259 int ret;
260 int err = 0;
261
262 if (act) {
263 old_sigset_t mask;
Ralf Baechle77c728c2005-03-04 19:36:51 +0000264 s32 handler;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700265
266 if (!access_ok(VERIFY_READ, act, sizeof(*act)))
267 return -EFAULT;
Ralf Baechle77c728c2005-03-04 19:36:51 +0000268 err |= __get_user(handler, &act->sa_handler);
269 new_ka.sa.sa_handler = (void*)(s64)handler;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700270 err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
271 err |= __get_user(mask, &act->sa_mask.sig[0]);
272 if (err)
273 return -EFAULT;
274
275 siginitset(&new_ka.sa.sa_mask, mask);
276 }
277
278 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
279
280 if (!ret && oact) {
281 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
282 return -EFAULT;
283 err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
284 err |= __put_user((u32)(u64)old_ka.sa.sa_handler,
285 &oact->sa_handler);
286 err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
287 err |= __put_user(0, &oact->sa_mask.sig[1]);
288 err |= __put_user(0, &oact->sa_mask.sig[2]);
289 err |= __put_user(0, &oact->sa_mask.sig[3]);
290 if (err)
291 return -EFAULT;
292 }
293
294 return ret;
295}
296
297asmlinkage int sys32_sigaltstack(nabi_no_regargs struct pt_regs regs)
298{
299 const stack32_t *uss = (const stack32_t *) regs.regs[4];
300 stack32_t *uoss = (stack32_t *) regs.regs[5];
301 unsigned long usp = regs.regs[29];
302 stack_t kss, koss;
303 int ret, err = 0;
304 mm_segment_t old_fs = get_fs();
305 s32 sp;
306
307 if (uss) {
308 if (!access_ok(VERIFY_READ, uss, sizeof(*uss)))
309 return -EFAULT;
310 err |= __get_user(sp, &uss->ss_sp);
311 kss.ss_sp = (void *) (long) sp;
312 err |= __get_user(kss.ss_size, &uss->ss_size);
313 err |= __get_user(kss.ss_flags, &uss->ss_flags);
314 if (err)
315 return -EFAULT;
316 }
317
318 set_fs (KERNEL_DS);
319 ret = do_sigaltstack(uss ? &kss : NULL , uoss ? &koss : NULL, usp);
320 set_fs (old_fs);
321
322 if (!ret && uoss) {
323 if (!access_ok(VERIFY_WRITE, uoss, sizeof(*uoss)))
324 return -EFAULT;
325 sp = (int) (long) koss.ss_sp;
326 err |= __put_user(sp, &uoss->ss_sp);
327 err |= __put_user(koss.ss_size, &uoss->ss_size);
328 err |= __put_user(koss.ss_flags, &uoss->ss_flags);
329 if (err)
330 return -EFAULT;
331 }
332 return ret;
333}
334
335static int restore_sigcontext32(struct pt_regs *regs, struct sigcontext32 *sc)
336{
337 int err = 0;
338 __u32 used_math;
339
340 /* Always make any pending restarted system calls return -EINTR */
341 current_thread_info()->restart_block.fn = do_no_restart_syscall;
342
343 err |= __get_user(regs->cp0_epc, &sc->sc_pc);
344 err |= __get_user(regs->hi, &sc->sc_mdhi);
345 err |= __get_user(regs->lo, &sc->sc_mdlo);
346
347#define restore_gp_reg(i) do { \
348 err |= __get_user(regs->regs[i], &sc->sc_regs[i]); \
349} while(0)
350 restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
351 restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
352 restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
353 restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
354 restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
355 restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
356 restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
357 restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
358 restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
359 restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
360 restore_gp_reg(31);
361#undef restore_gp_reg
362
363 err |= __get_user(used_math, &sc->sc_used_math);
364 conditional_used_math(used_math);
365
366 preempt_disable();
367
368 if (used_math()) {
369 /* restore fpu context if we have used it before */
370 own_fpu();
371 err |= restore_fp_context32(sc);
372 } else {
373 /* signal handler may have used FPU. Give it up. */
374 lose_fpu();
375 }
376
377 preempt_enable();
378
379 return err;
380}
381
382struct sigframe {
383 u32 sf_ass[4]; /* argument save space for o32 */
384 u32 sf_code[2]; /* signal trampoline */
385 struct sigcontext32 sf_sc;
386 sigset_t sf_mask;
387};
388
389struct rt_sigframe32 {
390 u32 rs_ass[4]; /* argument save space for o32 */
391 u32 rs_code[2]; /* signal trampoline */
392 compat_siginfo_t rs_info;
393 struct ucontext32 rs_uc;
394};
395
396int copy_siginfo_to_user32(compat_siginfo_t *to, siginfo_t *from)
397{
398 int err;
399
400 if (!access_ok (VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
401 return -EFAULT;
402
403 /* If you change siginfo_t structure, please be sure
404 this code is fixed accordingly.
405 It should never copy any pad contained in the structure
406 to avoid security leaks, but must copy the generic
407 3 ints plus the relevant union member.
408 This routine must convert siginfo from 64bit to 32bit as well
409 at the same time. */
410 err = __put_user(from->si_signo, &to->si_signo);
411 err |= __put_user(from->si_errno, &to->si_errno);
412 err |= __put_user((short)from->si_code, &to->si_code);
413 if (from->si_code < 0)
414 err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
415 else {
416 switch (from->si_code >> 16) {
Ralf Baechlea9820992005-02-16 21:24:16 +0000417 case __SI_TIMER >> 16:
418 err |= __put_user(from->si_tid, &to->si_tid);
419 err |= __put_user(from->si_overrun, &to->si_overrun);
420 err |= __put_user(from->si_int, &to->si_int);
421 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422 case __SI_CHLD >> 16:
423 err |= __put_user(from->si_utime, &to->si_utime);
424 err |= __put_user(from->si_stime, &to->si_stime);
425 err |= __put_user(from->si_status, &to->si_status);
426 default:
427 err |= __put_user(from->si_pid, &to->si_pid);
428 err |= __put_user(from->si_uid, &to->si_uid);
429 break;
430 case __SI_FAULT >> 16:
431 err |= __put_user((long)from->si_addr, &to->si_addr);
432 break;
433 case __SI_POLL >> 16:
434 err |= __put_user(from->si_band, &to->si_band);
435 err |= __put_user(from->si_fd, &to->si_fd);
436 break;
437 case __SI_RT >> 16: /* This is not generated by the kernel as of now. */
438 case __SI_MESGQ >> 16:
439 err |= __put_user(from->si_pid, &to->si_pid);
440 err |= __put_user(from->si_uid, &to->si_uid);
441 err |= __put_user(from->si_int, &to->si_int);
442 break;
443 }
444 }
445 return err;
446}
447
448save_static_function(sys32_sigreturn);
449__attribute_used__ noinline static void
450_sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
451{
452 struct sigframe *frame;
453 sigset_t blocked;
454
455 frame = (struct sigframe *) regs.regs[29];
456 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
457 goto badframe;
458 if (__copy_from_user(&blocked, &frame->sf_mask, sizeof(blocked)))
459 goto badframe;
460
461 sigdelsetmask(&blocked, ~_BLOCKABLE);
462 spin_lock_irq(&current->sighand->siglock);
463 current->blocked = blocked;
464 recalc_sigpending();
465 spin_unlock_irq(&current->sighand->siglock);
466
467 if (restore_sigcontext32(&regs, &frame->sf_sc))
468 goto badframe;
469
470 /*
471 * Don't let your children do this ...
472 */
473 if (current_thread_info()->flags & TIF_SYSCALL_TRACE)
474 do_syscall_trace(&regs, 1);
475 __asm__ __volatile__(
476 "move\t$29, %0\n\t"
477 "j\tsyscall_exit"
478 :/* no outputs */
479 :"r" (&regs));
480 /* Unreached */
481
482badframe:
483 force_sig(SIGSEGV, current);
484}
485
486save_static_function(sys32_rt_sigreturn);
487__attribute_used__ noinline static void
488_sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
489{
490 struct rt_sigframe32 *frame;
491 sigset_t set;
492 stack_t st;
493 s32 sp;
494
495 frame = (struct rt_sigframe32 *) regs.regs[29];
496 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
497 goto badframe;
498 if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set)))
499 goto badframe;
500
501 sigdelsetmask(&set, ~_BLOCKABLE);
502 spin_lock_irq(&current->sighand->siglock);
503 current->blocked = set;
504 recalc_sigpending();
505 spin_unlock_irq(&current->sighand->siglock);
506
507 if (restore_sigcontext32(&regs, &frame->rs_uc.uc_mcontext))
508 goto badframe;
509
510 /* The ucontext contains a stack32_t, so we must convert! */
511 if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp))
512 goto badframe;
513 st.ss_size = (long) sp;
514 if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size))
515 goto badframe;
516 if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags))
517 goto badframe;
518
519 /* It is more difficult to avoid calling this function than to
520 call it and ignore errors. */
521 do_sigaltstack(&st, NULL, regs.regs[29]);
522
523 /*
524 * Don't let your children do this ...
525 */
526 __asm__ __volatile__(
527 "move\t$29, %0\n\t"
528 "j\tsyscall_exit"
529 :/* no outputs */
530 :"r" (&regs));
531 /* Unreached */
532
533badframe:
534 force_sig(SIGSEGV, current);
535}
536
537static inline int setup_sigcontext32(struct pt_regs *regs,
538 struct sigcontext32 *sc)
539{
540 int err = 0;
541
542 err |= __put_user(regs->cp0_epc, &sc->sc_pc);
543 err |= __put_user(regs->cp0_status, &sc->sc_status);
544
545#define save_gp_reg(i) { \
546 err |= __put_user(regs->regs[i], &sc->sc_regs[i]); \
547} while(0)
548 __put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
549 save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
550 save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
551 save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
552 save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
553 save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
554 save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
555 save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
556 save_gp_reg(31);
557#undef save_gp_reg
558
559 err |= __put_user(regs->hi, &sc->sc_mdhi);
560 err |= __put_user(regs->lo, &sc->sc_mdlo);
561 err |= __put_user(regs->cp0_cause, &sc->sc_cause);
562 err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr);
563
564 err |= __put_user(!!used_math(), &sc->sc_used_math);
565
566 if (!used_math())
567 goto out;
568
Ralf Baechle42a3b4f2005-09-03 15:56:17 -0700569 /*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700570 * Save FPU state to signal context. Signal handler will "inherit"
571 * current FPU state.
572 */
573 preempt_disable();
574
575 if (!is_fpu_owner()) {
576 own_fpu();
577 restore_fp(current);
578 }
579 err |= save_fp_context32(sc);
580
581 preempt_enable();
582
583out:
584 return err;
585}
586
587/*
588 * Determine which stack to use..
589 */
590static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
591 size_t frame_size)
592{
593 unsigned long sp;
594
595 /* Default to using normal stack */
596 sp = regs->regs[29];
597
598 /*
599 * FPU emulator may have it's own trampoline active just
600 * above the user stack, 16-bytes before the next lowest
601 * 16 byte boundary. Try to avoid trashing it.
602 */
603 sp -= 32;
604
605 /* This is the X/Open sanctioned signal stack switching. */
606 if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
607 sp = current->sas_ss_sp + current->sas_ss_size;
608
609 return (void *)((sp - frame_size) & ALMASK);
610}
611
612static inline void setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
613 int signr, sigset_t *set)
614{
615 struct sigframe *frame;
616 int err = 0;
617
618 frame = get_sigframe(ka, regs, sizeof(*frame));
619 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
620 goto give_sigsegv;
621
622 /*
623 * Set up the return code ...
624 *
625 * li v0, __NR_O32_sigreturn
626 * syscall
627 */
628 err |= __put_user(0x24020000 + __NR_O32_sigreturn, frame->sf_code + 0);
629 err |= __put_user(0x0000000c , frame->sf_code + 1);
630 flush_cache_sigtramp((unsigned long) frame->sf_code);
631
632 err |= setup_sigcontext32(regs, &frame->sf_sc);
633 err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set));
634 if (err)
635 goto give_sigsegv;
636
637 /*
638 * Arguments to signal handler:
639 *
640 * a0 = signal number
641 * a1 = 0 (should be cause)
642 * a2 = pointer to struct sigcontext
643 *
644 * $25 and c0_epc point to the signal handler, $29 points to the
645 * struct sigframe.
646 */
647 regs->regs[ 4] = signr;
648 regs->regs[ 5] = 0;
649 regs->regs[ 6] = (unsigned long) &frame->sf_sc;
650 regs->regs[29] = (unsigned long) frame;
651 regs->regs[31] = (unsigned long) frame->sf_code;
652 regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
653
654#if DEBUG_SIG
655 printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n",
656 current->comm, current->pid,
657 frame, regs->cp0_epc, frame->sf_code);
658#endif
659 return;
660
661give_sigsegv:
662 force_sigsegv(signr, current);
663}
664
665static inline void setup_rt_frame(struct k_sigaction * ka,
666 struct pt_regs *regs, int signr,
667 sigset_t *set, siginfo_t *info)
668{
669 struct rt_sigframe32 *frame;
670 int err = 0;
671 s32 sp;
672
673 frame = get_sigframe(ka, regs, sizeof(*frame));
674 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
675 goto give_sigsegv;
676
677 /* Set up to return from userspace. If provided, use a stub already
678 in userspace. */
679 /*
680 * Set up the return code ...
681 *
682 * li v0, __NR_O32_rt_sigreturn
683 * syscall
684 */
685 err |= __put_user(0x24020000 + __NR_O32_rt_sigreturn, frame->rs_code + 0);
686 err |= __put_user(0x0000000c , frame->rs_code + 1);
687 flush_cache_sigtramp((unsigned long) frame->rs_code);
688
689 /* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
690 err |= copy_siginfo_to_user32(&frame->rs_info, info);
691
692 /* Create the ucontext. */
693 err |= __put_user(0, &frame->rs_uc.uc_flags);
694 err |= __put_user(0, &frame->rs_uc.uc_link);
695 sp = (int) (long) current->sas_ss_sp;
696 err |= __put_user(sp,
697 &frame->rs_uc.uc_stack.ss_sp);
698 err |= __put_user(sas_ss_flags(regs->regs[29]),
699 &frame->rs_uc.uc_stack.ss_flags);
700 err |= __put_user(current->sas_ss_size,
701 &frame->rs_uc.uc_stack.ss_size);
702 err |= setup_sigcontext32(regs, &frame->rs_uc.uc_mcontext);
703 err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set));
704
705 if (err)
706 goto give_sigsegv;
707
708 /*
709 * Arguments to signal handler:
710 *
711 * a0 = signal number
712 * a1 = 0 (should be cause)
713 * a2 = pointer to ucontext
714 *
715 * $25 and c0_epc point to the signal handler, $29 points to
716 * the struct rt_sigframe32.
717 */
718 regs->regs[ 4] = signr;
719 regs->regs[ 5] = (unsigned long) &frame->rs_info;
720 regs->regs[ 6] = (unsigned long) &frame->rs_uc;
721 regs->regs[29] = (unsigned long) frame;
722 regs->regs[31] = (unsigned long) frame->rs_code;
723 regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
724
725#if DEBUG_SIG
726 printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n",
727 current->comm, current->pid,
728 frame, regs->cp0_epc, frame->rs_code);
729#endif
730 return;
731
732give_sigsegv:
733 force_sigsegv(signr, current);
734}
735
736static inline void handle_signal(unsigned long sig, siginfo_t *info,
737 struct k_sigaction *ka, sigset_t *oldset, struct pt_regs * regs)
738{
739 switch (regs->regs[0]) {
740 case ERESTART_RESTARTBLOCK:
741 case ERESTARTNOHAND:
742 regs->regs[2] = EINTR;
743 break;
744 case ERESTARTSYS:
745 if(!(ka->sa.sa_flags & SA_RESTART)) {
746 regs->regs[2] = EINTR;
747 break;
748 }
749 /* fallthrough */
750 case ERESTARTNOINTR: /* Userland will reload $v0. */
751 regs->regs[7] = regs->regs[26];
752 regs->cp0_epc -= 8;
753 }
754
755 regs->regs[0] = 0; /* Don't deal with this again. */
756
757 if (ka->sa.sa_flags & SA_SIGINFO)
758 setup_rt_frame(ka, regs, sig, oldset, info);
759 else
760 setup_frame(ka, regs, sig, oldset);
761
Steven Rostedt69be8f12005-08-29 11:44:09 -0400762 spin_lock_irq(&current->sighand->siglock);
763 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
764 if (!(ka->sa.sa_flags & SA_NODEFER))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700765 sigaddset(&current->blocked,sig);
Steven Rostedt69be8f12005-08-29 11:44:09 -0400766 recalc_sigpending();
767 spin_unlock_irq(&current->sighand->siglock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700768}
769
770int do_signal32(sigset_t *oldset, struct pt_regs *regs)
771{
772 struct k_sigaction ka;
773 siginfo_t info;
774 int signr;
775
776 /*
777 * We want the common case to go fast, which is why we may in certain
778 * cases get here from kernel mode. Just return without doing anything
779 * if so.
780 */
781 if (!user_mode(regs))
782 return 1;
783
Nigel Cunningham0e6c1f52005-07-27 11:43:34 -0700784 if (try_to_freeze())
Linus Torvalds1da177e2005-04-16 15:20:36 -0700785 goto no_signal;
786
787 if (!oldset)
788 oldset = &current->blocked;
789
790 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
791 if (signr > 0) {
792 handle_signal(signr, &info, &ka, oldset, regs);
793 return 1;
794 }
795
796no_signal:
797 /*
798 * Who's code doesn't conform to the restartable syscall convention
799 * dies here!!! The li instruction, a single machine instruction,
800 * must directly be followed by the syscall instruction.
801 */
802 if (regs->regs[0]) {
803 if (regs->regs[2] == ERESTARTNOHAND ||
804 regs->regs[2] == ERESTARTSYS ||
805 regs->regs[2] == ERESTARTNOINTR) {
806 regs->regs[7] = regs->regs[26];
807 regs->cp0_epc -= 8;
808 }
809 if (regs->regs[2] == ERESTART_RESTARTBLOCK) {
810 regs->regs[2] = __NR_O32_restart_syscall;
811 regs->regs[7] = regs->regs[26];
812 regs->cp0_epc -= 4;
813 }
814 }
815 return 0;
816}
817
818asmlinkage int sys32_rt_sigaction(int sig, const struct sigaction32 *act,
819 struct sigaction32 *oact,
820 unsigned int sigsetsize)
821{
822 struct k_sigaction new_sa, old_sa;
823 int ret = -EINVAL;
824
825 /* XXX: Don't preclude handling different sized sigset_t's. */
826 if (sigsetsize != sizeof(sigset_t))
827 goto out;
828
829 if (act) {
Ralf Baechle77c728c2005-03-04 19:36:51 +0000830 s32 handler;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700831 int err = 0;
832
833 if (!access_ok(VERIFY_READ, act, sizeof(*act)))
834 return -EFAULT;
Ralf Baechle77c728c2005-03-04 19:36:51 +0000835 err |= __get_user(handler, &act->sa_handler);
836 new_sa.sa.sa_handler = (void*)(s64)handler;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700837 err |= __get_user(new_sa.sa.sa_flags, &act->sa_flags);
838 err |= get_sigset(&new_sa.sa.sa_mask, &act->sa_mask);
839 if (err)
840 return -EFAULT;
841 }
842
843 ret = do_sigaction(sig, act ? &new_sa : NULL, oact ? &old_sa : NULL);
844
845 if (!ret && oact) {
846 int err = 0;
847
848 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
849 return -EFAULT;
850
851 err |= __put_user((u32)(u64)old_sa.sa.sa_handler,
852 &oact->sa_handler);
853 err |= __put_user(old_sa.sa.sa_flags, &oact->sa_flags);
854 err |= put_sigset(&old_sa.sa.sa_mask, &oact->sa_mask);
855 if (err)
856 return -EFAULT;
857 }
858out:
859 return ret;
860}
861
862asmlinkage int sys32_rt_sigprocmask(int how, compat_sigset_t *set,
863 compat_sigset_t *oset, unsigned int sigsetsize)
864{
865 sigset_t old_set, new_set;
866 int ret;
867 mm_segment_t old_fs = get_fs();
868
869 if (set && get_sigset(&new_set, set))
870 return -EFAULT;
871
872 set_fs (KERNEL_DS);
873 ret = sys_rt_sigprocmask(how, set ? &new_set : NULL,
874 oset ? &old_set : NULL, sigsetsize);
875 set_fs (old_fs);
876
877 if (!ret && oset && put_sigset(&old_set, oset))
878 return -EFAULT;
879
880 return ret;
881}
882
883asmlinkage int sys32_rt_sigpending(compat_sigset_t *uset,
884 unsigned int sigsetsize)
885{
886 int ret;
887 sigset_t set;
888 mm_segment_t old_fs = get_fs();
889
890 set_fs (KERNEL_DS);
891 ret = sys_rt_sigpending(&set, sigsetsize);
892 set_fs (old_fs);
893
894 if (!ret && put_sigset(&set, uset))
895 return -EFAULT;
896
897 return ret;
898}
899
900asmlinkage int sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t *uinfo)
901{
902 siginfo_t info;
903 int ret;
904 mm_segment_t old_fs = get_fs();
905
906 if (copy_from_user (&info, uinfo, 3*sizeof(int)) ||
907 copy_from_user (info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE))
908 return -EFAULT;
909 set_fs (KERNEL_DS);
910 ret = sys_rt_sigqueueinfo(pid, sig, &info);
911 set_fs (old_fs);
912 return ret;
913}
Ralf Baechle54f2da72005-02-16 21:21:29 +0000914
915asmlinkage long
916sys32_waitid(int which, compat_pid_t pid,
917 compat_siginfo_t __user *uinfo, int options,
918 struct compat_rusage __user *uru)
919{
920 siginfo_t info;
921 struct rusage ru;
922 long ret;
923 mm_segment_t old_fs = get_fs();
924
925 info.si_signo = 0;
926 set_fs (KERNEL_DS);
927 ret = sys_waitid(which, pid, (siginfo_t __user *) &info, options,
928 uru ? (struct rusage __user *) &ru : NULL);
929 set_fs (old_fs);
930
931 if (ret < 0 || info.si_signo == 0)
932 return ret;
933
934 if (uru && (ret = put_compat_rusage(&ru, uru)))
935 return ret;
936
937 BUG_ON(info.si_code & __SI_MASK);
938 info.si_code |= __SI_CHLD;
939 return copy_siginfo_to_user32(uinfo, &info);
940}