1
2
3
4
5
6
7
8
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/kernel.h>
16#include <linux/signal.h>
17#include <linux/syscalls.h>
18#include <linux/errno.h>
19#include <linux/wait.h>
20#include <linux/ptrace.h>
21#include <linux/suspend.h>
22#include <linux/compiler.h>
23#include <linux/uaccess.h>
24
25#include <asm/abi.h>
26#include <asm/asm.h>
27#include <asm/compat-signal.h>
28#include <linux/bitops.h>
29#include <asm/cacheflush.h>
30#include <asm/sim.h>
31#include <asm/ucontext.h>
32#include <asm/system.h>
33#include <asm/fpu.h>
34#include <asm/war.h>
35#include <asm/vdso.h>
36
37#include "signal-common.h"
38
39static int (*save_fp_context32)(struct sigcontext32 __user *sc);
40static int (*restore_fp_context32)(struct sigcontext32 __user *sc);
41
42extern asmlinkage int _save_fp_context32(struct sigcontext32 __user *sc);
43extern asmlinkage int _restore_fp_context32(struct sigcontext32 __user *sc);
44
45extern asmlinkage int fpu_emulator_save_context32(struct sigcontext32 __user *sc);
46extern asmlinkage int fpu_emulator_restore_context32(struct sigcontext32 __user *sc);
47
48
49
50
51#define __NR_O32_restart_syscall 4253
52
53
54
55typedef unsigned int __sighandler32_t;
56typedef void (*vfptr_t)(void);
57
58struct sigaction32 {
59 unsigned int sa_flags;
60 __sighandler32_t sa_handler;
61 compat_sigset_t sa_mask;
62};
63
64
65typedef struct sigaltstack32 {
66 s32 ss_sp;
67 compat_size_t ss_size;
68 int ss_flags;
69} stack32_t;
70
71struct ucontext32 {
72 u32 uc_flags;
73 s32 uc_link;
74 stack32_t uc_stack;
75 struct sigcontext32 uc_mcontext;
76 compat_sigset_t uc_sigmask;
77};
78
79struct sigframe32 {
80 u32 sf_ass[4];
81 u32 sf_pad[2];
82 struct sigcontext32 sf_sc;
83 compat_sigset_t sf_mask;
84};
85
86struct rt_sigframe32 {
87 u32 rs_ass[4];
88 u32 rs_pad[2];
89 compat_siginfo_t rs_info;
90 struct ucontext32 rs_uc;
91};
92
93
94
95
96static int protected_save_fp_context32(struct sigcontext32 __user *sc)
97{
98 int err;
99 while (1) {
100 lock_fpu_owner();
101 own_fpu_inatomic(1);
102 err = save_fp_context32(sc);
103 unlock_fpu_owner();
104 if (likely(!err))
105 break;
106
107 err = __put_user(0, &sc->sc_fpregs[0]) |
108 __put_user(0, &sc->sc_fpregs[31]) |
109 __put_user(0, &sc->sc_fpc_csr);
110 if (err)
111 break;
112 }
113 return err;
114}
115
116static int protected_restore_fp_context32(struct sigcontext32 __user *sc)
117{
118 int err, tmp __maybe_unused;
119 while (1) {
120 lock_fpu_owner();
121 own_fpu_inatomic(0);
122 err = restore_fp_context32(sc);
123 unlock_fpu_owner();
124 if (likely(!err))
125 break;
126
127 err = __get_user(tmp, &sc->sc_fpregs[0]) |
128 __get_user(tmp, &sc->sc_fpregs[31]) |
129 __get_user(tmp, &sc->sc_fpc_csr);
130 if (err)
131 break;
132 }
133 return err;
134}
135
136static int setup_sigcontext32(struct pt_regs *regs,
137 struct sigcontext32 __user *sc)
138{
139 int err = 0;
140 int i;
141 u32 used_math;
142
143 err |= __put_user(regs->cp0_epc, &sc->sc_pc);
144
145 err |= __put_user(0, &sc->sc_regs[0]);
146 for (i = 1; i < 32; i++)
147 err |= __put_user(regs->regs[i], &sc->sc_regs[i]);
148
149 err |= __put_user(regs->hi, &sc->sc_mdhi);
150 err |= __put_user(regs->lo, &sc->sc_mdlo);
151 if (cpu_has_dsp) {
152 err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
153 err |= __put_user(mfhi1(), &sc->sc_hi1);
154 err |= __put_user(mflo1(), &sc->sc_lo1);
155 err |= __put_user(mfhi2(), &sc->sc_hi2);
156 err |= __put_user(mflo2(), &sc->sc_lo2);
157 err |= __put_user(mfhi3(), &sc->sc_hi3);
158 err |= __put_user(mflo3(), &sc->sc_lo3);
159 }
160
161 used_math = !!used_math();
162 err |= __put_user(used_math, &sc->sc_used_math);
163
164 if (used_math) {
165
166
167
168
169 err |= protected_save_fp_context32(sc);
170 }
171 return err;
172}
173
174static int
175check_and_restore_fp_context32(struct sigcontext32 __user *sc)
176{
177 int err, sig;
178
179 err = sig = fpcsr_pending(&sc->sc_fpc_csr);
180 if (err > 0)
181 err = 0;
182 err |= protected_restore_fp_context32(sc);
183 return err ?: sig;
184}
185
186static int restore_sigcontext32(struct pt_regs *regs,
187 struct sigcontext32 __user *sc)
188{
189 u32 used_math;
190 int err = 0;
191 s32 treg;
192 int i;
193
194
195 current_thread_info()->restart_block.fn = do_no_restart_syscall;
196
197 err |= __get_user(regs->cp0_epc, &sc->sc_pc);
198 err |= __get_user(regs->hi, &sc->sc_mdhi);
199 err |= __get_user(regs->lo, &sc->sc_mdlo);
200 if (cpu_has_dsp) {
201 err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
202 err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
203 err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
204 err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
205 err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
206 err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
207 err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
208 }
209
210 for (i = 1; i < 32; i++)
211 err |= __get_user(regs->regs[i], &sc->sc_regs[i]);
212
213 err |= __get_user(used_math, &sc->sc_used_math);
214 conditional_used_math(used_math);
215
216 if (used_math) {
217
218 if (!err)
219 err = check_and_restore_fp_context32(sc);
220 } else {
221
222 lose_fpu(0);
223 }
224
225 return err;
226}
227
228
229
230
231extern void __put_sigset_unknown_nsig(void);
232extern void __get_sigset_unknown_nsig(void);
233
234static inline int put_sigset(const sigset_t *kbuf, compat_sigset_t __user *ubuf)
235{
236 int err = 0;
237
238 if (!access_ok(VERIFY_WRITE, ubuf, sizeof(*ubuf)))
239 return -EFAULT;
240
241 switch (_NSIG_WORDS) {
242 default:
243 __put_sigset_unknown_nsig();
244 case 2:
245 err |= __put_user(kbuf->sig[1] >> 32, &ubuf->sig[3]);
246 err |= __put_user(kbuf->sig[1] & 0xffffffff, &ubuf->sig[2]);
247 case 1:
248 err |= __put_user(kbuf->sig[0] >> 32, &ubuf->sig[1]);
249 err |= __put_user(kbuf->sig[0] & 0xffffffff, &ubuf->sig[0]);
250 }
251
252 return err;
253}
254
255static inline int get_sigset(sigset_t *kbuf, const compat_sigset_t __user *ubuf)
256{
257 int err = 0;
258 unsigned long sig[4];
259
260 if (!access_ok(VERIFY_READ, ubuf, sizeof(*ubuf)))
261 return -EFAULT;
262
263 switch (_NSIG_WORDS) {
264 default:
265 __get_sigset_unknown_nsig();
266 case 2:
267 err |= __get_user(sig[3], &ubuf->sig[3]);
268 err |= __get_user(sig[2], &ubuf->sig[2]);
269 kbuf->sig[1] = sig[2] | (sig[3] << 32);
270 case 1:
271 err |= __get_user(sig[1], &ubuf->sig[1]);
272 err |= __get_user(sig[0], &ubuf->sig[0]);
273 kbuf->sig[0] = sig[0] | (sig[1] << 32);
274 }
275
276 return err;
277}
278
279
280
281
282
283asmlinkage int sys32_sigsuspend(nabi_no_regargs struct pt_regs regs)
284{
285 compat_sigset_t __user *uset;
286 sigset_t newset;
287
288 uset = (compat_sigset_t __user *) regs.regs[4];
289 if (get_sigset(&newset, uset))
290 return -EFAULT;
291 sigdelsetmask(&newset, ~_BLOCKABLE);
292
293 spin_lock_irq(¤t->sighand->siglock);
294 current->saved_sigmask = current->blocked;
295 current->blocked = newset;
296 recalc_sigpending();
297 spin_unlock_irq(¤t->sighand->siglock);
298
299 current->state = TASK_INTERRUPTIBLE;
300 schedule();
301 set_thread_flag(TIF_RESTORE_SIGMASK);
302 return -ERESTARTNOHAND;
303}
304
305asmlinkage int sys32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
306{
307 compat_sigset_t __user *uset;
308 sigset_t newset;
309 size_t sigsetsize;
310
311
312 sigsetsize = regs.regs[5];
313 if (sigsetsize != sizeof(compat_sigset_t))
314 return -EINVAL;
315
316 uset = (compat_sigset_t __user *) regs.regs[4];
317 if (get_sigset(&newset, uset))
318 return -EFAULT;
319 sigdelsetmask(&newset, ~_BLOCKABLE);
320
321 spin_lock_irq(¤t->sighand->siglock);
322 current->saved_sigmask = current->blocked;
323 current->blocked = newset;
324 recalc_sigpending();
325 spin_unlock_irq(¤t->sighand->siglock);
326
327 current->state = TASK_INTERRUPTIBLE;
328 schedule();
329 set_thread_flag(TIF_RESTORE_SIGMASK);
330 return -ERESTARTNOHAND;
331}
332
333SYSCALL_DEFINE3(32_sigaction, long, sig, const struct sigaction32 __user *, act,
334 struct sigaction32 __user *, oact)
335{
336 struct k_sigaction new_ka, old_ka;
337 int ret;
338 int err = 0;
339
340 if (act) {
341 old_sigset_t mask;
342 s32 handler;
343
344 if (!access_ok(VERIFY_READ, act, sizeof(*act)))
345 return -EFAULT;
346 err |= __get_user(handler, &act->sa_handler);
347 new_ka.sa.sa_handler = (void __user *)(s64)handler;
348 err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
349 err |= __get_user(mask, &act->sa_mask.sig[0]);
350 if (err)
351 return -EFAULT;
352
353 siginitset(&new_ka.sa.sa_mask, mask);
354 }
355
356 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
357
358 if (!ret && oact) {
359 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
360 return -EFAULT;
361 err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
362 err |= __put_user((u32)(u64)old_ka.sa.sa_handler,
363 &oact->sa_handler);
364 err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
365 err |= __put_user(0, &oact->sa_mask.sig[1]);
366 err |= __put_user(0, &oact->sa_mask.sig[2]);
367 err |= __put_user(0, &oact->sa_mask.sig[3]);
368 if (err)
369 return -EFAULT;
370 }
371
372 return ret;
373}
374
375asmlinkage int sys32_sigaltstack(nabi_no_regargs struct pt_regs regs)
376{
377 const stack32_t __user *uss = (const stack32_t __user *) regs.regs[4];
378 stack32_t __user *uoss = (stack32_t __user *) regs.regs[5];
379 unsigned long usp = regs.regs[29];
380 stack_t kss, koss;
381 int ret, err = 0;
382 mm_segment_t old_fs = get_fs();
383 s32 sp;
384
385 if (uss) {
386 if (!access_ok(VERIFY_READ, uss, sizeof(*uss)))
387 return -EFAULT;
388 err |= __get_user(sp, &uss->ss_sp);
389 kss.ss_sp = (void __user *) (long) sp;
390 err |= __get_user(kss.ss_size, &uss->ss_size);
391 err |= __get_user(kss.ss_flags, &uss->ss_flags);
392 if (err)
393 return -EFAULT;
394 }
395
396 set_fs(KERNEL_DS);
397 ret = do_sigaltstack(uss ? (stack_t __user *)&kss : NULL,
398 uoss ? (stack_t __user *)&koss : NULL, usp);
399 set_fs(old_fs);
400
401 if (!ret && uoss) {
402 if (!access_ok(VERIFY_WRITE, uoss, sizeof(*uoss)))
403 return -EFAULT;
404 sp = (int) (unsigned long) koss.ss_sp;
405 err |= __put_user(sp, &uoss->ss_sp);
406 err |= __put_user(koss.ss_size, &uoss->ss_size);
407 err |= __put_user(koss.ss_flags, &uoss->ss_flags);
408 if (err)
409 return -EFAULT;
410 }
411 return ret;
412}
413
414int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
415{
416 int err;
417
418 if (!access_ok (VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
419 return -EFAULT;
420
421
422
423
424
425
426
427
428 err = __put_user(from->si_signo, &to->si_signo);
429 err |= __put_user(from->si_errno, &to->si_errno);
430 err |= __put_user((short)from->si_code, &to->si_code);
431 if (from->si_code < 0)
432 err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
433 else {
434 switch (from->si_code >> 16) {
435 case __SI_TIMER >> 16:
436 err |= __put_user(from->si_tid, &to->si_tid);
437 err |= __put_user(from->si_overrun, &to->si_overrun);
438 err |= __put_user(from->si_int, &to->si_int);
439 break;
440 case __SI_CHLD >> 16:
441 err |= __put_user(from->si_utime, &to->si_utime);
442 err |= __put_user(from->si_stime, &to->si_stime);
443 err |= __put_user(from->si_status, &to->si_status);
444 default:
445 err |= __put_user(from->si_pid, &to->si_pid);
446 err |= __put_user(from->si_uid, &to->si_uid);
447 break;
448 case __SI_FAULT >> 16:
449 err |= __put_user((unsigned long)from->si_addr, &to->si_addr);
450 break;
451 case __SI_POLL >> 16:
452 err |= __put_user(from->si_band, &to->si_band);
453 err |= __put_user(from->si_fd, &to->si_fd);
454 break;
455 case __SI_RT >> 16:
456 case __SI_MESGQ >> 16:
457 err |= __put_user(from->si_pid, &to->si_pid);
458 err |= __put_user(from->si_uid, &to->si_uid);
459 err |= __put_user(from->si_int, &to->si_int);
460 break;
461 }
462 }
463 return err;
464}
465
466int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
467{
468 memset(to, 0, sizeof *to);
469
470 if (copy_from_user(to, from, 3*sizeof(int)) ||
471 copy_from_user(to->_sifields._pad,
472 from->_sifields._pad, SI_PAD_SIZE32))
473 return -EFAULT;
474
475 return 0;
476}
477
478asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
479{
480 struct sigframe32 __user *frame;
481 sigset_t blocked;
482 int sig;
483
484 frame = (struct sigframe32 __user *) regs.regs[29];
485 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
486 goto badframe;
487 if (__copy_conv_sigset_from_user(&blocked, &frame->sf_mask))
488 goto badframe;
489
490 sigdelsetmask(&blocked, ~_BLOCKABLE);
491 spin_lock_irq(¤t->sighand->siglock);
492 current->blocked = blocked;
493 recalc_sigpending();
494 spin_unlock_irq(¤t->sighand->siglock);
495
496 sig = restore_sigcontext32(®s, &frame->sf_sc);
497 if (sig < 0)
498 goto badframe;
499 else if (sig)
500 force_sig(sig, current);
501
502
503
504
505 __asm__ __volatile__(
506 "move\t$29, %0\n\t"
507 "j\tsyscall_exit"
508 :
509 :"r" (®s));
510
511
512badframe:
513 force_sig(SIGSEGV, current);
514}
515
516asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
517{
518 struct rt_sigframe32 __user *frame;
519 mm_segment_t old_fs;
520 sigset_t set;
521 stack_t st;
522 s32 sp;
523 int sig;
524
525 frame = (struct rt_sigframe32 __user *) regs.regs[29];
526 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
527 goto badframe;
528 if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask))
529 goto badframe;
530
531 sigdelsetmask(&set, ~_BLOCKABLE);
532 spin_lock_irq(¤t->sighand->siglock);
533 current->blocked = set;
534 recalc_sigpending();
535 spin_unlock_irq(¤t->sighand->siglock);
536
537 sig = restore_sigcontext32(®s, &frame->rs_uc.uc_mcontext);
538 if (sig < 0)
539 goto badframe;
540 else if (sig)
541 force_sig(sig, current);
542
543
544 if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp))
545 goto badframe;
546 st.ss_sp = (void __user *)(long) sp;
547 if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size))
548 goto badframe;
549 if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags))
550 goto badframe;
551
552
553
554 old_fs = get_fs();
555 set_fs(KERNEL_DS);
556 do_sigaltstack((stack_t __user *)&st, NULL, regs.regs[29]);
557 set_fs(old_fs);
558
559
560
561
562 __asm__ __volatile__(
563 "move\t$29, %0\n\t"
564 "j\tsyscall_exit"
565 :
566 :"r" (®s));
567
568
569badframe:
570 force_sig(SIGSEGV, current);
571}
572
573static int setup_frame_32(void *sig_return, struct k_sigaction *ka,
574 struct pt_regs *regs, int signr, sigset_t *set)
575{
576 struct sigframe32 __user *frame;
577 int err = 0;
578
579 frame = get_sigframe(ka, regs, sizeof(*frame));
580 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
581 goto give_sigsegv;
582
583 err |= setup_sigcontext32(regs, &frame->sf_sc);
584 err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
585
586 if (err)
587 goto give_sigsegv;
588
589
590
591
592
593
594
595
596
597
598
599 regs->regs[ 4] = signr;
600 regs->regs[ 5] = 0;
601 regs->regs[ 6] = (unsigned long) &frame->sf_sc;
602 regs->regs[29] = (unsigned long) frame;
603 regs->regs[31] = (unsigned long) sig_return;
604 regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
605
606 DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
607 current->comm, current->pid,
608 frame, regs->cp0_epc, regs->regs[31]);
609
610 return 0;
611
612give_sigsegv:
613 force_sigsegv(signr, current);
614 return -EFAULT;
615}
616
617static int setup_rt_frame_32(void *sig_return, struct k_sigaction *ka,
618 struct pt_regs *regs, int signr, sigset_t *set,
619 siginfo_t *info)
620{
621 struct rt_sigframe32 __user *frame;
622 int err = 0;
623 s32 sp;
624
625 frame = get_sigframe(ka, regs, sizeof(*frame));
626 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
627 goto give_sigsegv;
628
629
630 err |= copy_siginfo_to_user32(&frame->rs_info, info);
631
632
633 err |= __put_user(0, &frame->rs_uc.uc_flags);
634 err |= __put_user(0, &frame->rs_uc.uc_link);
635 sp = (int) (long) current->sas_ss_sp;
636 err |= __put_user(sp,
637 &frame->rs_uc.uc_stack.ss_sp);
638 err |= __put_user(sas_ss_flags(regs->regs[29]),
639 &frame->rs_uc.uc_stack.ss_flags);
640 err |= __put_user(current->sas_ss_size,
641 &frame->rs_uc.uc_stack.ss_size);
642 err |= setup_sigcontext32(regs, &frame->rs_uc.uc_mcontext);
643 err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
644
645 if (err)
646 goto give_sigsegv;
647
648
649
650
651
652
653
654
655
656
657
658 regs->regs[ 4] = signr;
659 regs->regs[ 5] = (unsigned long) &frame->rs_info;
660 regs->regs[ 6] = (unsigned long) &frame->rs_uc;
661 regs->regs[29] = (unsigned long) frame;
662 regs->regs[31] = (unsigned long) sig_return;
663 regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
664
665 DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
666 current->comm, current->pid,
667 frame, regs->cp0_epc, regs->regs[31]);
668
669 return 0;
670
671give_sigsegv:
672 force_sigsegv(signr, current);
673 return -EFAULT;
674}
675
676
677
678
679struct mips_abi mips_abi_32 = {
680 .setup_frame = setup_frame_32,
681 .signal_return_offset =
682 offsetof(struct mips_vdso, o32_signal_trampoline),
683 .setup_rt_frame = setup_rt_frame_32,
684 .rt_signal_return_offset =
685 offsetof(struct mips_vdso, o32_rt_signal_trampoline),
686 .restart = __NR_O32_restart_syscall
687};
688
689SYSCALL_DEFINE4(32_rt_sigaction, int, sig,
690 const struct sigaction32 __user *, act,
691 struct sigaction32 __user *, oact, unsigned int, sigsetsize)
692{
693 struct k_sigaction new_sa, old_sa;
694 int ret = -EINVAL;
695
696
697 if (sigsetsize != sizeof(sigset_t))
698 goto out;
699
700 if (act) {
701 s32 handler;
702 int err = 0;
703
704 if (!access_ok(VERIFY_READ, act, sizeof(*act)))
705 return -EFAULT;
706 err |= __get_user(handler, &act->sa_handler);
707 new_sa.sa.sa_handler = (void __user *)(s64)handler;
708 err |= __get_user(new_sa.sa.sa_flags, &act->sa_flags);
709 err |= get_sigset(&new_sa.sa.sa_mask, &act->sa_mask);
710 if (err)
711 return -EFAULT;
712 }
713
714 ret = do_sigaction(sig, act ? &new_sa : NULL, oact ? &old_sa : NULL);
715
716 if (!ret && oact) {
717 int err = 0;
718
719 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
720 return -EFAULT;
721
722 err |= __put_user((u32)(u64)old_sa.sa.sa_handler,
723 &oact->sa_handler);
724 err |= __put_user(old_sa.sa.sa_flags, &oact->sa_flags);
725 err |= put_sigset(&old_sa.sa.sa_mask, &oact->sa_mask);
726 if (err)
727 return -EFAULT;
728 }
729out:
730 return ret;
731}
732
733SYSCALL_DEFINE4(32_rt_sigprocmask, int, how, compat_sigset_t __user *, set,
734 compat_sigset_t __user *, oset, unsigned int, sigsetsize)
735{
736 sigset_t old_set, new_set;
737 int ret;
738 mm_segment_t old_fs = get_fs();
739
740 if (set && get_sigset(&new_set, set))
741 return -EFAULT;
742
743 set_fs(KERNEL_DS);
744 ret = sys_rt_sigprocmask(how, set ? (sigset_t __user *)&new_set : NULL,
745 oset ? (sigset_t __user *)&old_set : NULL,
746 sigsetsize);
747 set_fs(old_fs);
748
749 if (!ret && oset && put_sigset(&old_set, oset))
750 return -EFAULT;
751
752 return ret;
753}
754
755SYSCALL_DEFINE2(32_rt_sigpending, compat_sigset_t __user *, uset,
756 unsigned int, sigsetsize)
757{
758 int ret;
759 sigset_t set;
760 mm_segment_t old_fs = get_fs();
761
762 set_fs(KERNEL_DS);
763 ret = sys_rt_sigpending((sigset_t __user *)&set, sigsetsize);
764 set_fs(old_fs);
765
766 if (!ret && put_sigset(&set, uset))
767 return -EFAULT;
768
769 return ret;
770}
771
772SYSCALL_DEFINE3(32_rt_sigqueueinfo, int, pid, int, sig,
773 compat_siginfo_t __user *, uinfo)
774{
775 siginfo_t info;
776 int ret;
777 mm_segment_t old_fs = get_fs();
778
779 if (copy_from_user(&info, uinfo, 3*sizeof(int)) ||
780 copy_from_user(info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE))
781 return -EFAULT;
782 set_fs(KERNEL_DS);
783 ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *)&info);
784 set_fs(old_fs);
785 return ret;
786}
787
788SYSCALL_DEFINE5(32_waitid, int, which, compat_pid_t, pid,
789 compat_siginfo_t __user *, uinfo, int, options,
790 struct compat_rusage __user *, uru)
791{
792 siginfo_t info;
793 struct rusage ru;
794 long ret;
795 mm_segment_t old_fs = get_fs();
796
797 info.si_signo = 0;
798 set_fs(KERNEL_DS);
799 ret = sys_waitid(which, pid, (siginfo_t __user *) &info, options,
800 uru ? (struct rusage __user *) &ru : NULL);
801 set_fs(old_fs);
802
803 if (ret < 0 || info.si_signo == 0)
804 return ret;
805
806 if (uru && (ret = put_compat_rusage(&ru, uru)))
807 return ret;
808
809 BUG_ON(info.si_code & __SI_MASK);
810 info.si_code |= __SI_CHLD;
811 return copy_siginfo_to_user32(uinfo, &info);
812}
813
814static int signal32_init(void)
815{
816 if (cpu_has_fpu) {
817 save_fp_context32 = _save_fp_context32;
818 restore_fp_context32 = _restore_fp_context32;
819 } else {
820 save_fp_context32 = fpu_emulator_save_context32;
821 restore_fp_context32 = fpu_emulator_restore_context32;
822 }
823
824 return 0;
825}
826
827arch_initcall(signal32_init);
828