1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17#include <linux/config.h>
18#include <linux/sched.h>
19#include <linux/mm.h>
20#include <linux/smp.h>
21#include <linux/smp_lock.h>
22#include <linux/kernel.h>
23#include <linux/signal.h>
24#include <linux/syscalls.h>
25#include <linux/errno.h>
26#include <linux/elf.h>
27#include <linux/compat.h>
28#include <linux/ptrace.h>
29#include <asm/ppc32.h>
30#include <asm/uaccess.h>
31#include <asm/ppcdebug.h>
32#include <asm/unistd.h>
33#include <asm/cacheflush.h>
34
35#define DEBUG_SIG 0
36
37#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
38
39#define GP_REGS_SIZE32 min(sizeof(elf_gregset_t32), sizeof(struct pt_regs32))
40
41
42
43
44
45
46
47
48
49
50
51struct sigregs32 {
52 struct mcontext32 mctx;
53
54
55
56
57 int abigap[56];
58};
59
60
61#define tramp mc_pad
62
63
64
65
66
67
68
69
70
71
72
73
74struct rt_sigframe32 {
75 compat_siginfo_t info;
76 struct ucontext32 uc;
77
78
79
80
81 int abigap[56];
82};
83
84
85
86
87
88
89
90
91
92
93
94extern void restore_sigmask(sigset_t *set);
95
96
97
98
99
100static inline void compat_from_sigset(compat_sigset_t *compat, sigset_t *set)
101{
102 switch (_NSIG_WORDS) {
103 case 4: compat->sig[5] = set->sig[3] & 0xffffffffull ;
104 compat->sig[7] = set->sig[3] >> 32;
105 case 3: compat->sig[4] = set->sig[2] & 0xffffffffull ;
106 compat->sig[5] = set->sig[2] >> 32;
107 case 2: compat->sig[2] = set->sig[1] & 0xffffffffull ;
108 compat->sig[3] = set->sig[1] >> 32;
109 case 1: compat->sig[0] = set->sig[0] & 0xffffffffull ;
110 compat->sig[1] = set->sig[0] >> 32;
111 }
112}
113
114static inline void sigset_from_compat(sigset_t *set, compat_sigset_t *compat)
115{
116 switch (_NSIG_WORDS) {
117 case 4: set->sig[3] = compat->sig[6] | (((long)compat->sig[7]) << 32);
118 case 3: set->sig[2] = compat->sig[4] | (((long)compat->sig[5]) << 32);
119 case 2: set->sig[1] = compat->sig[2] | (((long)compat->sig[3]) << 32);
120 case 1: set->sig[0] = compat->sig[0] | (((long)compat->sig[1]) << 32);
121 }
122}
123
124
125
126
127
128
129
130static int save_user_regs(struct pt_regs *regs, struct mcontext32 __user *frame, int sigret)
131{
132 elf_greg_t64 *gregs = (elf_greg_t64 *)regs;
133 int i, err = 0;
134
135
136 flush_fp_to_thread(current);
137
138
139 for (i = 0; i <= PT_RESULT; i ++)
140 err |= __put_user((unsigned int)gregs[i], &frame->mc_gregs[i]);
141 err |= __copy_to_user(&frame->mc_fregs, current->thread.fpr,
142 ELF_NFPREG * sizeof(double));
143 if (err)
144 return 1;
145
146 current->thread.fpscr = 0;
147
148#ifdef CONFIG_ALTIVEC
149
150 if (current->thread.used_vr) {
151 flush_altivec_to_thread(current);
152 if (__copy_to_user(&frame->mc_vregs, current->thread.vr,
153 ELF_NVRREG32 * sizeof(vector128)))
154 return 1;
155
156
157 if (__put_user(regs->msr | MSR_VEC, &frame->mc_gregs[PT_MSR]))
158 return 1;
159 }
160
161
162
163
164
165
166
167 if (__put_user(current->thread.vrsave, (u32 __user *)&frame->mc_vregs[32]))
168 return 1;
169#endif
170
171 if (sigret) {
172
173 if (__put_user(0x38000000UL + sigret, &frame->tramp[0])
174 || __put_user(0x44000002UL, &frame->tramp[1]))
175 return 1;
176 flush_icache_range((unsigned long) &frame->tramp[0],
177 (unsigned long) &frame->tramp[2]);
178 }
179
180 return 0;
181}
182
183
184
185
186
187static long restore_user_regs(struct pt_regs *regs,
188 struct mcontext32 __user *sr, int sig)
189{
190 elf_greg_t64 *gregs = (elf_greg_t64 *)regs;
191 int i;
192 long err = 0;
193 unsigned int save_r2 = 0;
194#ifdef CONFIG_ALTIVEC
195 unsigned long msr;
196#endif
197
198
199
200
201
202 if (!sig)
203 save_r2 = (unsigned int)regs->gpr[2];
204 for (i = 0; i <= PT_RESULT; i++) {
205 if ((i == PT_MSR) || (i == PT_SOFTE))
206 continue;
207 err |= __get_user(gregs[i], &sr->mc_gregs[i]);
208 }
209 if (!sig)
210 regs->gpr[2] = (unsigned long) save_r2;
211 if (err)
212 return 1;
213
214
215
216 regs->msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1);
217 if (__copy_from_user(current->thread.fpr, &sr->mc_fregs,
218 sizeof(sr->mc_fregs)))
219 return 1;
220
221#ifdef CONFIG_ALTIVEC
222
223
224 regs->msr &= ~MSR_VEC;
225 if (!__get_user(msr, &sr->mc_gregs[PT_MSR]) && (msr & MSR_VEC) != 0) {
226
227 if (__copy_from_user(current->thread.vr, &sr->mc_vregs,
228 sizeof(sr->mc_vregs)))
229 return 1;
230 } else if (current->thread.used_vr)
231 memset(current->thread.vr, 0, ELF_NVRREG32 * sizeof(vector128));
232
233
234 if (__get_user(current->thread.vrsave, (u32 __user *)&sr->mc_vregs[32]))
235 return 1;
236#endif
237
238#ifndef CONFIG_SMP
239 preempt_disable();
240 if (last_task_used_math == current)
241 last_task_used_math = NULL;
242 if (last_task_used_altivec == current)
243 last_task_used_altivec = NULL;
244 preempt_enable();
245#endif
246 return 0;
247}
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268long sys32_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6, int p7,
269 struct pt_regs *regs)
270{
271 sigset_t saveset;
272
273 mask &= _BLOCKABLE;
274 spin_lock_irq(¤t->sighand->siglock);
275 saveset = current->blocked;
276 siginitset(¤t->blocked, mask);
277 recalc_sigpending();
278 spin_unlock_irq(¤t->sighand->siglock);
279
280 regs->result = -EINTR;
281 regs->gpr[3] = EINTR;
282 regs->ccr |= 0x10000000;
283 while (1) {
284 current->state = TASK_INTERRUPTIBLE;
285 schedule();
286 if (do_signal32(&saveset, regs))
287
288
289
290
291
292
293 return 0;
294 }
295}
296
297long sys32_sigaction(int sig, struct old_sigaction32 __user *act,
298 struct old_sigaction32 __user *oact)
299{
300 struct k_sigaction new_ka, old_ka;
301 int ret;
302
303 if (sig < 0)
304 sig = -sig;
305
306 if (act) {
307 compat_old_sigset_t mask;
308 compat_uptr_t handler, restorer;
309
310 if (get_user(handler, &act->sa_handler) ||
311 __get_user(restorer, &act->sa_restorer) ||
312 __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
313 __get_user(mask, &act->sa_mask))
314 return -EFAULT;
315 new_ka.sa.sa_handler = compat_ptr(handler);
316 new_ka.sa.sa_restorer = compat_ptr(restorer);
317 siginitset(&new_ka.sa.sa_mask, mask);
318 }
319
320 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
321 if (!ret && oact) {
322 if (put_user((long)old_ka.sa.sa_handler, &oact->sa_handler) ||
323 __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer) ||
324 __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
325 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
326 return -EFAULT;
327 }
328
329 return ret;
330}
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354long sys32_rt_sigaction(int sig, const struct sigaction32 __user *act,
355 struct sigaction32 __user *oact, size_t sigsetsize)
356{
357 struct k_sigaction new_ka, old_ka;
358 int ret;
359 compat_sigset_t set32;
360
361
362 if (sigsetsize != sizeof(compat_sigset_t))
363 return -EINVAL;
364
365 if (act) {
366 compat_uptr_t handler;
367
368 ret = get_user(handler, &act->sa_handler);
369 new_ka.sa.sa_handler = compat_ptr(handler);
370 ret |= __copy_from_user(&set32, &act->sa_mask,
371 sizeof(compat_sigset_t));
372 sigset_from_compat(&new_ka.sa.sa_mask, &set32);
373 ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
374 if (ret)
375 return -EFAULT;
376 }
377
378 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
379 if (!ret && oact) {
380 compat_from_sigset(&set32, &old_ka.sa.sa_mask);
381 ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler);
382 ret |= __copy_to_user(&oact->sa_mask, &set32,
383 sizeof(compat_sigset_t));
384 ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
385 }
386 return ret;
387}
388
389
390
391
392
393
394
395
396long sys32_rt_sigprocmask(u32 how, compat_sigset_t __user *set,
397 compat_sigset_t __user *oset, size_t sigsetsize)
398{
399 sigset_t s;
400 sigset_t __user *up;
401 compat_sigset_t s32;
402 int ret;
403 mm_segment_t old_fs = get_fs();
404
405 if (set) {
406 if (copy_from_user (&s32, set, sizeof(compat_sigset_t)))
407 return -EFAULT;
408 sigset_from_compat(&s, &s32);
409 }
410
411 set_fs(KERNEL_DS);
412
413 up = (sigset_t __user *) &s;
414 ret = sys_rt_sigprocmask((int)how, set ? up : NULL, oset ? up : NULL,
415 sigsetsize);
416 set_fs(old_fs);
417 if (ret)
418 return ret;
419 if (oset) {
420 compat_from_sigset(&s32, &s);
421 if (copy_to_user (oset, &s32, sizeof(compat_sigset_t)))
422 return -EFAULT;
423 }
424 return 0;
425}
426
427long sys32_rt_sigpending(compat_sigset_t __user *set, compat_size_t sigsetsize)
428{
429 sigset_t s;
430 compat_sigset_t s32;
431 int ret;
432 mm_segment_t old_fs = get_fs();
433
434 set_fs(KERNEL_DS);
435
436 ret = sys_rt_sigpending((sigset_t __user *) &s, sigsetsize);
437 set_fs(old_fs);
438 if (!ret) {
439 compat_from_sigset(&s32, &s);
440 if (copy_to_user (set, &s32, sizeof(compat_sigset_t)))
441 return -EFAULT;
442 }
443 return ret;
444}
445
446
447int copy_siginfo_to_user32(struct compat_siginfo __user *d, siginfo_t *s)
448{
449 int err;
450
451 if (!access_ok (VERIFY_WRITE, d, sizeof(*d)))
452 return -EFAULT;
453
454
455
456
457
458
459
460
461
462 err = __put_user(s->si_signo, &d->si_signo);
463 err |= __put_user(s->si_errno, &d->si_errno);
464 err |= __put_user((short)s->si_code, &d->si_code);
465 if (s->si_code < 0)
466 err |= __copy_to_user(&d->_sifields._pad, &s->_sifields._pad,
467 SI_PAD_SIZE32);
468 else switch(s->si_code >> 16) {
469 case __SI_CHLD >> 16:
470 err |= __put_user(s->si_pid, &d->si_pid);
471 err |= __put_user(s->si_uid, &d->si_uid);
472 err |= __put_user(s->si_utime, &d->si_utime);
473 err |= __put_user(s->si_stime, &d->si_stime);
474 err |= __put_user(s->si_status, &d->si_status);
475 break;
476 case __SI_FAULT >> 16:
477 err |= __put_user((unsigned int)(unsigned long)s->si_addr,
478 &d->si_addr);
479 break;
480 case __SI_POLL >> 16:
481 err |= __put_user(s->si_band, &d->si_band);
482 err |= __put_user(s->si_fd, &d->si_fd);
483 break;
484 case __SI_TIMER >> 16:
485 err |= __put_user(s->si_tid, &d->si_tid);
486 err |= __put_user(s->si_overrun, &d->si_overrun);
487 err |= __put_user(s->si_int, &d->si_int);
488 break;
489 case __SI_RT >> 16:
490 case __SI_MESGQ >> 16:
491 err |= __put_user(s->si_int, &d->si_int);
492
493 case __SI_KILL >> 16:
494 default:
495 err |= __put_user(s->si_pid, &d->si_pid);
496 err |= __put_user(s->si_uid, &d->si_uid);
497 break;
498 }
499 return err;
500}
501
502
503
504
505
506
507
508
509long sys32_rt_sigqueueinfo(u32 pid, u32 sig, compat_siginfo_t __user *uinfo)
510{
511 siginfo_t info;
512 int ret;
513 mm_segment_t old_fs = get_fs();
514
515 if (copy_from_user (&info, uinfo, 3*sizeof(int)) ||
516 copy_from_user (info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE32))
517 return -EFAULT;
518 set_fs (KERNEL_DS);
519
520 ret = sys_rt_sigqueueinfo((int)pid, (int)sig, (siginfo_t __user *) &info);
521 set_fs (old_fs);
522 return ret;
523}
524
525int sys32_rt_sigsuspend(compat_sigset_t __user * unewset, size_t sigsetsize, int p3,
526 int p4, int p6, int p7, struct pt_regs *regs)
527{
528 sigset_t saveset, newset;
529 compat_sigset_t s32;
530
531
532 if (sigsetsize != sizeof(sigset_t))
533 return -EINVAL;
534
535 if (copy_from_user(&s32, unewset, sizeof(s32)))
536 return -EFAULT;
537
538
539
540
541
542 sigset_from_compat(&newset, &s32);
543
544 sigdelsetmask(&newset, ~_BLOCKABLE);
545 spin_lock_irq(¤t->sighand->siglock);
546 saveset = current->blocked;
547 current->blocked = newset;
548 recalc_sigpending();
549 spin_unlock_irq(¤t->sighand->siglock);
550
551 regs->result = -EINTR;
552 regs->gpr[3] = EINTR;
553 regs->ccr |= 0x10000000;
554 while (1) {
555 current->state = TASK_INTERRUPTIBLE;
556 schedule();
557 if (do_signal32(&saveset, regs))
558
559
560
561
562
563
564 return 0;
565 }
566}
567
568
569
570
571
572
573
574
575int sys32_sigaltstack(u32 __new, u32 __old, int r5,
576 int r6, int r7, int r8, struct pt_regs *regs)
577{
578 stack_32_t __user * newstack = (stack_32_t __user *)(long) __new;
579 stack_32_t __user * oldstack = (stack_32_t __user *)(long) __old;
580 stack_t uss, uoss;
581 int ret;
582 mm_segment_t old_fs;
583 unsigned long sp;
584 compat_uptr_t ss_sp;
585
586
587
588
589
590 sp = regs->gpr[1];
591
592
593 if (newstack) {
594 if (get_user(ss_sp, &newstack->ss_sp) ||
595 __get_user(uss.ss_flags, &newstack->ss_flags) ||
596 __get_user(uss.ss_size, &newstack->ss_size))
597 return -EFAULT;
598 uss.ss_sp = compat_ptr(ss_sp);
599 }
600
601 old_fs = get_fs();
602 set_fs(KERNEL_DS);
603
604 ret = do_sigaltstack(
605 newstack ? (stack_t __user *) &uss : NULL,
606 oldstack ? (stack_t __user *) &uoss : NULL,
607 sp);
608 set_fs(old_fs);
609
610 if (!ret && oldstack &&
611 (put_user((long)uoss.ss_sp, &oldstack->ss_sp) ||
612 __put_user(uoss.ss_flags, &oldstack->ss_flags) ||
613 __put_user(uoss.ss_size, &oldstack->ss_size)))
614 return -EFAULT;
615 return ret;
616}
617
618
619
620
621
622
623static int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
624 siginfo_t *info, sigset_t *oldset,
625 struct pt_regs * regs, unsigned long newsp)
626{
627 struct rt_sigframe32 __user *rt_sf;
628 struct mcontext32 __user *frame;
629 unsigned long origsp = newsp;
630 compat_sigset_t c_oldset;
631
632
633
634 newsp -= sizeof(*rt_sf);
635 rt_sf = (struct rt_sigframe32 __user *)newsp;
636
637
638 newsp -= __SIGNAL_FRAMESIZE32 + 16;
639
640 if (verify_area(VERIFY_WRITE, (void __user *)newsp, origsp - newsp))
641 goto badframe;
642
643 compat_from_sigset(&c_oldset, oldset);
644
645
646 if (copy_siginfo_to_user32(&rt_sf->info, info)
647 || __put_user(0, &rt_sf->uc.uc_flags)
648 || __put_user(0, &rt_sf->uc.uc_link)
649 || __put_user(current->sas_ss_sp, &rt_sf->uc.uc_stack.ss_sp)
650 || __put_user(sas_ss_flags(regs->gpr[1]),
651 &rt_sf->uc.uc_stack.ss_flags)
652 || __put_user(current->sas_ss_size, &rt_sf->uc.uc_stack.ss_size)
653 || __put_user((u32)(u64)&rt_sf->uc.uc_mcontext, &rt_sf->uc.uc_regs)
654 || __copy_to_user(&rt_sf->uc.uc_sigmask, &c_oldset, sizeof(c_oldset)))
655 goto badframe;
656
657
658 frame = &rt_sf->uc.uc_mcontext;
659 if (save_user_regs(regs, frame, __NR_rt_sigreturn))
660 goto badframe;
661
662 if (put_user(regs->gpr[1], (unsigned long __user *)newsp))
663 goto badframe;
664 regs->gpr[1] = (unsigned long) newsp;
665 regs->gpr[3] = sig;
666 regs->gpr[4] = (unsigned long) &rt_sf->info;
667 regs->gpr[5] = (unsigned long) &rt_sf->uc;
668 regs->gpr[6] = (unsigned long) rt_sf;
669 regs->nip = (unsigned long) ka->sa.sa_handler;
670 regs->link = (unsigned long) frame->tramp;
671 regs->trap = 0;
672 regs->result = 0;
673
674 if (test_thread_flag(TIF_SINGLESTEP))
675 ptrace_notify(SIGTRAP);
676
677 return 1;
678
679badframe:
680#if DEBUG_SIG
681 printk("badframe in handle_rt_signal, regs=%p frame=%p newsp=%lx\n",
682 regs, frame, newsp);
683#endif
684 force_sigsegv(sig, current);
685 return 0;
686}
687
688static long do_setcontext32(struct ucontext32 __user *ucp, struct pt_regs *regs, int sig)
689{
690 compat_sigset_t c_set;
691 sigset_t set;
692 u32 mcp;
693
694 if (__copy_from_user(&c_set, &ucp->uc_sigmask, sizeof(c_set))
695 || __get_user(mcp, &ucp->uc_regs))
696 return -EFAULT;
697 sigset_from_compat(&set, &c_set);
698 restore_sigmask(&set);
699 if (restore_user_regs(regs, (struct mcontext32 __user *)(u64)mcp, sig))
700 return -EFAULT;
701
702 return 0;
703}
704
705
706
707
708
709long sys32_swapcontext(struct ucontext32 __user *old_ctx,
710 struct ucontext32 __user *new_ctx,
711 int ctx_size, int r6, int r7, int r8, struct pt_regs *regs)
712{
713 unsigned char tmp;
714 compat_sigset_t c_set;
715
716
717
718
719 if (ctx_size < sizeof(struct ucontext32))
720 return -EINVAL;
721
722 if (old_ctx != NULL) {
723 compat_from_sigset(&c_set, ¤t->blocked);
724 if (verify_area(VERIFY_WRITE, old_ctx, sizeof(*old_ctx))
725 || save_user_regs(regs, &old_ctx->uc_mcontext, 0)
726 || __copy_to_user(&old_ctx->uc_sigmask, &c_set, sizeof(c_set))
727 || __put_user((u32)(u64)&old_ctx->uc_mcontext, &old_ctx->uc_regs))
728 return -EFAULT;
729 }
730 if (new_ctx == NULL)
731 return 0;
732 if (verify_area(VERIFY_READ, new_ctx, sizeof(*new_ctx))
733 || __get_user(tmp, (u8 __user *) new_ctx)
734 || __get_user(tmp, (u8 __user *) (new_ctx + 1) - 1))
735 return -EFAULT;
736
737
738
739
740
741
742
743
744
745
746
747
748 if (do_setcontext32(new_ctx, regs, 0))
749 do_exit(SIGSEGV);
750
751 return 0;
752}
753
754long sys32_rt_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
755 struct pt_regs *regs)
756{
757 struct rt_sigframe32 __user *rt_sf;
758 int ret;
759
760
761
762 current_thread_info()->restart_block.fn = do_no_restart_syscall;
763
764 rt_sf = (struct rt_sigframe32 __user *)
765 (regs->gpr[1] + __SIGNAL_FRAMESIZE32 + 16);
766 if (verify_area(VERIFY_READ, rt_sf, sizeof(*rt_sf)))
767 goto bad;
768 if (do_setcontext32(&rt_sf->uc, regs, 1))
769 goto bad;
770
771
772
773
774
775
776
777
778
779
780
781 sys32_sigaltstack((u32)(u64)&rt_sf->uc.uc_stack, 0, 0, 0, 0, 0, regs);
782
783 ret = regs->result;
784
785 return ret;
786
787 bad:
788 force_sig(SIGSEGV, current);
789 return 0;
790}
791
792
793
794
795
796static int handle_signal32(unsigned long sig, struct k_sigaction *ka,
797 siginfo_t *info, sigset_t *oldset,
798 struct pt_regs * regs, unsigned long newsp)
799{
800 struct sigcontext32 __user *sc;
801 struct sigregs32 __user *frame;
802 unsigned long origsp = newsp;
803
804
805 newsp -= sizeof(struct sigregs32);
806 frame = (struct sigregs32 __user *) newsp;
807
808
809 newsp -= sizeof(*sc);
810 sc = (struct sigcontext32 __user *) newsp;
811
812
813 newsp -= __SIGNAL_FRAMESIZE32;
814
815 if (verify_area(VERIFY_WRITE, (void __user *) newsp, origsp - newsp))
816 goto badframe;
817
818#if _NSIG != 64
819#error "Please adjust handle_signal32()"
820#endif
821 if (__put_user((u32)(u64)ka->sa.sa_handler, &sc->handler)
822 || __put_user(oldset->sig[0], &sc->oldmask)
823 || __put_user((oldset->sig[0] >> 32), &sc->_unused[3])
824 || __put_user((u32)(u64)frame, &sc->regs)
825 || __put_user(sig, &sc->signal))
826 goto badframe;
827
828 if (save_user_regs(regs, &frame->mctx, __NR_sigreturn))
829 goto badframe;
830
831 if (put_user(regs->gpr[1], (unsigned long __user *)newsp))
832 goto badframe;
833 regs->gpr[1] = (unsigned long) newsp;
834 regs->gpr[3] = sig;
835 regs->gpr[4] = (unsigned long) sc;
836 regs->nip = (unsigned long) ka->sa.sa_handler;
837 regs->link = (unsigned long) frame->mctx.tramp;
838 regs->trap = 0;
839 regs->result = 0;
840
841 if (test_thread_flag(TIF_SINGLESTEP))
842 ptrace_notify(SIGTRAP);
843
844 return 1;
845
846badframe:
847#if DEBUG_SIG
848 printk("badframe in handle_signal, regs=%p frame=%x newsp=%x\n",
849 regs, frame, *newspp);
850#endif
851 force_sigsegv(sig, current);
852 return 0;
853}
854
855
856
857
858long sys32_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
859 struct pt_regs *regs)
860{
861 struct sigcontext32 __user *sc;
862 struct sigcontext32 sigctx;
863 struct mcontext32 __user *sr;
864 sigset_t set;
865 int ret;
866
867
868 current_thread_info()->restart_block.fn = do_no_restart_syscall;
869
870 sc = (struct sigcontext32 __user *)(regs->gpr[1] + __SIGNAL_FRAMESIZE32);
871 if (copy_from_user(&sigctx, sc, sizeof(sigctx)))
872 goto badframe;
873
874
875
876
877
878 set.sig[0] = sigctx.oldmask + ((long)(sigctx._unused[3]) << 32);
879 restore_sigmask(&set);
880
881 sr = (struct mcontext32 __user *)(u64)sigctx.regs;
882 if (verify_area(VERIFY_READ, sr, sizeof(*sr))
883 || restore_user_regs(regs, sr, 1))
884 goto badframe;
885
886 ret = regs->result;
887 return ret;
888
889badframe:
890 force_sig(SIGSEGV, current);
891 return 0;
892}
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911int do_signal32(sigset_t *oldset, struct pt_regs *regs)
912{
913 siginfo_t info;
914 unsigned int frame, newsp;
915 int signr, ret;
916 struct k_sigaction ka;
917
918 if (!oldset)
919 oldset = ¤t->blocked;
920
921 newsp = frame = 0;
922
923 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
924
925 if (TRAP(regs) == 0x0C00
926 && regs->ccr & 0x10000000
927 && ((ret = regs->gpr[3]) == ERESTARTSYS
928 || ret == ERESTARTNOHAND || ret == ERESTARTNOINTR
929 || ret == ERESTART_RESTARTBLOCK)) {
930
931 if (signr > 0
932 && (ret == ERESTARTNOHAND || ret == ERESTART_RESTARTBLOCK
933 || (ret == ERESTARTSYS
934 && !(ka.sa.sa_flags & SA_RESTART)))) {
935
936 regs->result = -EINTR;
937 regs->gpr[3] = EINTR;
938
939 } else {
940 regs->nip -= 4;
941 regs->result = 0;
942 regs->trap = 0;
943 if (ret == ERESTART_RESTARTBLOCK)
944 regs->gpr[0] = __NR_restart_syscall;
945 else
946 regs->gpr[3] = regs->orig_gpr3;
947 }
948 }
949
950 if (signr == 0)
951 return 0;
952
953 if ((ka.sa.sa_flags & SA_ONSTACK) && current->sas_ss_size
954 && (!on_sig_stack(regs->gpr[1])))
955 newsp = (current->sas_ss_sp + current->sas_ss_size);
956 else
957 newsp = regs->gpr[1];
958 newsp &= ~0xfUL;
959
960
961 if (ka.sa.sa_flags & SA_SIGINFO)
962 ret = handle_rt_signal32(signr, &ka, &info, oldset, regs, newsp);
963 else
964 ret = handle_signal32(signr, &ka, &info, oldset, regs, newsp);
965
966 if (ret && !(ka.sa.sa_flags & SA_NODEFER)) {
967 spin_lock_irq(¤t->sighand->siglock);
968 sigorsets(¤t->blocked, ¤t->blocked,
969 &ka.sa.sa_mask);
970 sigaddset(¤t->blocked, signr);
971 recalc_sigpending();
972 spin_unlock_irq(¤t->sighand->siglock);
973 }
974
975 return ret;
976}
977