static int do_signal(struct pt_regs *regs) { sigset_t *oldset; siginfo_t info; int signr; struct k_sigaction ka; int ret; int is32 = is_32bit_task(); if (current_thread_info()->local_flags & _TLF_RESTORE_SIGMASK) oldset = ¤t->saved_sigmask; else oldset = ¤t->blocked; signr = get_signal_to_deliver(&info, &ka, regs, NULL); check_syscall_restart(regs, &ka, signr > 0); if (signr <= 0) { struct thread_info *ti = current_thread_info(); if (ti->local_flags & _TLF_RESTORE_SIGMASK) { ti->local_flags &= ~_TLF_RESTORE_SIGMASK; sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } regs->trap = 0; return 0; } #ifndef CONFIG_PPC_ADV_DEBUG_REGS if (current->thread.dabr) set_dabr(current->thread.dabr); #endif thread_change_pc(current, regs); if (is32) { if (ka.sa.sa_flags & SA_SIGINFO) ret = handle_rt_signal32(signr, &ka, &info, oldset, regs); else ret = handle_signal32(signr, &ka, &info, oldset, regs); } else { ret = handle_rt_signal64(signr, &ka, &info, oldset, regs); } regs->trap = 0; if (ret) { block_sigmask(&ka, signr); current_thread_info()->local_flags &= ~_TLF_RESTORE_SIGMASK; tracehook_signal_handler(signr, &info, &ka, regs, test_thread_flag(TIF_SINGLESTEP)); } return ret; }
static inline int handle_signal(unsigned long signr, struct k_sigaction *ka, siginfo_t *info, sigset_t *oldset, struct pt_regs *regs) { int err; if (ka->sa.sa_flags & SA_SIGINFO) err = setup_rt_frame(ka, regs, signr, oldset, info); else err = setup_frame(ka, regs, signr, oldset); if (err) return err; spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); if (!(ka->sa.sa_flags & SA_NOMASK)) sigaddset(¤t->blocked, signr); recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); tracehook_signal_handler(signr, info, ka, regs, 0); return 0; }
/* * handle a potential signal */ static void do_signal(struct pt_regs *regs, int syscall) { struct k_sigaction ka; siginfo_t info; sigset_t *oldset; int signr; /* we want the common case to go fast, which is why we may in certain * cases get here from kernel mode */ if (!user_mode(regs)) return; if (test_thread_flag(TIF_RESTORE_SIGMASK)) oldset = ¤t->saved_sigmask; else oldset = ¤t->blocked; signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { if (handle_signal(signr, &info, &ka, oldset, regs, syscall) == 0) { /* a signal was successfully delivered; the saved * sigmask will have been stored in the signal frame, * and will be restored by sigreturn, so we can simply * clear the TIF_RESTORE_SIGMASK flag */ if (test_thread_flag(TIF_RESTORE_SIGMASK)) clear_thread_flag(TIF_RESTORE_SIGMASK); tracehook_signal_handler(signr, &info, &ka, regs, 0); } return; } /* did we come from a system call? */ if (syscall) { /* restart the system call - no handlers present */ switch (regs->a4) { case -ERESTARTNOHAND: case -ERESTARTSYS: case -ERESTARTNOINTR: regs->a4 = regs->orig_a4; regs->pc -= 4; break; case -ERESTART_RESTARTBLOCK: regs->a4 = regs->orig_a4; regs->b0 = __NR_restart_syscall; regs->pc -= 4; break; } } /* if there's no signal to deliver, we just put the saved sigmask * back */ if (test_thread_flag(TIF_RESTORE_SIGMASK)) { clear_thread_flag(TIF_RESTORE_SIGMASK); sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } }
static void do_signal(struct pt_regs *regs) { struct k_sigaction sigact; siginfo_t info; int signo; if (!user_mode(regs)) return; if (try_to_freeze()) goto no_signal; signo = get_signal_to_deliver(&info, &sigact, regs, NULL); if (signo > 0) { sigset_t *oldset; if (test_thread_flag(TIF_RESTORE_SIGMASK)) oldset = ¤t->saved_sigmask; else oldset = ¤t->blocked; if (handle_signal(signo, &info, &sigact, oldset, regs) == 0) { clear_thread_flag(TIF_RESTORE_SIGMASK); tracehook_signal_handler(signo, &info, &sigact, regs, test_thread_flag(TIF_SINGLESTEP)); } return; } no_signal: if (regs->syscall_nr >= 0) { switch (regs->r00) { case -ERESTARTNOHAND: case -ERESTARTSYS: case -ERESTARTNOINTR: regs->r06 = regs->syscall_nr; break; case -ERESTART_RESTARTBLOCK: regs->r06 = __NR_restart_syscall; break; default: goto no_restart; } pt_set_elr(regs, pt_elr(regs) - 4); regs->r00 = regs->restart_r0; } no_restart: if (test_thread_flag(TIF_RESTORE_SIGMASK)) { clear_thread_flag(TIF_RESTORE_SIGMASK); sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } }
/* * Note that 'init' is a special process: it doesn't get signals it doesn't * want to handle. Thus you cannot kill init even with a SIGKILL even by * mistake. * * Note that we go through the signals twice: once to check the signals * that the kernel can handle, and then we build all the user-level signal * handling stack-frames in one go after that. */ asmlinkage void do_signal(struct pt_regs *regs) { siginfo_t info; int signr; struct k_sigaction ka; sigset_t *oldset; current->thread.esp0 = (unsigned long)regs; if (try_to_freeze()) goto no_signal; if (test_thread_flag(TIF_RESTORE_SIGMASK)) oldset = ¤t->saved_sigmask; else oldset = ¤t->blocked; signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { /* Whee! Actually deliver the signal. */ if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { /* a signal was successfully delivered; the saved * sigmask will have been stored in the signal frame, * and will be restored by sigreturn, so we can simply * clear the TIF_RESTORE_SIGMASK flag */ if (test_thread_flag(TIF_RESTORE_SIGMASK)) clear_thread_flag(TIF_RESTORE_SIGMASK); tracehook_signal_handler(signr, &info, &ka, regs, test_thread_flag(TIF_SINGLESTEP)); } return; } no_signal: /* Did we come from a system call? */ if (regs->orig_p0 >= 0) /* Restart the system call - no handlers present */ handle_restart(regs, NULL, 0); /* if there's no signal to deliver, we just put the saved sigmask * back */ if (test_thread_flag(TIF_RESTORE_SIGMASK)) { clear_thread_flag(TIF_RESTORE_SIGMASK); sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } }
static inline int handle_signal(unsigned long signr, struct k_sigaction *ka, siginfo_t *info, sigset_t *oldset, struct pt_regs *regs) { int err; err = setup_rt_frame(ka, regs, signr, oldset, (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL); if (err) return err; block_sigmask(ka, signr); tracehook_signal_handler(signr, info, ka, regs, 0); return 0; }
/* * OK, we're invoking a handler */ static int handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *oldset, struct pt_regs * regs) { struct thread_info *thread = current_thread_info(); struct task_struct *tsk = current; int usig = sig; int ret; /* * translate the signal */ if (usig < 32 && thread->exec_domain && thread->exec_domain->signal_invmap) usig = thread->exec_domain->signal_invmap[usig]; /* * Set up the stack frame */ if (ka->sa.sa_flags & SA_SIGINFO) ret = setup_rt_frame(usig, ka, info, oldset, regs); else ret = setup_frame(usig, ka, oldset, regs); /* * Check that the resulting registers are actually sane. */ ret |= !valid_user_regs(regs); if (ret != 0) { force_sigsegv(sig, tsk); return ret; } /* * Block the signal if we were successful. */ block_sigmask(ka, sig); tracehook_signal_handler(sig, info, ka, regs, 0); return 0; }
static inline int handle_signal(unsigned long signr, struct k_sigaction *ka, siginfo_t *info, sigset_t *oldset, struct pt_regs *regs) { sigset_t blocked; int err; err = setup_rt_frame(ka, regs, signr, oldset, (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL); if (err) return err; sigorsets(&blocked, ¤t->blocked, &ka->sa.sa_mask); if (!(ka->sa.sa_flags & SA_NOMASK)) sigaddset(&blocked, signr); set_current_blocked(&blocked); tracehook_signal_handler(signr, info, ka, regs, 0); return 0; }
static long handle_signal (unsigned long sig, struct k_sigaction *ka, siginfo_t *info, struct sigscratch *scr) { if (!setup_frame(sig, ka, info, sigmask_to_save(), scr)) return 0; spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); if (!(ka->sa.sa_flags & SA_NODEFER)) sigaddset(¤t->blocked, sig); recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); /* * Let tracing know that we've done the handler setup. */ tracehook_signal_handler(sig, info, ka, &scr->pt, test_thread_flag(TIF_SINGLESTEP)); return 1; }
static int do_signal_pending(sigset_t *oldset, struct pt_regs *regs) { siginfo_t info; int signr; struct k_sigaction ka; int ret; int is32 = is_32bit_task(); #ifdef CONFIG_PREEMPT_RT /* * Fully-preemptible kernel does not need interrupts disabled: */ local_irq_enable(); preempt_check_resched(); #endif if (current_thread_info()->local_flags & _TLF_RESTORE_SIGMASK) oldset = ¤t->saved_sigmask; else if (!oldset) oldset = ¤t->blocked; signr = get_signal_to_deliver(&info, &ka, regs, NULL); /* Is there any syscall restart business here ? */ check_syscall_restart(regs, &ka, signr > 0); if (signr <= 0) { struct thread_info *ti = current_thread_info(); /* No signal to deliver -- put the saved sigmask back */ if (ti->local_flags & _TLF_RESTORE_SIGMASK) { ti->local_flags &= ~_TLF_RESTORE_SIGMASK; sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } return 0; /* no signals delivered */ } /* * Reenable the DABR before delivering the signal to * user space. The DABR will have been cleared if it * triggered inside the kernel. */ if (current->thread.dabr) { set_dabr(current->thread.dabr); #if defined(CONFIG_BOOKE) mtspr(SPRN_DBCR0, current->thread.dbcr0); #endif } if (is32) { if (ka.sa.sa_flags & SA_SIGINFO) ret = handle_rt_signal32(signr, &ka, &info, oldset, regs); else ret = handle_signal32(signr, &ka, &info, oldset, regs); } else { ret = handle_rt_signal64(signr, &ka, &info, oldset, regs); } if (ret) { spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked, ¤t->blocked, &ka.sa.sa_mask); if (!(ka.sa.sa_flags & SA_NODEFER)) sigaddset(¤t->blocked, signr); recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); /* * A signal was successfully delivered; the saved sigmask is in * its frame, and we can clear the TLF_RESTORE_SIGMASK flag. */ current_thread_info()->local_flags &= ~_TLF_RESTORE_SIGMASK; /* * Let tracing know that we've done the handler setup. */ tracehook_signal_handler(signr, &info, &ka, regs, test_thread_flag(TIF_SINGLESTEP)); } return ret; }
void do_signal(struct pt_regs *regs) { siginfo_t info; int signr; struct k_sigaction ka; /* * We want the common case to go fast, which * is why we may in certain cases get here from * kernel mode. Just return without doing anything * if so. */ if (!user_mode(regs)) return; signr = get_signal_to_deliver(&info, &ka, regs, NULL); /* If we are coming out of a syscall then we need * to check if the syscall was interrupted and wants to be * restarted after handling the signal. If so, the original * syscall number is put back into r11 and the PC rewound to * point at the l.sys instruction that resulted in the * original syscall. Syscall results other than the four * below mean that the syscall executed to completion and no * restart is necessary. */ if (regs->syscallno) { int restart = 0; switch (regs->gpr[11]) { case -ERESTART_RESTARTBLOCK: case -ERESTARTNOHAND: /* Restart if there is no signal handler */ restart = (signr <= 0); break; case -ERESTARTSYS: /* Restart if there no signal handler or * SA_RESTART flag is set */ restart = (signr <= 0 || (ka.sa.sa_flags & SA_RESTART)); break; case -ERESTARTNOINTR: /* Always restart */ restart = 1; break; } if (restart) { if (regs->gpr[11] == -ERESTART_RESTARTBLOCK) regs->gpr[11] = __NR_restart_syscall; else regs->gpr[11] = regs->orig_gpr11; regs->pc -= 4; } else { regs->gpr[11] = -EINTR; } } if (signr <= 0) { /* no signal to deliver so we just put the saved sigmask * back */ if (test_thread_flag(TIF_RESTORE_SIGMASK)) { clear_thread_flag(TIF_RESTORE_SIGMASK); sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } } else { /* signr > 0 */ sigset_t *oldset; if (current_thread_info()->flags & _TIF_RESTORE_SIGMASK) oldset = ¤t->saved_sigmask; else oldset = ¤t->blocked; /* Whee! Actually deliver the signal. */ handle_signal(signr, &info, &ka, oldset, regs); /* a signal was successfully delivered; the saved * sigmask will have been stored in the signal frame, * and will be restored by sigreturn, so we can simply * clear the TIF_RESTORE_SIGMASK flag */ if (test_thread_flag(TIF_RESTORE_SIGMASK)) clear_thread_flag(TIF_RESTORE_SIGMASK); tracehook_signal_handler(signr, &info, &ka, regs, test_thread_flag(TIF_SINGLESTEP)); } return; }
static int handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs) { int ret; /* Are we from a system call? */ if (syscall_get_nr(current, regs) >= 0) { /* If so, check system call restarting.. */ switch (syscall_get_error(current, regs)) { case -ERESTART_RESTARTBLOCK: case -ERESTARTNOHAND: regs->ax = -EINTR; break; case -ERESTARTSYS: if (!(ka->sa.sa_flags & SA_RESTART)) { regs->ax = -EINTR; break; } /* fallthrough */ case -ERESTARTNOINTR: regs->ax = regs->orig_ax; regs->ip -= 2; break; } } /* * If TF is set due to a debugger (TIF_FORCED_TF), clear the TF * flag so that register information in the sigcontext is correct. */ if (unlikely(regs->flags & X86_EFLAGS_TF) && likely(test_and_clear_thread_flag(TIF_FORCED_TF))) regs->flags &= ~X86_EFLAGS_TF; ret = setup_rt_frame(sig, ka, info, oldset, regs); if (ret) return ret; #ifdef CONFIG_X86_64 /* * This has nothing to do with segment registers, * despite the name. This magic affects uaccess.h * macros' behavior. Reset it to the normal setting. */ set_fs(USER_DS); #endif /* * Clear the direction flag as per the ABI for function entry. */ regs->flags &= ~X86_EFLAGS_DF; /* * Clear TF when entering the signal handler, but * notify any tracer that was single-stepping it. * The tracer may want to single-step inside the * handler too. */ regs->flags &= ~X86_EFLAGS_TF; spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); if (!(ka->sa.sa_flags & SA_NODEFER)) sigaddset(¤t->blocked, sig); recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); tracehook_signal_handler(sig, info, ka, regs, test_thread_flag(TIF_SINGLESTEP)); return 0; }
/* * Note that 'init' is a special process: it doesn't get signals it doesn't * want to handle. Thus you cannot kill init even with a SIGKILL even by * mistake. * * Note that we go through the signals twice: once to check the signals that * the kernel can handle, and then we build all the user-level signal handling * stack-frames in one go after that. */ static void do_signal(struct pt_regs *regs, unsigned int save_r0) { siginfo_t info; int signr; struct k_sigaction ka; sigset_t *oldset; /* * We want the common case to go fast, which * is why we may in certain cases get here from * kernel mode. Just return without doing anything * if so. */ if (!user_mode(regs)) return; if (current_thread_info()->status & TS_RESTORE_SIGMASK) oldset = ¤t->saved_sigmask; else oldset = ¤t->blocked; signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { handle_syscall_restart(save_r0, regs, &ka.sa); /* Whee! Actually deliver the signal. */ if (handle_signal(signr, &ka, &info, oldset, regs, save_r0) == 0) { /* * A signal was successfully delivered; the saved * sigmask will have been stored in the signal frame, * and will be restored by sigreturn, so we can simply * clear the TS_RESTORE_SIGMASK flag */ current_thread_info()->status &= ~TS_RESTORE_SIGMASK; tracehook_signal_handler(signr, &info, &ka, regs, test_thread_flag(TIF_SINGLESTEP)); } return; } /* Did we come from a system call? */ if (regs->tra >= 0) { /* Restart the system call - no handlers present */ if (regs->regs[0] == -ERESTARTNOHAND || regs->regs[0] == -ERESTARTSYS || regs->regs[0] == -ERESTARTNOINTR) { regs->regs[0] = save_r0; regs->pc -= instruction_size(__raw_readw(regs->pc - 4)); } else if (regs->regs[0] == -ERESTART_RESTARTBLOCK) { regs->pc -= instruction_size(__raw_readw(regs->pc - 4)); regs->regs[3] = __NR_restart_syscall; } } /* * If there's no signal to deliver, we just put the saved sigmask * back. */ if (current_thread_info()->status & TS_RESTORE_SIGMASK) { current_thread_info()->status &= ~TS_RESTORE_SIGMASK; sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } }
/* * Note that 'init' is a special process: it doesn't get signals it doesn't * want to handle. Thus you cannot kill init even with a SIGKILL even by * mistake. */ static void do_signal(void) { struct k_sigaction ka; siginfo_t info; sigset_t *oldset; int signr; /* * We want the common case to go fast, which * is why we may in certain cases get here from * kernel mode. Just return without doing anything * if so. */ if (!user_mode(__frame)) return; if (try_to_freeze()) goto no_signal; if (test_thread_flag(TIF_RESTORE_SIGMASK)) oldset = ¤t->saved_sigmask; else oldset = ¤t->blocked; signr = get_signal_to_deliver(&info, &ka, __frame, NULL); if (signr > 0) { if (handle_signal(signr, &info, &ka, oldset) == 0) { /* a signal was successfully delivered; the saved * sigmask will have been stored in the signal frame, * and will be restored by sigreturn, so we can simply * clear the TIF_RESTORE_SIGMASK flag */ if (test_thread_flag(TIF_RESTORE_SIGMASK)) clear_thread_flag(TIF_RESTORE_SIGMASK); tracehook_signal_handler(signr, &info, &ka, __frame, test_thread_flag(TIF_SINGLESTEP)); } return; } no_signal: /* Did we come from a system call? */ if (__frame->syscallno != -1) { /* Restart the system call - no handlers present */ switch (__frame->gr8) { case -ERESTARTNOHAND: case -ERESTARTSYS: case -ERESTARTNOINTR: __frame->gr8 = __frame->orig_gr8; __frame->pc -= 4; break; case -ERESTART_RESTARTBLOCK: __frame->gr7 = __NR_restart_syscall; __frame->pc -= 4; break; } __frame->syscallno = -1; } /* if there's no signal to deliver, we just put the saved sigmask * back */ if (test_thread_flag(TIF_RESTORE_SIGMASK)) { clear_thread_flag(TIF_RESTORE_SIGMASK); sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } } /* end do_signal() */
/* * Note that 'init' is a special process: it doesn't get signals it doesn't * want to handle. Thus you cannot kill init even with a SIGKILL even by * mistake. * * Note that we go through the signals twice: once to check the signals that * the kernel can handle, and then we build all the user-level signal handling * stack-frames in one go after that. */ void do_signal(struct pt_regs *regs) { unsigned long retval = 0, continue_addr = 0, restart_addr = 0; siginfo_t info; int signr; struct k_sigaction ka; sigset_t *oldset; /* * We want the common case to go fast, which * is why we may in certain cases get here from * kernel mode. Just return without doing anything * if so. */ if (!user_mode(regs)) return; if (test_thread_flag(TIF_RESTORE_SIGMASK)) oldset = ¤t->saved_sigmask; else oldset = ¤t->blocked; /* Are we from a system call? */ if (regs->svcnr) { continue_addr = regs->psw.addr; restart_addr = continue_addr - regs->ilc; retval = regs->gprs[2]; /* Prepare for system call restart. We do this here so that a debugger will see the already changed PSW. */ switch (retval) { case -ERESTARTNOHAND: case -ERESTARTSYS: case -ERESTARTNOINTR: regs->gprs[2] = regs->orig_gpr2; regs->psw.addr = restart_addr; break; case -ERESTART_RESTARTBLOCK: regs->gprs[2] = -EINTR; } regs->svcnr = 0; /* Don't deal with this again. */ } /* Get signal to deliver. When running under ptrace, at this point the debugger may change all our registers ... */ signr = get_signal_to_deliver(&info, &ka, regs, NULL); /* Depending on the signal settings we may need to revert the decision to restart the system call. */ if (signr > 0 && regs->psw.addr == restart_addr) { if (retval == -ERESTARTNOHAND || (retval == -ERESTARTSYS && !(current->sighand->action[signr-1].sa.sa_flags & SA_RESTART))) { regs->gprs[2] = -EINTR; regs->psw.addr = continue_addr; } } if (signr > 0) { /* Whee! Actually deliver the signal. */ int ret; #ifdef CONFIG_COMPAT if (test_thread_flag(TIF_31BIT)) { ret = handle_signal32(signr, &ka, &info, oldset, regs); } else #endif ret = handle_signal(signr, &ka, &info, oldset, regs); if (!ret) { /* * A signal was successfully delivered; the saved * sigmask will have been stored in the signal frame, * and will be restored by sigreturn, so we can simply * clear the TIF_RESTORE_SIGMASK flag. */ if (test_thread_flag(TIF_RESTORE_SIGMASK)) clear_thread_flag(TIF_RESTORE_SIGMASK); /* * If we would have taken a single-step trap * for a normal instruction, act like we took * one for the handler setup. */ if (current->thread.per_info.single_step) set_thread_flag(TIF_SINGLE_STEP); /* * Let tracing know that we've done the handler setup. */ tracehook_signal_handler(signr, &info, &ka, regs, test_thread_flag(TIF_SINGLE_STEP)); } return; } /* * If there's no signal to deliver, we just put the saved sigmask back. */ if (test_thread_flag(TIF_RESTORE_SIGMASK)) { clear_thread_flag(TIF_RESTORE_SIGMASK); sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } /* Restart a different system call. */ if (retval == -ERESTART_RESTARTBLOCK && regs->psw.addr == continue_addr) { regs->gprs[2] = __NR_restart_syscall; set_thread_flag(TIF_RESTART_SVC); } }
static int do_signal(struct pt_regs *regs) { sigset_t *oldset; siginfo_t info; int signr; struct k_sigaction ka; int ret; int is32 = is_32bit_task(); if (current_thread_info()->local_flags & _TLF_RESTORE_SIGMASK) oldset = ¤t->saved_sigmask; else oldset = ¤t->blocked; signr = get_signal_to_deliver(&info, &ka, regs, NULL); /* Is there any syscall restart business here ? */ check_syscall_restart(regs, &ka, signr > 0); if (signr <= 0) { struct thread_info *ti = current_thread_info(); /* No signal to deliver -- put the saved sigmask back */ if (ti->local_flags & _TLF_RESTORE_SIGMASK) { ti->local_flags &= ~_TLF_RESTORE_SIGMASK; sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } regs->trap = 0; return 0; /* no signals delivered */ } #ifndef CONFIG_PPC_ADV_DEBUG_REGS /* * Reenable the DABR before delivering the signal to * user space. The DABR will have been cleared if it * triggered inside the kernel. */ if (current->thread.dabr) set_dabr(current->thread.dabr); #endif /* Re-enable the breakpoints for the signal stack */ thread_change_pc(current, regs); if (is32) { if (ka.sa.sa_flags & SA_SIGINFO) ret = handle_rt_signal32(signr, &ka, &info, oldset, regs); else ret = handle_signal32(signr, &ka, &info, oldset, regs); } else { ret = handle_rt_signal64(signr, &ka, &info, oldset, regs); } regs->trap = 0; if (ret) { block_sigmask(&ka, signr); /* * A signal was successfully delivered; the saved sigmask is in * its frame, and we can clear the TLF_RESTORE_SIGMASK flag. */ current_thread_info()->local_flags &= ~_TLF_RESTORE_SIGMASK; /* * Let tracing know that we've done the handler setup. */ tracehook_signal_handler(signr, &info, &ka, regs, test_thread_flag(TIF_SINGLESTEP)); } return ret; }
/* Note that 'init' is a special process: it doesn't get signals it doesn't * want to handle. Thus you cannot kill init even with a SIGKILL even by * mistake. */ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) { struct k_sigaction ka; int restart_syscall; sigset_t *oldset; siginfo_t info; int signr; if (pt_regs_is_syscall(regs) && (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) { restart_syscall = 1; } else restart_syscall = 0; if (current_thread_info()->status & TS_RESTORE_SIGMASK) oldset = ¤t->saved_sigmask; else oldset = ¤t->blocked; #ifdef CONFIG_COMPAT if (test_thread_flag(TIF_32BIT)) { extern void do_signal32(sigset_t *, struct pt_regs *, int restart_syscall, unsigned long orig_i0); do_signal32(oldset, regs, restart_syscall, orig_i0); return; } #endif signr = get_signal_to_deliver(&info, &ka, regs, NULL); /* If the debugger messes with the program counter, it clears * the software "in syscall" bit, directing us to not perform * a syscall restart. */ if (restart_syscall && !pt_regs_is_syscall(regs)) restart_syscall = 0; if (signr > 0) { if (restart_syscall) syscall_restart(orig_i0, regs, &ka.sa); handle_signal(signr, &ka, &info, oldset, regs); /* A signal was successfully delivered; the saved * sigmask will have been stored in the signal frame, * and will be restored by sigreturn, so we can simply * clear the TS_RESTORE_SIGMASK flag. */ current_thread_info()->status &= ~TS_RESTORE_SIGMASK; tracehook_signal_handler(signr, &info, &ka, regs, 0); return; } if (restart_syscall && (regs->u_regs[UREG_I0] == ERESTARTNOHAND || regs->u_regs[UREG_I0] == ERESTARTSYS || regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { /* replay the system call when we are done */ regs->u_regs[UREG_I0] = orig_i0; regs->tpc -= 4; regs->tnpc -= 4; } if (restart_syscall && regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { regs->u_regs[UREG_G1] = __NR_restart_syscall; regs->tpc -= 4; regs->tnpc -= 4; } /* If there's no signal to deliver, we just put the saved sigmask * back */ if (current_thread_info()->status & TS_RESTORE_SIGMASK) { current_thread_info()->status &= ~TS_RESTORE_SIGMASK; sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } }
/* * Note that 'init' is a special process: it doesn't get signals it doesn't * want to handle. Thus you cannot kill init even with a SIGKILL even by * mistake. * * Note that we go through the signals twice: once to check the signals that * the kernel can handle, and then we build all the user-level signal handling * stack-frames in one go after that. */ void do_signal(struct pt_regs *regs) { siginfo_t info; int signr; struct k_sigaction ka; sigset_t *oldset; /* * We want the common case to go fast, which * is why we may in certain cases get here from * kernel mode. Just return without doing anything * if so. */ if (!user_mode(regs)) return; if (test_thread_flag(TIF_RESTORE_SIGMASK)) oldset = ¤t->saved_sigmask; else oldset = ¤t->blocked; /* * Get signal to deliver. When running under ptrace, at this point * the debugger may change all our registers, including the system * call information. */ current_thread_info()->system_call = test_thread_flag(TIF_SYSCALL) ? regs->int_code : 0; signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { /* Whee! Actually deliver the signal. */ if (current_thread_info()->system_call) { regs->int_code = current_thread_info()->system_call; /* Check for system call restarting. */ switch (regs->gprs[2]) { case -ERESTART_RESTARTBLOCK: case -ERESTARTNOHAND: regs->gprs[2] = -EINTR; break; case -ERESTARTSYS: if (!(ka.sa.sa_flags & SA_RESTART)) { regs->gprs[2] = -EINTR; break; } /* fallthrough */ case -ERESTARTNOINTR: regs->gprs[2] = regs->orig_gpr2; regs->psw.addr = __rewind_psw(regs->psw, regs->int_code >> 16); break; } } /* No longer in a system call */ clear_thread_flag(TIF_SYSCALL); if ((is_compat_task() ? handle_signal32(signr, &ka, &info, oldset, regs) : handle_signal(signr, &ka, &info, oldset, regs)) == 0) { /* * A signal was successfully delivered; the saved * sigmask will have been stored in the signal frame, * and will be restored by sigreturn, so we can simply * clear the TIF_RESTORE_SIGMASK flag. */ if (test_thread_flag(TIF_RESTORE_SIGMASK)) clear_thread_flag(TIF_RESTORE_SIGMASK); /* * Let tracing know that we've done the handler setup. */ tracehook_signal_handler(signr, &info, &ka, regs, test_thread_flag(TIF_SINGLE_STEP)); } return; }
/* * Called from return-from-event code. */ static void do_signal(struct pt_regs *regs) { struct k_sigaction sigact; siginfo_t info; int signo; if (!user_mode(regs)) return; if (try_to_freeze()) goto no_signal; signo = get_signal_to_deliver(&info, &sigact, regs, NULL); if (signo > 0) { sigset_t *oldset; if (test_thread_flag(TIF_RESTORE_SIGMASK)) oldset = ¤t->saved_sigmask; else oldset = ¤t->blocked; if (handle_signal(signo, &info, &sigact, oldset, regs) == 0) { /* * Successful delivery case. The saved sigmask is * stored in the signal frame, and will be restored * by sigreturn. We can clear the TIF flag. */ clear_thread_flag(TIF_RESTORE_SIGMASK); tracehook_signal_handler(signo, &info, &sigact, regs, test_thread_flag(TIF_SINGLESTEP)); } return; } no_signal: /* * If we came from a system call, handle the restart. */ if (regs->syscall_nr >= 0) { switch (regs->r00) { case -ERESTARTNOHAND: case -ERESTARTSYS: case -ERESTARTNOINTR: regs->r06 = regs->syscall_nr; break; case -ERESTART_RESTARTBLOCK: regs->r06 = __NR_restart_syscall; break; default: goto no_restart; } pt_set_elr(regs, pt_elr(regs) - 4); regs->r00 = regs->restart_r0; } no_restart: /* If there's no signal to deliver, put the saved sigmask back */ if (test_thread_flag(TIF_RESTORE_SIGMASK)) { clear_thread_flag(TIF_RESTORE_SIGMASK); sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } }
/* * Note that 'init' is a special process: it doesn't get signals it doesn't * want to handle. Thus you cannot kill init even with a SIGKILL even by * mistake. * * Note that we go through the signals twice: once to check the signals that * the kernel can handle, and then we build all the user-level signal handling * stack-frames in one go after that. */ static int do_signal(struct pt_regs *regs, sigset_t *oldset) { siginfo_t info; int signr; struct k_sigaction ka; /* * We want the common case to go fast, which * is why we may in certain cases get here from * kernel mode. Just return without doing anything * if so. */ if (!user_mode(regs)) return 1; if (try_to_freeze()) goto no_signal; if (test_thread_flag(TIF_RESTORE_SIGMASK)) oldset = ¤t->saved_sigmask; else if (!oldset) oldset = ¤t->blocked; signr = get_signal_to_deliver(&info, &ka, regs, 0); if (signr > 0) { handle_syscall_restart(regs, &ka.sa); /* Whee! Actually deliver the signal. */ if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { /* * If a signal was successfully delivered, the * saved sigmask is in its frame, and we can * clear the TIF_RESTORE_SIGMASK flag. */ if (test_thread_flag(TIF_RESTORE_SIGMASK)) clear_thread_flag(TIF_RESTORE_SIGMASK); tracehook_signal_handler(signr, &info, &ka, regs, 0); return 1; } } no_signal: /* Did we come from a system call? */ if (regs->syscall_nr >= 0) { /* Restart the system call - no handlers present */ switch (regs->regs[REG_RET]) { case -ERESTARTNOHAND: case -ERESTARTSYS: case -ERESTARTNOINTR: /* Decode Syscall # */ regs->regs[REG_RET] = regs->syscall_nr; regs->pc -= 4; break; case -ERESTART_RESTARTBLOCK: regs->regs[REG_RET] = __NR_restart_syscall; regs->pc -= 4; break; } } /* No signal to deliver -- put the saved sigmask back */ if (test_thread_flag(TIF_RESTORE_SIGMASK)) { clear_thread_flag(TIF_RESTORE_SIGMASK); sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } return 0; }
void do_signal(struct pt_regs *regs) { siginfo_t info; int signr; struct k_sigaction ka; /* */ if (!user_mode(regs)) return; signr = get_signal_to_deliver(&info, &ka, regs, NULL); /* */ if (regs->orig_gpr11) { int restart = 0; switch (regs->gpr[11]) { case -ERESTART_RESTARTBLOCK: case -ERESTARTNOHAND: /* */ restart = (signr <= 0); break; case -ERESTARTSYS: /* */ restart = (signr <= 0 || (ka.sa.sa_flags & SA_RESTART)); break; case -ERESTARTNOINTR: /* */ restart = 1; break; } if (restart) { if (regs->gpr[11] == -ERESTART_RESTARTBLOCK) regs->gpr[11] = __NR_restart_syscall; else regs->gpr[11] = regs->orig_gpr11; regs->pc -= 4; } else { regs->gpr[11] = -EINTR; } } if (signr <= 0) { /* */ if (test_thread_flag(TIF_RESTORE_SIGMASK)) { clear_thread_flag(TIF_RESTORE_SIGMASK); sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } } else { /* */ sigset_t *oldset; if (current_thread_info()->flags & _TIF_RESTORE_SIGMASK) oldset = ¤t->saved_sigmask; else oldset = ¤t->blocked; /* */ if (!handle_signal(signr, &info, &ka, oldset, regs)) { /* */ clear_thread_flag(TIF_RESTORE_SIGMASK); } tracehook_signal_handler(signr, &info, &ka, regs, test_thread_flag(TIF_SINGLESTEP)); } return; }