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