Pull bugzilla-7570 into release branch
[deliverable/linux.git] / arch / mips / kernel / signal32.c
1 /*
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, 2006 Ralf Baechle
8 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
9 */
10 #include <linux/cache.h>
11 #include <linux/compat.h>
12 #include <linux/sched.h>
13 #include <linux/mm.h>
14 #include <linux/smp.h>
15 #include <linux/smp_lock.h>
16 #include <linux/kernel.h>
17 #include <linux/signal.h>
18 #include <linux/syscalls.h>
19 #include <linux/errno.h>
20 #include <linux/wait.h>
21 #include <linux/ptrace.h>
22 #include <linux/compat.h>
23 #include <linux/suspend.h>
24 #include <linux/compiler.h>
25
26 #include <asm/abi.h>
27 #include <asm/asm.h>
28 #include <asm/compat-signal.h>
29 #include <linux/bitops.h>
30 #include <asm/cacheflush.h>
31 #include <asm/sim.h>
32 #include <asm/uaccess.h>
33 #include <asm/ucontext.h>
34 #include <asm/system.h>
35 #include <asm/fpu.h>
36 #include <asm/war.h>
37
38 #include "signal-common.h"
39
40 #define SI_PAD_SIZE32 ((SI_MAX_SIZE/sizeof(int)) - 3)
41
42 typedef struct compat_siginfo {
43 int si_signo;
44 int si_code;
45 int si_errno;
46
47 union {
48 int _pad[SI_PAD_SIZE32];
49
50 /* kill() */
51 struct {
52 compat_pid_t _pid; /* sender's pid */
53 compat_uid_t _uid; /* sender's uid */
54 } _kill;
55
56 /* SIGCHLD */
57 struct {
58 compat_pid_t _pid; /* which child */
59 compat_uid_t _uid; /* sender's uid */
60 int _status; /* exit code */
61 compat_clock_t _utime;
62 compat_clock_t _stime;
63 } _sigchld;
64
65 /* IRIX SIGCHLD */
66 struct {
67 compat_pid_t _pid; /* which child */
68 compat_clock_t _utime;
69 int _status; /* exit code */
70 compat_clock_t _stime;
71 } _irix_sigchld;
72
73 /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
74 struct {
75 s32 _addr; /* faulting insn/memory ref. */
76 } _sigfault;
77
78 /* SIGPOLL, SIGXFSZ (To do ...) */
79 struct {
80 int _band; /* POLL_IN, POLL_OUT, POLL_MSG */
81 int _fd;
82 } _sigpoll;
83
84 /* POSIX.1b timers */
85 struct {
86 timer_t _tid; /* timer id */
87 int _overrun; /* overrun count */
88 compat_sigval_t _sigval;/* same as below */
89 int _sys_private; /* not to be passed to user */
90 } _timer;
91
92 /* POSIX.1b signals */
93 struct {
94 compat_pid_t _pid; /* sender's pid */
95 compat_uid_t _uid; /* sender's uid */
96 compat_sigval_t _sigval;
97 } _rt;
98
99 } _sifields;
100 } compat_siginfo_t;
101
102 /*
103 * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
104 */
105 #define __NR_O32_sigreturn 4119
106 #define __NR_O32_rt_sigreturn 4193
107 #define __NR_O32_restart_syscall 4253
108
109 /* 32-bit compatibility types */
110
111 typedef unsigned int __sighandler32_t;
112 typedef void (*vfptr_t)(void);
113
114 struct sigaction32 {
115 unsigned int sa_flags;
116 __sighandler32_t sa_handler;
117 compat_sigset_t sa_mask;
118 };
119
120 /* IRIX compatible stack_t */
121 typedef struct sigaltstack32 {
122 s32 ss_sp;
123 compat_size_t ss_size;
124 int ss_flags;
125 } stack32_t;
126
127 struct ucontext32 {
128 u32 uc_flags;
129 s32 uc_link;
130 stack32_t uc_stack;
131 struct sigcontext32 uc_mcontext;
132 compat_sigset_t uc_sigmask; /* mask last for extensibility */
133 };
134
135 /*
136 * Horribly complicated - with the bloody RM9000 workarounds enabled
137 * the signal trampolines is moving to the end of the structure so we can
138 * increase the alignment without breaking software compatibility.
139 */
140 #if ICACHE_REFILLS_WORKAROUND_WAR == 0
141
142 struct sigframe32 {
143 u32 sf_ass[4]; /* argument save space for o32 */
144 u32 sf_code[2]; /* signal trampoline */
145 struct sigcontext32 sf_sc;
146 compat_sigset_t sf_mask;
147 };
148
149 struct rt_sigframe32 {
150 u32 rs_ass[4]; /* argument save space for o32 */
151 u32 rs_code[2]; /* signal trampoline */
152 compat_siginfo_t rs_info;
153 struct ucontext32 rs_uc;
154 };
155
156 #else /* ICACHE_REFILLS_WORKAROUND_WAR */
157
158 struct sigframe32 {
159 u32 sf_ass[4]; /* argument save space for o32 */
160 u32 sf_pad[2];
161 struct sigcontext32 sf_sc; /* hw context */
162 compat_sigset_t sf_mask;
163 u32 sf_code[8] ____cacheline_aligned; /* signal trampoline */
164 };
165
166 struct rt_sigframe32 {
167 u32 rs_ass[4]; /* argument save space for o32 */
168 u32 rs_pad[2];
169 compat_siginfo_t rs_info;
170 struct ucontext32 rs_uc;
171 u32 rs_code[8] __attribute__((aligned(32))); /* signal trampoline */
172 };
173
174 #endif /* !ICACHE_REFILLS_WORKAROUND_WAR */
175
176 /*
177 * sigcontext handlers
178 */
179 static int setup_sigcontext32(struct pt_regs *regs,
180 struct sigcontext32 __user *sc)
181 {
182 int err = 0;
183 int i;
184
185 err |= __put_user(regs->cp0_epc, &sc->sc_pc);
186
187 err |= __put_user(0, &sc->sc_regs[0]);
188 for (i = 1; i < 32; i++)
189 err |= __put_user(regs->regs[i], &sc->sc_regs[i]);
190
191 err |= __put_user(regs->hi, &sc->sc_mdhi);
192 err |= __put_user(regs->lo, &sc->sc_mdlo);
193 if (cpu_has_dsp) {
194 err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
195 err |= __put_user(mfhi1(), &sc->sc_hi1);
196 err |= __put_user(mflo1(), &sc->sc_lo1);
197 err |= __put_user(mfhi2(), &sc->sc_hi2);
198 err |= __put_user(mflo2(), &sc->sc_lo2);
199 err |= __put_user(mfhi3(), &sc->sc_hi3);
200 err |= __put_user(mflo3(), &sc->sc_lo3);
201 }
202
203 err |= __put_user(!!used_math(), &sc->sc_used_math);
204
205 if (used_math()) {
206 /*
207 * Save FPU state to signal context. Signal handler
208 * will "inherit" current FPU state.
209 */
210 preempt_disable();
211
212 if (!is_fpu_owner()) {
213 own_fpu();
214 restore_fp(current);
215 }
216 err |= save_fp_context32(sc);
217
218 preempt_enable();
219 }
220 return err;
221 }
222
223 static int restore_sigcontext32(struct pt_regs *regs,
224 struct sigcontext32 __user *sc)
225 {
226 u32 used_math;
227 int err = 0;
228 s32 treg;
229 int i;
230
231 /* Always make any pending restarted system calls return -EINTR */
232 current_thread_info()->restart_block.fn = do_no_restart_syscall;
233
234 err |= __get_user(regs->cp0_epc, &sc->sc_pc);
235 err |= __get_user(regs->hi, &sc->sc_mdhi);
236 err |= __get_user(regs->lo, &sc->sc_mdlo);
237 if (cpu_has_dsp) {
238 err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
239 err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
240 err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
241 err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
242 err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
243 err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
244 err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
245 }
246
247 for (i = 1; i < 32; i++)
248 err |= __get_user(regs->regs[i], &sc->sc_regs[i]);
249
250 err |= __get_user(used_math, &sc->sc_used_math);
251 conditional_used_math(used_math);
252
253 preempt_disable();
254
255 if (used_math()) {
256 /* restore fpu context if we have used it before */
257 own_fpu();
258 err |= restore_fp_context32(sc);
259 } else {
260 /* signal handler may have used FPU. Give it up. */
261 lose_fpu();
262 }
263
264 preempt_enable();
265
266 return err;
267 }
268
269 /*
270 *
271 */
272 extern void __put_sigset_unknown_nsig(void);
273 extern void __get_sigset_unknown_nsig(void);
274
275 static inline int put_sigset(const sigset_t *kbuf, compat_sigset_t __user *ubuf)
276 {
277 int err = 0;
278
279 if (!access_ok(VERIFY_WRITE, ubuf, sizeof(*ubuf)))
280 return -EFAULT;
281
282 switch (_NSIG_WORDS) {
283 default:
284 __put_sigset_unknown_nsig();
285 case 2:
286 err |= __put_user (kbuf->sig[1] >> 32, &ubuf->sig[3]);
287 err |= __put_user (kbuf->sig[1] & 0xffffffff, &ubuf->sig[2]);
288 case 1:
289 err |= __put_user (kbuf->sig[0] >> 32, &ubuf->sig[1]);
290 err |= __put_user (kbuf->sig[0] & 0xffffffff, &ubuf->sig[0]);
291 }
292
293 return err;
294 }
295
296 static inline int get_sigset(sigset_t *kbuf, const compat_sigset_t __user *ubuf)
297 {
298 int err = 0;
299 unsigned long sig[4];
300
301 if (!access_ok(VERIFY_READ, ubuf, sizeof(*ubuf)))
302 return -EFAULT;
303
304 switch (_NSIG_WORDS) {
305 default:
306 __get_sigset_unknown_nsig();
307 case 2:
308 err |= __get_user (sig[3], &ubuf->sig[3]);
309 err |= __get_user (sig[2], &ubuf->sig[2]);
310 kbuf->sig[1] = sig[2] | (sig[3] << 32);
311 case 1:
312 err |= __get_user (sig[1], &ubuf->sig[1]);
313 err |= __get_user (sig[0], &ubuf->sig[0]);
314 kbuf->sig[0] = sig[0] | (sig[1] << 32);
315 }
316
317 return err;
318 }
319
320 /*
321 * Atomically swap in the new signal mask, and wait for a signal.
322 */
323
324 asmlinkage int sys32_sigsuspend(nabi_no_regargs struct pt_regs regs)
325 {
326 compat_sigset_t __user *uset;
327 sigset_t newset;
328
329 uset = (compat_sigset_t __user *) regs.regs[4];
330 if (get_sigset(&newset, uset))
331 return -EFAULT;
332 sigdelsetmask(&newset, ~_BLOCKABLE);
333
334 spin_lock_irq(&current->sighand->siglock);
335 current->saved_sigmask = current->blocked;
336 current->blocked = newset;
337 recalc_sigpending();
338 spin_unlock_irq(&current->sighand->siglock);
339
340 current->state = TASK_INTERRUPTIBLE;
341 schedule();
342 set_thread_flag(TIF_RESTORE_SIGMASK);
343 return -ERESTARTNOHAND;
344 }
345
346 asmlinkage int sys32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
347 {
348 compat_sigset_t __user *uset;
349 sigset_t newset;
350 size_t sigsetsize;
351
352 /* XXX Don't preclude handling different sized sigset_t's. */
353 sigsetsize = regs.regs[5];
354 if (sigsetsize != sizeof(compat_sigset_t))
355 return -EINVAL;
356
357 uset = (compat_sigset_t __user *) regs.regs[4];
358 if (get_sigset(&newset, uset))
359 return -EFAULT;
360 sigdelsetmask(&newset, ~_BLOCKABLE);
361
362 spin_lock_irq(&current->sighand->siglock);
363 current->saved_sigmask = current->blocked;
364 current->blocked = newset;
365 recalc_sigpending();
366 spin_unlock_irq(&current->sighand->siglock);
367
368 current->state = TASK_INTERRUPTIBLE;
369 schedule();
370 set_thread_flag(TIF_RESTORE_SIGMASK);
371 return -ERESTARTNOHAND;
372 }
373
374 asmlinkage int sys32_sigaction(int sig, const struct sigaction32 __user *act,
375 struct sigaction32 __user *oact)
376 {
377 struct k_sigaction new_ka, old_ka;
378 int ret;
379 int err = 0;
380
381 if (act) {
382 old_sigset_t mask;
383 s32 handler;
384
385 if (!access_ok(VERIFY_READ, act, sizeof(*act)))
386 return -EFAULT;
387 err |= __get_user(handler, &act->sa_handler);
388 new_ka.sa.sa_handler = (void __user *)(s64)handler;
389 err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
390 err |= __get_user(mask, &act->sa_mask.sig[0]);
391 if (err)
392 return -EFAULT;
393
394 siginitset(&new_ka.sa.sa_mask, mask);
395 }
396
397 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
398
399 if (!ret && oact) {
400 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
401 return -EFAULT;
402 err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
403 err |= __put_user((u32)(u64)old_ka.sa.sa_handler,
404 &oact->sa_handler);
405 err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
406 err |= __put_user(0, &oact->sa_mask.sig[1]);
407 err |= __put_user(0, &oact->sa_mask.sig[2]);
408 err |= __put_user(0, &oact->sa_mask.sig[3]);
409 if (err)
410 return -EFAULT;
411 }
412
413 return ret;
414 }
415
416 asmlinkage int sys32_sigaltstack(nabi_no_regargs struct pt_regs regs)
417 {
418 const stack32_t __user *uss = (const stack32_t __user *) regs.regs[4];
419 stack32_t __user *uoss = (stack32_t __user *) regs.regs[5];
420 unsigned long usp = regs.regs[29];
421 stack_t kss, koss;
422 int ret, err = 0;
423 mm_segment_t old_fs = get_fs();
424 s32 sp;
425
426 if (uss) {
427 if (!access_ok(VERIFY_READ, uss, sizeof(*uss)))
428 return -EFAULT;
429 err |= __get_user(sp, &uss->ss_sp);
430 kss.ss_sp = (void __user *) (long) sp;
431 err |= __get_user(kss.ss_size, &uss->ss_size);
432 err |= __get_user(kss.ss_flags, &uss->ss_flags);
433 if (err)
434 return -EFAULT;
435 }
436
437 set_fs (KERNEL_DS);
438 ret = do_sigaltstack(uss ? (stack_t __user *)&kss : NULL,
439 uoss ? (stack_t __user *)&koss : NULL, usp);
440 set_fs (old_fs);
441
442 if (!ret && uoss) {
443 if (!access_ok(VERIFY_WRITE, uoss, sizeof(*uoss)))
444 return -EFAULT;
445 sp = (int) (unsigned long) koss.ss_sp;
446 err |= __put_user(sp, &uoss->ss_sp);
447 err |= __put_user(koss.ss_size, &uoss->ss_size);
448 err |= __put_user(koss.ss_flags, &uoss->ss_flags);
449 if (err)
450 return -EFAULT;
451 }
452 return ret;
453 }
454
455 int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
456 {
457 int err;
458
459 if (!access_ok (VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
460 return -EFAULT;
461
462 /* If you change siginfo_t structure, please be sure
463 this code is fixed accordingly.
464 It should never copy any pad contained in the structure
465 to avoid security leaks, but must copy the generic
466 3 ints plus the relevant union member.
467 This routine must convert siginfo from 64bit to 32bit as well
468 at the same time. */
469 err = __put_user(from->si_signo, &to->si_signo);
470 err |= __put_user(from->si_errno, &to->si_errno);
471 err |= __put_user((short)from->si_code, &to->si_code);
472 if (from->si_code < 0)
473 err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
474 else {
475 switch (from->si_code >> 16) {
476 case __SI_TIMER >> 16:
477 err |= __put_user(from->si_tid, &to->si_tid);
478 err |= __put_user(from->si_overrun, &to->si_overrun);
479 err |= __put_user(from->si_int, &to->si_int);
480 break;
481 case __SI_CHLD >> 16:
482 err |= __put_user(from->si_utime, &to->si_utime);
483 err |= __put_user(from->si_stime, &to->si_stime);
484 err |= __put_user(from->si_status, &to->si_status);
485 default:
486 err |= __put_user(from->si_pid, &to->si_pid);
487 err |= __put_user(from->si_uid, &to->si_uid);
488 break;
489 case __SI_FAULT >> 16:
490 err |= __put_user((unsigned long)from->si_addr, &to->si_addr);
491 break;
492 case __SI_POLL >> 16:
493 err |= __put_user(from->si_band, &to->si_band);
494 err |= __put_user(from->si_fd, &to->si_fd);
495 break;
496 case __SI_RT >> 16: /* This is not generated by the kernel as of now. */
497 case __SI_MESGQ >> 16:
498 err |= __put_user(from->si_pid, &to->si_pid);
499 err |= __put_user(from->si_uid, &to->si_uid);
500 err |= __put_user(from->si_int, &to->si_int);
501 break;
502 }
503 }
504 return err;
505 }
506
507 asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
508 {
509 struct sigframe32 __user *frame;
510 sigset_t blocked;
511
512 frame = (struct sigframe32 __user *) regs.regs[29];
513 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
514 goto badframe;
515 if (__copy_conv_sigset_from_user(&blocked, &frame->sf_mask))
516 goto badframe;
517
518 sigdelsetmask(&blocked, ~_BLOCKABLE);
519 spin_lock_irq(&current->sighand->siglock);
520 current->blocked = blocked;
521 recalc_sigpending();
522 spin_unlock_irq(&current->sighand->siglock);
523
524 if (restore_sigcontext32(&regs, &frame->sf_sc))
525 goto badframe;
526
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
537 badframe:
538 force_sig(SIGSEGV, current);
539 }
540
541 asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
542 {
543 struct rt_sigframe32 __user *frame;
544 mm_segment_t old_fs;
545 sigset_t set;
546 stack_t st;
547 s32 sp;
548
549 frame = (struct rt_sigframe32 __user *) regs.regs[29];
550 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
551 goto badframe;
552 if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask))
553 goto badframe;
554
555 sigdelsetmask(&set, ~_BLOCKABLE);
556 spin_lock_irq(&current->sighand->siglock);
557 current->blocked = set;
558 recalc_sigpending();
559 spin_unlock_irq(&current->sighand->siglock);
560
561 if (restore_sigcontext32(&regs, &frame->rs_uc.uc_mcontext))
562 goto badframe;
563
564 /* The ucontext contains a stack32_t, so we must convert! */
565 if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp))
566 goto badframe;
567 st.ss_sp = (void __user *)(long) sp;
568 if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size))
569 goto badframe;
570 if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags))
571 goto badframe;
572
573 /* It is more difficult to avoid calling this function than to
574 call it and ignore errors. */
575 old_fs = get_fs();
576 set_fs (KERNEL_DS);
577 do_sigaltstack((stack_t __user *)&st, NULL, regs.regs[29]);
578 set_fs (old_fs);
579
580 /*
581 * Don't let your children do this ...
582 */
583 __asm__ __volatile__(
584 "move\t$29, %0\n\t"
585 "j\tsyscall_exit"
586 :/* no outputs */
587 :"r" (&regs));
588 /* Unreached */
589
590 badframe:
591 force_sig(SIGSEGV, current);
592 }
593
594 static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
595 int signr, sigset_t *set)
596 {
597 struct sigframe32 __user *frame;
598 int err = 0;
599
600 frame = get_sigframe(ka, regs, sizeof(*frame));
601 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
602 goto give_sigsegv;
603
604 err |= install_sigtramp(frame->sf_code, __NR_O32_sigreturn);
605
606 err |= setup_sigcontext32(regs, &frame->sf_sc);
607 err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
608
609 if (err)
610 goto give_sigsegv;
611
612 /*
613 * Arguments to signal handler:
614 *
615 * a0 = signal number
616 * a1 = 0 (should be cause)
617 * a2 = pointer to struct sigcontext
618 *
619 * $25 and c0_epc point to the signal handler, $29 points to the
620 * struct sigframe.
621 */
622 regs->regs[ 4] = signr;
623 regs->regs[ 5] = 0;
624 regs->regs[ 6] = (unsigned long) &frame->sf_sc;
625 regs->regs[29] = (unsigned long) frame;
626 regs->regs[31] = (unsigned long) frame->sf_code;
627 regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
628
629 DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
630 current->comm, current->pid,
631 frame, regs->cp0_epc, regs->regs[31]);
632
633 return 0;
634
635 give_sigsegv:
636 force_sigsegv(signr, current);
637 return -EFAULT;
638 }
639
640 static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
641 int signr, sigset_t *set, siginfo_t *info)
642 {
643 struct rt_sigframe32 __user *frame;
644 int err = 0;
645 s32 sp;
646
647 frame = get_sigframe(ka, regs, sizeof(*frame));
648 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
649 goto give_sigsegv;
650
651 err |= install_sigtramp(frame->rs_code, __NR_O32_rt_sigreturn);
652
653 /* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
654 err |= copy_siginfo_to_user32(&frame->rs_info, info);
655
656 /* Create the ucontext. */
657 err |= __put_user(0, &frame->rs_uc.uc_flags);
658 err |= __put_user(0, &frame->rs_uc.uc_link);
659 sp = (int) (long) current->sas_ss_sp;
660 err |= __put_user(sp,
661 &frame->rs_uc.uc_stack.ss_sp);
662 err |= __put_user(sas_ss_flags(regs->regs[29]),
663 &frame->rs_uc.uc_stack.ss_flags);
664 err |= __put_user(current->sas_ss_size,
665 &frame->rs_uc.uc_stack.ss_size);
666 err |= setup_sigcontext32(regs, &frame->rs_uc.uc_mcontext);
667 err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
668
669 if (err)
670 goto give_sigsegv;
671
672 /*
673 * Arguments to signal handler:
674 *
675 * a0 = signal number
676 * a1 = 0 (should be cause)
677 * a2 = pointer to ucontext
678 *
679 * $25 and c0_epc point to the signal handler, $29 points to
680 * the struct rt_sigframe32.
681 */
682 regs->regs[ 4] = signr;
683 regs->regs[ 5] = (unsigned long) &frame->rs_info;
684 regs->regs[ 6] = (unsigned long) &frame->rs_uc;
685 regs->regs[29] = (unsigned long) frame;
686 regs->regs[31] = (unsigned long) frame->rs_code;
687 regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
688
689 DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
690 current->comm, current->pid,
691 frame, regs->cp0_epc, regs->regs[31]);
692
693 return 0;
694
695 give_sigsegv:
696 force_sigsegv(signr, current);
697 return -EFAULT;
698 }
699
700 /*
701 * o32 compatibility on 64-bit kernels, without DSP ASE
702 */
703 struct mips_abi mips_abi_32 = {
704 .setup_frame = setup_frame_32,
705 .setup_rt_frame = setup_rt_frame_32,
706 .restart = __NR_O32_restart_syscall
707 };
708
709 asmlinkage int sys32_rt_sigaction(int sig, const struct sigaction32 __user *act,
710 struct sigaction32 __user *oact,
711 unsigned int sigsetsize)
712 {
713 struct k_sigaction new_sa, old_sa;
714 int ret = -EINVAL;
715
716 /* XXX: Don't preclude handling different sized sigset_t's. */
717 if (sigsetsize != sizeof(sigset_t))
718 goto out;
719
720 if (act) {
721 s32 handler;
722 int err = 0;
723
724 if (!access_ok(VERIFY_READ, act, sizeof(*act)))
725 return -EFAULT;
726 err |= __get_user(handler, &act->sa_handler);
727 new_sa.sa.sa_handler = (void __user *)(s64)handler;
728 err |= __get_user(new_sa.sa.sa_flags, &act->sa_flags);
729 err |= get_sigset(&new_sa.sa.sa_mask, &act->sa_mask);
730 if (err)
731 return -EFAULT;
732 }
733
734 ret = do_sigaction(sig, act ? &new_sa : NULL, oact ? &old_sa : NULL);
735
736 if (!ret && oact) {
737 int err = 0;
738
739 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
740 return -EFAULT;
741
742 err |= __put_user((u32)(u64)old_sa.sa.sa_handler,
743 &oact->sa_handler);
744 err |= __put_user(old_sa.sa.sa_flags, &oact->sa_flags);
745 err |= put_sigset(&old_sa.sa.sa_mask, &oact->sa_mask);
746 if (err)
747 return -EFAULT;
748 }
749 out:
750 return ret;
751 }
752
753 asmlinkage int sys32_rt_sigprocmask(int how, compat_sigset_t __user *set,
754 compat_sigset_t __user *oset, unsigned int sigsetsize)
755 {
756 sigset_t old_set, new_set;
757 int ret;
758 mm_segment_t old_fs = get_fs();
759
760 if (set && get_sigset(&new_set, set))
761 return -EFAULT;
762
763 set_fs (KERNEL_DS);
764 ret = sys_rt_sigprocmask(how, set ? (sigset_t __user *)&new_set : NULL,
765 oset ? (sigset_t __user *)&old_set : NULL,
766 sigsetsize);
767 set_fs (old_fs);
768
769 if (!ret && oset && put_sigset(&old_set, oset))
770 return -EFAULT;
771
772 return ret;
773 }
774
775 asmlinkage int sys32_rt_sigpending(compat_sigset_t __user *uset,
776 unsigned int sigsetsize)
777 {
778 int ret;
779 sigset_t set;
780 mm_segment_t old_fs = get_fs();
781
782 set_fs (KERNEL_DS);
783 ret = sys_rt_sigpending((sigset_t __user *)&set, sigsetsize);
784 set_fs (old_fs);
785
786 if (!ret && put_sigset(&set, uset))
787 return -EFAULT;
788
789 return ret;
790 }
791
792 asmlinkage int sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *uinfo)
793 {
794 siginfo_t info;
795 int ret;
796 mm_segment_t old_fs = get_fs();
797
798 if (copy_from_user (&info, uinfo, 3*sizeof(int)) ||
799 copy_from_user (info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE))
800 return -EFAULT;
801 set_fs (KERNEL_DS);
802 ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *)&info);
803 set_fs (old_fs);
804 return ret;
805 }
806
807 asmlinkage long
808 sys32_waitid(int which, compat_pid_t pid,
809 compat_siginfo_t __user *uinfo, int options,
810 struct compat_rusage __user *uru)
811 {
812 siginfo_t info;
813 struct rusage ru;
814 long ret;
815 mm_segment_t old_fs = get_fs();
816
817 info.si_signo = 0;
818 set_fs (KERNEL_DS);
819 ret = sys_waitid(which, pid, (siginfo_t __user *) &info, options,
820 uru ? (struct rusage __user *) &ru : NULL);
821 set_fs (old_fs);
822
823 if (ret < 0 || info.si_signo == 0)
824 return ret;
825
826 if (uru && (ret = put_compat_rusage(&ru, uru)))
827 return ret;
828
829 BUG_ON(info.si_code & __SI_MASK);
830 info.si_code |= __SI_CHLD;
831 return copy_siginfo_to_user32(uinfo, &info);
832 }
This page took 0.07085 seconds and 6 git commands to generate.