~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/ppc64/kernel/signal.c

Version: ~ [ linux-6.4-rc3 ] ~ [ linux-6.3.4 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.30 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.113 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.180 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.243 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.283 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.315 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  *  linux/arch/ppc64/kernel/signal.c
  3  *
  4  *  PowerPC version 
  5  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  6  *
  7  *  Derived from "arch/i386/kernel/signal.c"
  8  *    Copyright (C) 1991, 1992 Linus Torvalds
  9  *    1997-11-28  Modified for POSIX.1b signals by Richard Henderson
 10  *
 11  *  This program is free software; you can redistribute it and/or
 12  *  modify it under the terms of the GNU General Public License
 13  *  as published by the Free Software Foundation; either version
 14  *  2 of the License, or (at your option) any later version.
 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  * When we have signals to deliver, we set up on the user stack,
 53  * going down from the original stack pointer:
 54  *      1) a sigframe/rt_sigframe struct which contains the sigcontext/ucontext 
 55  *      2) a gap of __SIGNAL_FRAMESIZE bytes which acts as a dummy caller
 56  *         frame for the signal handler.
 57  */
 58 
 59 struct sigframe {
 60         /* sys_sigreturn requires the sigcontext be the first field */
 61         struct sigcontext sc;
 62         unsigned int tramp[TRAMP_SIZE];
 63         /* 64 bit ABI allows for 288 bytes below sp before decrementing it. */
 64         char abigap[288];
 65 };
 66 
 67 struct rt_sigframe {
 68         /* sys_rt_sigreturn requires the ucontext be the first field */
 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         /* 64 bit ABI allows for 288 bytes below sp before decrementing it. */
 76         char abigap[288];
 77 };
 78 
 79 extern long sys_wait4(pid_t pid, unsigned int *stat_addr,
 80                      int options, /*unsigned long*/ struct rusage *ru);
 81 
 82 int
 83 copy_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                 /* If you change siginfo_t structure, please be sure
 93                    this code is fixed accordingly.
 94                    It should never copy any pad contained in the structure
 95                    to avoid security leaks, but must copy the generic
 96                    3 ints plus the relevant union member.  */
 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                 /* First 32bits of unions are always present.  */
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                 /* case __SI_RT: This is not generated by the kernel as of now.  */
114                 }
115                 return err;
116         }
117 }
118 
119 int do_signal(sigset_t *oldset, struct pt_regs *regs);
120 
121 /*
122  * Atomically swap in the new signal mask, and wait for a signal.
123  */
124 asmlinkage long
125 sys_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(&current->sigmask_lock);
132         saveset = current->blocked;
133         siginitset(&current->blocked, mask);
134         recalc_sigpending(current);
135         spin_unlock_irq(&current->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                          * If a signal handler needs to be called,
146                          * do_signal() has set R3 to the signal number (the
147                          * first argument of the signal handler), so don't
148                          * overwrite that with EINTR !
149                          * In the other cases, do_signal() doesn't touch 
150                          * R3, so it's still set to -EINTR (see above).
151                          */
152                         return regs->gpr[3];
153         }
154 }
155 
156 asmlinkage long
157 sys_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         /* XXX: Don't preclude handling different sized sigset_t's.  */
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(&current->sigmask_lock);
171         saveset = current->blocked;
172         current->blocked = newset;
173         recalc_sigpending(current);
174         spin_unlock_irq(&current->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 
187 asmlinkage long
188 sys_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 
195 asmlinkage long
196 sys_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  * Set up the sigcontext for the signal frame.
229  */
230 
231 static int
232 setup_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, &current->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  * Restore the sigcontext from the signal frame.
254  */
255 
256 static int
257 restore_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         /* copy up to but not including MSR */
265         err |= __copy_from_user(regs, &sc->gp_regs,
266                                 PT_MSR * sizeof(elf_greg_t));
267         /* get the MSR value from the stack but don't put it in regs->msr */
268         err |= __get_user(msr, &sc->gp_regs[PT_MSR]);
269         /* copy from orig_r3 (the word after the MSR) to the end,
270          * but don't copy softe */
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         /* make the process reload FP regs if it executes an FP instr */
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(&current->thread.fpr, &sc->fp_regs, FP_REGS_SIZE);
282 
283         /* restore the signal mask */
284         if (set != NULL)
285                 err |=  __get_user(set->sig[0], &sc->oldmask);
286 
287         return err;
288 }
289 
290 /*
291  * Allocate space for the signal frame
292  */
293 static inline void *
294 get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
295 {
296         unsigned long newsp;
297 
298         /* Default to using normal stack */
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         /* The ABI requires quadword alignment for the stack. */
307         return (void *)((newsp - frame_size) & -16ul);
308 
309 }
310 
311 static int
312 setup_trampoline(unsigned int syscall, unsigned int *tramp)
313 {
314         int i, err = 0;
315 
316         /* addi r1, r1, __SIGNAL_FRAMESIZE  # Pop the dummy stackframe */
317         err |= __put_user(0x38210000UL | (__SIGNAL_FRAMESIZE & 0xffff), &tramp[0]);
318         /* li r0, __NR_[rt_]sigreturn| */
319         err |= __put_user(0x38000000UL | (syscall & 0xffff), &tramp[1]);
320         /* sc */
321         err |= __put_user(0x44000002UL, &tramp[2]);
322 
323         /* Minimal traceback info */
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 
335 asmlinkage long
336 sys_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(&current->sigmask_lock);
352         current->blocked = set;
353         recalc_sigpending(current);
354         spin_unlock_irq(&current->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         /* This function sets back the stack flags into
363            the current task structure.  */
364         sys_sigaltstack(&st, NULL, 0, 0, 0, 0, regs);
365 
366         return regs->result;
367 
368 badframe:
369         do_exit(SIGSEGV);
370 }
371 
372 static void
373 setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
374                 sigset_t *set, struct pt_regs *regs)
375 {
376         /* Handler is *really* a pointer to the function descriptor for
377          * the signal routine.  The first entry in the function
378          * descriptor is the entry address of signal and the second
379          * entry is the TOC value we need to use.
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         /* Create the ucontext.  */
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         /* Set up to return from userspace. */
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         /* Allocate a dummy caller frame for the signal handler. */
418         newsp = (unsigned long)frame - __SIGNAL_FRAMESIZE;
419         err |= put_user(0, (unsigned long *)newsp);
420 
421         /* Set up "regs" so we "return" to the signal handler. */
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 
435 give_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  * Do a signal return; undo the signal stack.
445  */
446 asmlinkage long
447 sys_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(&current->sigmask_lock);
462         current->blocked = set;
463         recalc_sigpending(current);
464         spin_unlock_irq(&current->sigmask_lock);
465 
466         return regs->result;
467 
468 badframe:
469         do_exit(SIGSEGV);
470 }       
471 
472 
473 static void
474 setup_frame(int signr, struct k_sigaction *ka, sigset_t *set,
475             struct pt_regs *regs)
476 {
477         /* Handler is *really* a pointer to the function descriptor for
478          * the signal routine.  The first entry in the function
479          * descriptor is the entry address of signal and the second
480          * entry is the TOC value we need to use.
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         /* Set up to return from userspace. */
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         /* Allocate a dummy caller frame for the signal handler. */
503         newsp = (unsigned long)frame - __SIGNAL_FRAMESIZE;
504         err |= put_user(0, (unsigned long *)newsp);
505 
506         /* Set up "regs" so we "return" to the signal handler. */
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 
518 badframe:
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  * OK, we're invoking a handler
528  */
529 static void
530 handle_signal(unsigned long sig, struct k_sigaction *ka,
531               siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
532 {
533         /* Set up Signal Frame */
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(&current->sigmask_lock);
544                 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
545                 sigaddset(&current->blocked,sig);
546                 recalc_sigpending(current);
547                 spin_unlock_irq(&current->sigmask_lock);
548         }
549 }
550 
551 static inline void
552 syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
553 {
554         switch ((int)regs->result) {
555                 case -ERESTARTNOHAND:
556                         /* ERESTARTNOHAND means that the syscall should only
557                            be restarted if there was no handler for the signal,
558                            and since we only get here if there is a handler,
559                            we dont restart */
560                         regs->result = -EINTR;
561                         break;
562 
563                 case -ERESTARTSYS:
564                         /* ERESTARTSYS means to restart the syscall if there is
565                            no handler or the handler was registered with SA_RESTART */
566                         if (!(ka->sa.sa_flags & SA_RESTART)) {
567                                 regs->result = -EINTR;
568                                 break;
569                         }
570                 /* fallthrough */
571                 case -ERESTARTNOINTR:
572                         /* ERESTARTNOINTR means that the syscall should be
573                            called again after the signal handler returns */
574                         regs->gpr[3] = regs->orig_gpr3;
575                         regs->nip -= 4;
576                         regs->result = 0;
577         }
578 }
579 
580 static int
581 get_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(&current->sigmask_lock);
588                 signr = dequeue_signal(&current->blocked, info);
589                 spin_unlock_irq(&current->sigmask_lock);
590 
591                 if (!signr)
592                         break;
593 
594                 if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
595                         /* Let the debugger run.  */
596                         current->exit_code = signr;
597                         current->state = TASK_STOPPED;
598                         notify_parent(current, SIGCHLD);
599                         schedule();
600 
601                         /* We're back.  Did the debugger cancel the sig?  */
602                         signr = current->exit_code;
603                         if (signr == 0)
604                                 continue;
605                         current->exit_code = 0;
606 
607                         /* The debugger continued.  Ignore SIGSTOP.  */
608                         if (signr == SIGSTOP)
609                                 continue;
610 
611                         /* Update the siginfo structure.  Is this good?  */
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                         /* If the (new) signal is now blocked, requeue it.  */
621                         if (sigismember(&current->blocked, signr)) {
622                                 send_sig_info(signr, info, current);
623                                 continue;
624                         }
625                 }
626 
627                 ka = &current->sig->action[signr-1];
628 
629                 if (ka->sa.sa_handler == SIG_IGN) {
630                         if (signr != SIGCHLD)
631                                 continue;
632                         /* Check for SIGCHLD: it's special.  */
633                         while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
634                                 /* nothing */;
635                         continue;
636                 }
637 
638                 if (ka->sa.sa_handler == SIG_DFL) {
639                         int exit_code = signr;
640 
641                         /* Init gets no signals it doesn't want.  */
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                                 /* FALLTHRU */
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                                 /* FALLTHRU */
671 
672                         default:
673                                 sig_exit(signr, exit_code, info);
674                                 /* NOTREACHED */
675                         }
676                 }
677                 return signr;
678         }
679         return 0;
680 }
681 
682 /*
683  * Note that 'init' is a special process: it doesn't get signals it doesn't
684  * want to handle. Thus you cannot kill init even with a SIGKILL even by
685  * mistake.
686  */
687 extern int do_signal32(sigset_t *oldset, struct pt_regs *regs);
688 
689 int
690 do_signal(sigset_t *oldset, struct pt_regs *regs)
691 {
692         siginfo_t info;
693         int signr;
694 
695         /*
696          * If the current thread is 32 bit - invoke the
697          * 32 bit signal handling code
698          */
699         if (current->thread.flags & PPC_FLAG_32BIT)
700                 return do_signal32(oldset, regs);
701 
702         if (!oldset)
703                 oldset = &current->blocked;
704 
705         signr = get_signal_to_deliver(&info, regs);
706         if (signr > 0) {
707                 struct k_sigaction *ka = &current->sig->action[signr-1];
708 
709                 /* Whee!  Actually deliver the signal.  */
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 /* System Call! */ &&
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;         /* Back up & retry system call */
722                 regs->result = 0;
723         }
724 
725         return 0;
726 }
727 
728 
729 
730 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp