blob: 5e7d0fa026729fe647a921f47050a968dba833e9 [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;
Ralf Baechle1fcf1cc2005-04-13 18:18:04 +0000491 mm_segment_t old_fs;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700492 sigset_t set;
493 stack_t st;
494 s32 sp;
495
496 frame = (struct rt_sigframe32 *) regs.regs[29];
497 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
498 goto badframe;
499 if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set)))
500 goto badframe;
501
502 sigdelsetmask(&set, ~_BLOCKABLE);
503 spin_lock_irq(&current->sighand->siglock);
504 current->blocked = set;
505 recalc_sigpending();
506 spin_unlock_irq(&current->sighand->siglock);
507
508 if (restore_sigcontext32(&regs, &frame->rs_uc.uc_mcontext))
509 goto badframe;
510
511 /* The ucontext contains a stack32_t, so we must convert! */
512 if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp))
513 goto badframe;
514 st.ss_size = (long) sp;
515 if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size))
516 goto badframe;
517 if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags))
518 goto badframe;
519
520 /* It is more difficult to avoid calling this function than to
521 call it and ignore errors. */
Ralf Baechle1fcf1cc2005-04-13 18:18:04 +0000522 old_fs = get_fs();
523 set_fs (KERNEL_DS);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700524 do_sigaltstack(&st, NULL, regs.regs[29]);
Ralf Baechle1fcf1cc2005-04-13 18:18:04 +0000525 set_fs (old_fs);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700526
527 /*
528 * Don't let your children do this ...
529 */
530 __asm__ __volatile__(
531 "move\t$29, %0\n\t"
532 "j\tsyscall_exit"
533 :/* no outputs */
534 :"r" (&regs));
535 /* Unreached */
536
537badframe:
538 force_sig(SIGSEGV, current);
539}
540
541static inline int setup_sigcontext32(struct pt_regs *regs,
542 struct sigcontext32 *sc)
543{
544 int err = 0;
545
546 err |= __put_user(regs->cp0_epc, &sc->sc_pc);
547 err |= __put_user(regs->cp0_status, &sc->sc_status);
548
549#define save_gp_reg(i) { \
550 err |= __put_user(regs->regs[i], &sc->sc_regs[i]); \
551} while(0)
552 __put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
553 save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
554 save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
555 save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
556 save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
557 save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
558 save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
559 save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
560 save_gp_reg(31);
561#undef save_gp_reg
562
563 err |= __put_user(regs->hi, &sc->sc_mdhi);
564 err |= __put_user(regs->lo, &sc->sc_mdlo);
565 err |= __put_user(regs->cp0_cause, &sc->sc_cause);
566 err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr);
567
568 err |= __put_user(!!used_math(), &sc->sc_used_math);
569
570 if (!used_math())
571 goto out;
572
Ralf Baechle42a3b4f2005-09-03 15:56:17 -0700573 /*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700574 * Save FPU state to signal context. Signal handler will "inherit"
575 * current FPU state.
576 */
577 preempt_disable();
578
579 if (!is_fpu_owner()) {
580 own_fpu();
581 restore_fp(current);
582 }
583 err |= save_fp_context32(sc);
584
585 preempt_enable();
586
587out:
588 return err;
589}
590
591/*
592 * Determine which stack to use..
593 */
594static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
595 size_t frame_size)
596{
597 unsigned long sp;
598
599 /* Default to using normal stack */
600 sp = regs->regs[29];
601
602 /*
603 * FPU emulator may have it's own trampoline active just
604 * above the user stack, 16-bytes before the next lowest
605 * 16 byte boundary. Try to avoid trashing it.
606 */
607 sp -= 32;
608
609 /* This is the X/Open sanctioned signal stack switching. */
610 if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
611 sp = current->sas_ss_sp + current->sas_ss_size;
612
613 return (void *)((sp - frame_size) & ALMASK);
614}
615
616static inline void setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
617 int signr, sigset_t *set)
618{
619 struct sigframe *frame;
620 int err = 0;
621
622 frame = get_sigframe(ka, regs, sizeof(*frame));
623 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
624 goto give_sigsegv;
625
626 /*
627 * Set up the return code ...
628 *
629 * li v0, __NR_O32_sigreturn
630 * syscall
631 */
632 err |= __put_user(0x24020000 + __NR_O32_sigreturn, frame->sf_code + 0);
633 err |= __put_user(0x0000000c , frame->sf_code + 1);
634 flush_cache_sigtramp((unsigned long) frame->sf_code);
635
636 err |= setup_sigcontext32(regs, &frame->sf_sc);
637 err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set));
638 if (err)
639 goto give_sigsegv;
640
641 /*
642 * Arguments to signal handler:
643 *
644 * a0 = signal number
645 * a1 = 0 (should be cause)
646 * a2 = pointer to struct sigcontext
647 *
648 * $25 and c0_epc point to the signal handler, $29 points to the
649 * struct sigframe.
650 */
651 regs->regs[ 4] = signr;
652 regs->regs[ 5] = 0;
653 regs->regs[ 6] = (unsigned long) &frame->sf_sc;
654 regs->regs[29] = (unsigned long) frame;
655 regs->regs[31] = (unsigned long) frame->sf_code;
656 regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
657
658#if DEBUG_SIG
659 printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n",
660 current->comm, current->pid,
661 frame, regs->cp0_epc, frame->sf_code);
662#endif
663 return;
664
665give_sigsegv:
666 force_sigsegv(signr, current);
667}
668
669static inline void setup_rt_frame(struct k_sigaction * ka,
670 struct pt_regs *regs, int signr,
671 sigset_t *set, siginfo_t *info)
672{
673 struct rt_sigframe32 *frame;
674 int err = 0;
675 s32 sp;
676
677 frame = get_sigframe(ka, regs, sizeof(*frame));
678 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
679 goto give_sigsegv;
680
681 /* Set up to return from userspace. If provided, use a stub already
682 in userspace. */
683 /*
684 * Set up the return code ...
685 *
686 * li v0, __NR_O32_rt_sigreturn
687 * syscall
688 */
689 err |= __put_user(0x24020000 + __NR_O32_rt_sigreturn, frame->rs_code + 0);
690 err |= __put_user(0x0000000c , frame->rs_code + 1);
691 flush_cache_sigtramp((unsigned long) frame->rs_code);
692
693 /* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
694 err |= copy_siginfo_to_user32(&frame->rs_info, info);
695
696 /* Create the ucontext. */
697 err |= __put_user(0, &frame->rs_uc.uc_flags);
698 err |= __put_user(0, &frame->rs_uc.uc_link);
699 sp = (int) (long) current->sas_ss_sp;
700 err |= __put_user(sp,
701 &frame->rs_uc.uc_stack.ss_sp);
702 err |= __put_user(sas_ss_flags(regs->regs[29]),
703 &frame->rs_uc.uc_stack.ss_flags);
704 err |= __put_user(current->sas_ss_size,
705 &frame->rs_uc.uc_stack.ss_size);
706 err |= setup_sigcontext32(regs, &frame->rs_uc.uc_mcontext);
707 err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set));
708
709 if (err)
710 goto give_sigsegv;
711
712 /*
713 * Arguments to signal handler:
714 *
715 * a0 = signal number
716 * a1 = 0 (should be cause)
717 * a2 = pointer to ucontext
718 *
719 * $25 and c0_epc point to the signal handler, $29 points to
720 * the struct rt_sigframe32.
721 */
722 regs->regs[ 4] = signr;
723 regs->regs[ 5] = (unsigned long) &frame->rs_info;
724 regs->regs[ 6] = (unsigned long) &frame->rs_uc;
725 regs->regs[29] = (unsigned long) frame;
726 regs->regs[31] = (unsigned long) frame->rs_code;
727 regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
728
729#if DEBUG_SIG
730 printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n",
731 current->comm, current->pid,
732 frame, regs->cp0_epc, frame->rs_code);
733#endif
734 return;
735
736give_sigsegv:
737 force_sigsegv(signr, current);
738}
739
740static inline void handle_signal(unsigned long sig, siginfo_t *info,
741 struct k_sigaction *ka, sigset_t *oldset, struct pt_regs * regs)
742{
743 switch (regs->regs[0]) {
744 case ERESTART_RESTARTBLOCK:
745 case ERESTARTNOHAND:
746 regs->regs[2] = EINTR;
747 break;
748 case ERESTARTSYS:
749 if(!(ka->sa.sa_flags & SA_RESTART)) {
750 regs->regs[2] = EINTR;
751 break;
752 }
753 /* fallthrough */
754 case ERESTARTNOINTR: /* Userland will reload $v0. */
755 regs->regs[7] = regs->regs[26];
756 regs->cp0_epc -= 8;
757 }
758
759 regs->regs[0] = 0; /* Don't deal with this again. */
760
761 if (ka->sa.sa_flags & SA_SIGINFO)
762 setup_rt_frame(ka, regs, sig, oldset, info);
763 else
764 setup_frame(ka, regs, sig, oldset);
765
Steven Rostedt69be8f12005-08-29 11:44:09 -0400766 spin_lock_irq(&current->sighand->siglock);
767 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
768 if (!(ka->sa.sa_flags & SA_NODEFER))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700769 sigaddset(&current->blocked,sig);
Steven Rostedt69be8f12005-08-29 11:44:09 -0400770 recalc_sigpending();
771 spin_unlock_irq(&current->sighand->siglock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700772}
773
774int do_signal32(sigset_t *oldset, struct pt_regs *regs)
775{
776 struct k_sigaction ka;
777 siginfo_t info;
778 int signr;
779
780 /*
781 * We want the common case to go fast, which is why we may in certain
782 * cases get here from kernel mode. Just return without doing anything
783 * if so.
784 */
785 if (!user_mode(regs))
786 return 1;
787
Nigel Cunningham0e6c1f52005-07-27 11:43:34 -0700788 if (try_to_freeze())
Linus Torvalds1da177e2005-04-16 15:20:36 -0700789 goto no_signal;
790
791 if (!oldset)
792 oldset = &current->blocked;
793
794 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
795 if (signr > 0) {
796 handle_signal(signr, &info, &ka, oldset, regs);
797 return 1;
798 }
799
800no_signal:
801 /*
802 * Who's code doesn't conform to the restartable syscall convention
803 * dies here!!! The li instruction, a single machine instruction,
804 * must directly be followed by the syscall instruction.
805 */
806 if (regs->regs[0]) {
807 if (regs->regs[2] == ERESTARTNOHAND ||
808 regs->regs[2] == ERESTARTSYS ||
809 regs->regs[2] == ERESTARTNOINTR) {
810 regs->regs[7] = regs->regs[26];
811 regs->cp0_epc -= 8;
812 }
813 if (regs->regs[2] == ERESTART_RESTARTBLOCK) {
814 regs->regs[2] = __NR_O32_restart_syscall;
815 regs->regs[7] = regs->regs[26];
816 regs->cp0_epc -= 4;
817 }
818 }
819 return 0;
820}
821
822asmlinkage int sys32_rt_sigaction(int sig, const struct sigaction32 *act,
823 struct sigaction32 *oact,
824 unsigned int sigsetsize)
825{
826 struct k_sigaction new_sa, old_sa;
827 int ret = -EINVAL;
828
829 /* XXX: Don't preclude handling different sized sigset_t's. */
830 if (sigsetsize != sizeof(sigset_t))
831 goto out;
832
833 if (act) {
Ralf Baechle77c728c2005-03-04 19:36:51 +0000834 s32 handler;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700835 int err = 0;
836
837 if (!access_ok(VERIFY_READ, act, sizeof(*act)))
838 return -EFAULT;
Ralf Baechle77c728c2005-03-04 19:36:51 +0000839 err |= __get_user(handler, &act->sa_handler);
840 new_sa.sa.sa_handler = (void*)(s64)handler;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700841 err |= __get_user(new_sa.sa.sa_flags, &act->sa_flags);
842 err |= get_sigset(&new_sa.sa.sa_mask, &act->sa_mask);
843 if (err)
844 return -EFAULT;
845 }
846
847 ret = do_sigaction(sig, act ? &new_sa : NULL, oact ? &old_sa : NULL);
848
849 if (!ret && oact) {
850 int err = 0;
851
852 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
853 return -EFAULT;
854
855 err |= __put_user((u32)(u64)old_sa.sa.sa_handler,
856 &oact->sa_handler);
857 err |= __put_user(old_sa.sa.sa_flags, &oact->sa_flags);
858 err |= put_sigset(&old_sa.sa.sa_mask, &oact->sa_mask);
859 if (err)
860 return -EFAULT;
861 }
862out:
863 return ret;
864}
865
866asmlinkage int sys32_rt_sigprocmask(int how, compat_sigset_t *set,
867 compat_sigset_t *oset, unsigned int sigsetsize)
868{
869 sigset_t old_set, new_set;
870 int ret;
871 mm_segment_t old_fs = get_fs();
872
873 if (set && get_sigset(&new_set, set))
874 return -EFAULT;
875
876 set_fs (KERNEL_DS);
877 ret = sys_rt_sigprocmask(how, set ? &new_set : NULL,
878 oset ? &old_set : NULL, sigsetsize);
879 set_fs (old_fs);
880
881 if (!ret && oset && put_sigset(&old_set, oset))
882 return -EFAULT;
883
884 return ret;
885}
886
887asmlinkage int sys32_rt_sigpending(compat_sigset_t *uset,
888 unsigned int sigsetsize)
889{
890 int ret;
891 sigset_t set;
892 mm_segment_t old_fs = get_fs();
893
894 set_fs (KERNEL_DS);
895 ret = sys_rt_sigpending(&set, sigsetsize);
896 set_fs (old_fs);
897
898 if (!ret && put_sigset(&set, uset))
899 return -EFAULT;
900
901 return ret;
902}
903
904asmlinkage int sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t *uinfo)
905{
906 siginfo_t info;
907 int ret;
908 mm_segment_t old_fs = get_fs();
909
910 if (copy_from_user (&info, uinfo, 3*sizeof(int)) ||
911 copy_from_user (info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE))
912 return -EFAULT;
913 set_fs (KERNEL_DS);
914 ret = sys_rt_sigqueueinfo(pid, sig, &info);
915 set_fs (old_fs);
916 return ret;
917}
Ralf Baechle54f2da72005-02-16 21:21:29 +0000918
919asmlinkage long
920sys32_waitid(int which, compat_pid_t pid,
921 compat_siginfo_t __user *uinfo, int options,
922 struct compat_rusage __user *uru)
923{
924 siginfo_t info;
925 struct rusage ru;
926 long ret;
927 mm_segment_t old_fs = get_fs();
928
929 info.si_signo = 0;
930 set_fs (KERNEL_DS);
931 ret = sys_waitid(which, pid, (siginfo_t __user *) &info, options,
932 uru ? (struct rusage __user *) &ru : NULL);
933 set_fs (old_fs);
934
935 if (ret < 0 || info.si_signo == 0)
936 return ret;
937
938 if (uru && (ret = put_compat_rusage(&ru, uru)))
939 return ret;
940
941 BUG_ON(info.si_code & __SI_MASK);
942 info.si_code |= __SI_CHLD;
943 return copy_siginfo_to_user32(uinfo, &info);
944}