1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17#include <linux/sched.h>
18#include <linux/mm.h>
19#include <linux/smp.h>
20#include <linux/smp_lock.h>
21#include <linux/kernel.h>
22#include <linux/signal.h>
23#include <linux/errno.h>
24#include <linux/wait.h>
25#include <linux/ptrace.h>
26#include <linux/unistd.h>
27#include <linux/stddef.h>
28#include <linux/elf.h>
29#include <asm/ppc32.h>
30#include <asm/sigcontext.h>
31#include <asm/ucontext.h>
32#include <asm/uaccess.h>
33#include <asm/pgtable.h>
34#include <asm/unistd.h>
35#include <asm/processor.h>
36
37#define DEBUG_SIG 0
38
39#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
40
41#ifndef MIN
42#define MIN(a,b) (((a) < (b)) ? (a) : (b))
43#endif
44
45#define GP_REGS_SIZE MIN(sizeof(elf_gregset_t), sizeof(struct pt_regs))
46#define FP_REGS_SIZE sizeof(elf_fpregset_t)
47
48#define TRAMP_TRACEBACK 3
49#define TRAMP_SIZE 6
50
51
52
53
54
55
56
57
58
59struct sigframe {
60
61 struct sigcontext sc;
62 unsigned int tramp[TRAMP_SIZE];
63
64 char abigap[288];
65};
66
67struct rt_sigframe {
68
69 struct ucontext uc;
70 unsigned long _unused[2];
71 unsigned int tramp[TRAMP_SIZE];
72 struct siginfo *pinfo;
73 void *puc;
74 struct siginfo info;
75
76 char abigap[288];
77};
78
79extern long sys_wait4(pid_t pid, unsigned int *stat_addr,
80 int options, struct rusage *ru);
81
82int
83copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
84{
85 if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
86 return -EFAULT;
87 if (from->si_code < 0)
88 return __copy_to_user(to, from, sizeof(siginfo_t));
89 else {
90 int err;
91
92
93
94
95
96
97 err = __put_user(from->si_signo, &to->si_signo);
98 err |= __put_user(from->si_errno, &to->si_errno);
99 err |= __put_user((short)from->si_code, &to->si_code);
100
101 err |= __put_user(from->si_pid, &to->si_pid);
102 switch (from->si_code >> 16) {
103 case __SI_FAULT >> 16:
104 err |= __put_user(from->si_addr, &to->si_addr);
105 break;
106 case __SI_CHLD >> 16:
107 err |= __put_user(from->si_utime, &to->si_utime);
108 err |= __put_user(from->si_stime, &to->si_stime);
109 err |= __put_user(from->si_status, &to->si_status);
110 default:
111 err |= __put_user(from->si_uid, &to->si_uid);
112 break;
113
114 }
115 return err;
116 }
117}
118
119int do_signal(sigset_t *oldset, struct pt_regs *regs);
120
121
122
123
124asmlinkage long
125sys_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6, int p7,
126 struct pt_regs *regs)
127{
128 sigset_t saveset;
129
130 mask &= _BLOCKABLE;
131 spin_lock_irq(¤t->sigmask_lock);
132 saveset = current->blocked;
133 siginitset(¤t->blocked, mask);
134 recalc_sigpending(current);
135 spin_unlock_irq(¤t->sigmask_lock);
136
137 regs->result = -EINTR;
138 regs->gpr[3] = EINTR;
139 regs->ccr |= 0x10000000;
140 while (1) {
141 set_current_state(TASK_INTERRUPTIBLE);
142 schedule();
143 if (do_signal(&saveset, regs))
144
145
146
147
148
149
150
151
152 return regs->gpr[3];
153 }
154}
155
156asmlinkage long
157sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, int p3, int p4, int p6,
158 int p7, struct pt_regs *regs)
159{
160 sigset_t saveset, newset;
161
162
163 if (sigsetsize != sizeof(sigset_t))
164 return -EINVAL;
165
166 if (copy_from_user(&newset, unewset, sizeof(newset)))
167 return -EFAULT;
168 sigdelsetmask(&newset, ~_BLOCKABLE);
169
170 spin_lock_irq(¤t->sigmask_lock);
171 saveset = current->blocked;
172 current->blocked = newset;
173 recalc_sigpending(current);
174 spin_unlock_irq(¤t->sigmask_lock);
175
176 regs->result = -EINTR;
177 regs->gpr[3] = EINTR;
178 regs->ccr |= 0x10000000;
179 while (1) {
180 current->state = TASK_INTERRUPTIBLE;
181 schedule();
182 if (do_signal(&saveset, regs))
183 return regs->gpr[3];
184 }
185}
186
187asmlinkage long
188sys_sigaltstack(const stack_t *uss, stack_t *uoss, unsigned long r5,
189 unsigned long r6, unsigned long r7, unsigned long r8,
190 struct pt_regs *regs)
191{
192 return do_sigaltstack(uss, uoss, regs->gpr[1]);
193}
194
195asmlinkage long
196sys_sigaction(int sig, const struct old_sigaction *act,
197 struct old_sigaction *oact)
198{
199 struct k_sigaction new_ka, old_ka;
200 int ret;
201
202 if (act) {
203 old_sigset_t mask;
204
205 if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
206 __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
207 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
208 return -EFAULT;
209 __get_user(new_ka.sa.sa_flags, &act->sa_flags);
210 __get_user(mask, &act->sa_mask);
211 siginitset(&new_ka.sa.sa_mask, mask);
212 }
213
214 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
215 if (!ret && oact) {
216 if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
217 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
218 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
219 return -EFAULT;
220 __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
221 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
222 }
223
224 return ret;
225}
226
227
228
229
230
231static int
232setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
233 int signr, sigset_t *set, unsigned long handler)
234{
235 int err = 0;
236
237 if (regs->msr & MSR_FP)
238 giveup_fpu(current);
239 err |= __put_user(&sc->gp_regs, &sc->regs);
240 err |= __copy_to_user(&sc->gp_regs, regs, GP_REGS_SIZE);
241 err |= __copy_to_user(&sc->fp_regs, ¤t->thread.fpr, FP_REGS_SIZE);
242 current->thread.fpscr = 0;
243
244 err |= __put_user(signr, &sc->signal);
245 err |= __put_user(handler, &sc->handler);
246 if (set != NULL)
247 err |= __put_user(set->sig[0], &sc->oldmask);
248
249 return err;
250}
251
252
253
254
255
256static int
257restore_sigcontext(struct pt_regs *regs, sigset_t *set, struct sigcontext *sc)
258{
259 unsigned int err = 0;
260 int i;
261 elf_greg_t *gregs = (elf_greg_t *)regs;
262 unsigned long msr;
263
264
265 err |= __copy_from_user(regs, &sc->gp_regs,
266 PT_MSR * sizeof(elf_greg_t));
267
268 err |= __get_user(msr, &sc->gp_regs[PT_MSR]);
269
270
271 for (i = PT_ORIG_R3; err == 0 && i <= PT_RESULT; ++i)
272 if (i != PT_SOFTE)
273 err |= __get_user(gregs[i], &sc->gp_regs[i]);
274
275
276 regs->msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1);
277#ifndef CONFIG_SMP
278 if (last_task_used_math == current)
279 last_task_used_math = NULL;
280#endif
281 err |= __copy_from_user(¤t->thread.fpr, &sc->fp_regs, FP_REGS_SIZE);
282
283
284 if (set != NULL)
285 err |= __get_user(set->sig[0], &sc->oldmask);
286
287 return err;
288}
289
290
291
292
293static inline void *
294get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
295{
296 unsigned long newsp;
297
298
299 newsp = regs->gpr[1];
300
301 if (ka->sa.sa_flags & SA_ONSTACK) {
302 if (! on_sig_stack(regs->gpr[1]))
303 newsp = (current->sas_ss_sp + current->sas_ss_size);
304 }
305
306
307 return (void *)((newsp - frame_size) & -16ul);
308
309}
310
311static int
312setup_trampoline(unsigned int syscall, unsigned int *tramp)
313{
314 int i, err = 0;
315
316
317 err |= __put_user(0x38210000UL | (__SIGNAL_FRAMESIZE & 0xffff), &tramp[0]);
318
319 err |= __put_user(0x38000000UL | (syscall & 0xffff), &tramp[1]);
320
321 err |= __put_user(0x44000002UL, &tramp[2]);
322
323
324 for (i=TRAMP_TRACEBACK; i < TRAMP_SIZE ;i++)
325 err |= __put_user(0, &tramp[i]);
326
327 if (!err)
328 flush_icache_range((unsigned long) &tramp[0],
329 (unsigned long) &tramp[TRAMP_SIZE]);
330
331 return err;
332}
333
334
335asmlinkage int
336sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
337 unsigned long r6, unsigned long r7, unsigned long r8,
338 struct pt_regs *regs)
339{
340 struct ucontext *uc = (struct ucontext *)regs->gpr[1];
341 sigset_t set;
342 stack_t st;
343
344 if (verify_area(VERIFY_READ, uc, sizeof(*uc)))
345 goto badframe;
346
347 if (__copy_from_user(&set, &uc->uc_sigmask, sizeof(set)))
348 goto badframe;
349
350 sigdelsetmask(&set, ~_BLOCKABLE);
351 spin_lock_irq(¤t->sigmask_lock);
352 current->blocked = set;
353 recalc_sigpending(current);
354 spin_unlock_irq(¤t->sigmask_lock);
355
356 if (restore_sigcontext(regs, NULL, &uc->uc_mcontext))
357 goto badframe;
358
359 if (__copy_from_user(&st, &uc->uc_stack, sizeof(st)))
360 goto badframe;
361
362
363
364 sys_sigaltstack(&st, NULL, 0, 0, 0, 0, regs);
365
366 return regs->result;
367
368badframe:
369 do_exit(SIGSEGV);
370}
371
372static void
373setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
374 sigset_t *set, struct pt_regs *regs)
375{
376
377
378
379
380
381 func_descr_t *funct_desc_ptr;
382 struct rt_sigframe *frame;
383 unsigned long newsp;
384 int err = 0;
385
386 frame = get_sigframe(ka, regs, sizeof(*frame));
387
388 if (verify_area(VERIFY_WRITE, frame, sizeof(*frame)))
389 goto give_sigsegv;
390
391 err |= __put_user(&frame->info, &frame->pinfo);
392 err |= __put_user(&frame->uc, &frame->puc);
393 err |= copy_siginfo_to_user(&frame->info, info);
394 if (err)
395 goto give_sigsegv;
396
397
398 err |= __put_user(0, &frame->uc.uc_flags);
399 err |= __put_user(0, &frame->uc.uc_link);
400 err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
401 err |= __put_user(sas_ss_flags(regs->gpr[1]),
402 &frame->uc.uc_stack.ss_flags);
403 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
404 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, signr, NULL,
405 (unsigned long)ka->sa.sa_handler);
406 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
407 if (err)
408 goto give_sigsegv;
409
410
411 err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]);
412 if (err)
413 goto give_sigsegv;
414
415 funct_desc_ptr = (func_descr_t *) ka->sa.sa_handler;
416
417
418 newsp = (unsigned long)frame - __SIGNAL_FRAMESIZE;
419 err |= put_user(0, (unsigned long *)newsp);
420
421
422 err |= get_user(regs->nip, &funct_desc_ptr->entry);
423 regs->link = (unsigned long) &frame->tramp[0];
424 regs->gpr[1] = newsp;
425 err |= get_user(regs->gpr[2], &funct_desc_ptr->toc);
426 regs->gpr[3] = signr;
427 err |= get_user(regs->gpr[4], (unsigned long *)&frame->pinfo);
428 err |= get_user(regs->gpr[5], (unsigned long *)&frame->puc);
429 regs->gpr[6] = (unsigned long) frame;
430 if (err)
431 goto give_sigsegv;
432
433 return;
434
435give_sigsegv:
436#if DEBUG_SIG
437 printk("badframe in setup_rt_frame, regs=%p frame=%p, newsp=0x%lx\n",
438 regs, frame, newsp);
439#endif
440 do_exit(SIGSEGV);
441}
442
443
444
445
446asmlinkage long
447sys_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
448 unsigned long r6, unsigned long r7, unsigned long r8,
449 struct pt_regs *regs)
450{
451 struct sigcontext *sc = (struct sigcontext *)regs->gpr[1];
452 sigset_t set;
453
454 if (verify_area(VERIFY_READ, sc, sizeof(*sc)))
455 goto badframe;
456
457 if (restore_sigcontext(regs, &set, sc))
458 goto badframe;
459
460 sigdelsetmask(&set, ~_BLOCKABLE);
461 spin_lock_irq(¤t->sigmask_lock);
462 current->blocked = set;
463 recalc_sigpending(current);
464 spin_unlock_irq(¤t->sigmask_lock);
465
466 return regs->result;
467
468badframe:
469 do_exit(SIGSEGV);
470}
471
472
473static void
474setup_frame(int signr, struct k_sigaction *ka, sigset_t *set,
475 struct pt_regs *regs)
476{
477
478
479
480
481
482 func_descr_t *funct_desc_ptr;
483 struct sigframe *frame;
484 unsigned long newsp;
485 int err = 0;
486
487 frame = get_sigframe(ka, regs, sizeof(*frame));
488
489 if (verify_area(VERIFY_WRITE, frame, sizeof(*frame)))
490 goto badframe;
491
492 err |= setup_sigcontext(&frame->sc, regs, signr, set,
493 (unsigned long)ka->sa.sa_handler);
494
495
496 err |= setup_trampoline(__NR_sigreturn, &frame->tramp[0]);
497 if (err)
498 goto badframe;
499
500 funct_desc_ptr = (func_descr_t *) ka->sa.sa_handler;
501
502
503 newsp = (unsigned long)frame - __SIGNAL_FRAMESIZE;
504 err |= put_user(0, (unsigned long *)newsp);
505
506
507 err |= get_user(regs->nip, &funct_desc_ptr->entry);
508 regs->link = (unsigned long) &frame->tramp[0];
509 regs->gpr[1] = newsp;
510 err |= get_user(regs->gpr[2], &funct_desc_ptr->toc);
511 regs->gpr[3] = signr;
512 regs->gpr[4] = (unsigned long) &frame->sc;
513 if (err)
514 goto badframe;
515
516 return;
517
518badframe:
519#if DEBUG_SIG
520 printk("badframe in setup_frame, regs=%p frame=%p newsp=%lx\n",
521 regs, frame, newsp);
522#endif
523 do_exit(SIGSEGV);
524}
525
526
527
528
529static void
530handle_signal(unsigned long sig, struct k_sigaction *ka,
531 siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
532{
533
534 if (ka->sa.sa_flags & SA_SIGINFO)
535 setup_rt_frame(sig, ka, info, oldset, regs);
536 else
537 setup_frame(sig, ka, oldset, regs);
538
539 if (ka->sa.sa_flags & SA_ONESHOT)
540 ka->sa.sa_handler = SIG_DFL;
541
542 if (!(ka->sa.sa_flags & SA_NODEFER)) {
543 spin_lock_irq(¤t->sigmask_lock);
544 sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask);
545 sigaddset(¤t->blocked,sig);
546 recalc_sigpending(current);
547 spin_unlock_irq(¤t->sigmask_lock);
548 }
549}
550
551static inline void
552syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
553{
554 switch ((int)regs->result) {
555 case -ERESTARTNOHAND:
556
557
558
559
560 regs->result = -EINTR;
561 break;
562
563 case -ERESTARTSYS:
564
565
566 if (!(ka->sa.sa_flags & SA_RESTART)) {
567 regs->result = -EINTR;
568 break;
569 }
570
571 case -ERESTARTNOINTR:
572
573
574 regs->gpr[3] = regs->orig_gpr3;
575 regs->nip -= 4;
576 regs->result = 0;
577 }
578}
579
580static int
581get_signal_to_deliver(siginfo_t *info, struct pt_regs *regs)
582{
583 for (;;) {
584 unsigned long signr;
585 struct k_sigaction *ka;
586
587 spin_lock_irq(¤t->sigmask_lock);
588 signr = dequeue_signal(¤t->blocked, info);
589 spin_unlock_irq(¤t->sigmask_lock);
590
591 if (!signr)
592 break;
593
594 if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
595
596 current->exit_code = signr;
597 current->state = TASK_STOPPED;
598 notify_parent(current, SIGCHLD);
599 schedule();
600
601
602 signr = current->exit_code;
603 if (signr == 0)
604 continue;
605 current->exit_code = 0;
606
607
608 if (signr == SIGSTOP)
609 continue;
610
611
612 if (signr != info->si_signo) {
613 info->si_signo = signr;
614 info->si_errno = 0;
615 info->si_code = SI_USER;
616 info->si_pid = current->p_pptr->pid;
617 info->si_uid = current->p_pptr->uid;
618 }
619
620
621 if (sigismember(¤t->blocked, signr)) {
622 send_sig_info(signr, info, current);
623 continue;
624 }
625 }
626
627 ka = ¤t->sig->action[signr-1];
628
629 if (ka->sa.sa_handler == SIG_IGN) {
630 if (signr != SIGCHLD)
631 continue;
632
633 while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
634 ;
635 continue;
636 }
637
638 if (ka->sa.sa_handler == SIG_DFL) {
639 int exit_code = signr;
640
641
642 if (current->pid == 1)
643 continue;
644
645 switch (signr) {
646 case SIGCONT: case SIGCHLD: case SIGWINCH: case SIGURG:
647 continue;
648
649 case SIGTSTP: case SIGTTIN: case SIGTTOU:
650 if (is_orphaned_pgrp(current->pgrp))
651 continue;
652
653
654 case SIGSTOP: {
655 struct signal_struct *sig;
656 current->state = TASK_STOPPED;
657 current->exit_code = signr;
658 sig = current->p_pptr->sig;
659 if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
660 notify_parent(current, SIGCHLD);
661 schedule();
662 continue;
663 }
664
665 case SIGQUIT: case SIGILL: case SIGTRAP:
666 case SIGABRT: case SIGFPE: case SIGSEGV:
667 case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
668 if (do_coredump(signr, regs))
669 exit_code |= 0x80;
670
671
672 default:
673 sig_exit(signr, exit_code, info);
674
675 }
676 }
677 return signr;
678 }
679 return 0;
680}
681
682
683
684
685
686
687extern int do_signal32(sigset_t *oldset, struct pt_regs *regs);
688
689int
690do_signal(sigset_t *oldset, struct pt_regs *regs)
691{
692 siginfo_t info;
693 int signr;
694
695
696
697
698
699 if (current->thread.flags & PPC_FLAG_32BIT)
700 return do_signal32(oldset, regs);
701
702 if (!oldset)
703 oldset = ¤t->blocked;
704
705 signr = get_signal_to_deliver(&info, regs);
706 if (signr > 0) {
707 struct k_sigaction *ka = ¤t->sig->action[signr-1];
708
709
710 if (regs->trap == 0x0C00)
711 syscall_restart(regs, ka);
712 handle_signal(signr, ka, &info, oldset, regs);
713 return 1;
714 }
715
716 if (regs->trap == 0x0C00 &&
717 ((int)regs->result == -ERESTARTNOHAND ||
718 (int)regs->result == -ERESTARTSYS ||
719 (int)regs->result == -ERESTARTNOINTR)) {
720 regs->gpr[3] = regs->orig_gpr3;
721 regs->nip -= 4;
722 regs->result = 0;
723 }
724
725 return 0;
726}
727
728
729
730