/* * 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, int in_syscall) { siginfo_t info; int signr; struct k_sigaction ka; #ifdef DEBUG_SIG pr_info("do signal: %p %d\n", regs, in_syscall); pr_info("do signal2: %lx %lx %ld [%lx]\n", regs->pc, regs->r1, regs->r12, current_thread_info()->flags); #endif signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { /* Whee! Actually deliver the signal. */ if (in_syscall) handle_restart(regs, &ka, 1); handle_signal(signr, &ka, &info, regs); return; } if (in_syscall) handle_restart(regs, NULL, 0); /* * If there's no signal to deliver, we just put the saved sigmask * back. */ restore_saved_sigmask(); }
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; }
/* * 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); } }
/* * 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. */ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs) { struct k_sigaction ka; siginfo_t info; 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(regs)) return 1; if (!oldset) oldset = ¤t->blocked; signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { /* Whee! Actually deliver the signal. */ handle_signal(signr, &ka, &info, oldset, regs); return 1; } /* Did we come from a system call? */ if (regs->frame_type == -1) { /* Restart the system call - no handlers present */ handle_restart(regs, NULL, 0); } 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. */ static 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 (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) { /* Re-enable any watchpoints before delivering the * signal to user space. The processor register will * have been cleared if the watchpoint triggered * inside the kernel. */ /* Whee! Actually deliver the signal. */ if (handle_signal(signr, &ka, &info, oldset, regs) == 0) clear_thread_flag(TIF_RESTORE_SIGMASK); return; } no_signal: /* Did we come from a system call? */ if (regs->syscall_nr >= 0) { /* Restart the system call - no handlers present */ if (regs->r0 == -ERESTARTNOHAND || regs->r0 == -ERESTARTSYS || regs->r0 == -ERESTARTNOINTR) { regs->r0 = regs->orig_r0; prev_insn(regs); } else if (regs->r0 == -ERESTART_RESTARTBLOCK){ regs->r0 = regs->orig_r0; regs->r7 = __NR_restart_syscall; prev_insn(regs); } } if (test_thread_flag(TIF_RESTORE_SIGMASK)) { clear_thread_flag(TIF_RESTORE_SIGMASK); sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } }
void do_signal(int canrestart, 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; signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { /* Whee! Actually deliver the signal. */ if (handle_signal(canrestart, 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); } return; } /* Did we come from a system call? */ if (canrestart) { /* Restart the system call - no handlers present */ if (regs->r10 == -ERESTARTNOHAND || regs->r10 == -ERESTARTSYS || regs->r10 == -ERESTARTNOINTR) { RESTART_CRIS_SYS(regs); } if (regs->r10 == -ERESTART_RESTARTBLOCK) { regs->r10 = __NR_restart_syscall; regs->irp -= 2; } } /* 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); } }
/* * 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(int retval, 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 0; 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. */ handle_signal(signr, &info, &ka, oldset, regs); if (test_thread_flag(TIF_RESTORE_SIGMASK)) clear_thread_flag(TIF_RESTORE_SIGMASK); return signr; } no_signal: /* Did we come from a system call? */ if (regs->r8) { /* Restart the system call - no handlers present */ if (retval == -ERESTARTNOHAND || retval == -ERESTARTSYS || retval == -ERESTARTNOINTR) { regs->ea -= 4; /* Size of scall insn. */ } else if (retval == -ERESTART_RESTARTBLOCK) { regs->r8 = __NR_restart_syscall; regs->ea -= 4; /* Size of scall insn. */ } } if (test_thread_flag(TIF_RESTORE_SIGMASK)) { clear_thread_flag(TIF_RESTORE_SIGMASK); sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } return retval; }
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); } }
static int kern_do_signal(struct pt_regs *regs) { struct k_sigaction ka_copy; siginfo_t info; sigset_t *oldset; int sig, handled_sig = 0; if (test_thread_flag(TIF_RESTORE_SIGMASK)) oldset = ¤t->saved_sigmask; else oldset = ¤t->blocked; while ((sig = get_signal_to_deliver(&info, &ka_copy, regs, NULL)) > 0) { handled_sig = 1; /* Whee! Actually deliver the signal. */ handle_signal(regs, sig, &ka_copy, &info); } /* Did we come from a system call? */ if (!handled_sig && (PT_REGS_SYSCALL_NR(regs) >= 0)) { /* Restart the system call - no handlers present */ switch (PT_REGS_SYSCALL_RET(regs)) { case -ERESTARTNOHAND: case -ERESTARTSYS: case -ERESTARTNOINTR: PT_REGS_ORIG_SYSCALL(regs) = PT_REGS_SYSCALL_NR(regs); PT_REGS_RESTART_SYSCALL(regs); break; case -ERESTART_RESTARTBLOCK: PT_REGS_ORIG_SYSCALL(regs) = __NR_restart_syscall; PT_REGS_RESTART_SYSCALL(regs); break; } } /* * This closes a way to execute a system call on the host. If * you set a breakpoint on a system call instruction and singlestep * from it, the tracing thread used to PTRACE_SINGLESTEP the process * rather than PTRACE_SYSCALL it, allowing the system call to execute * on the host. The tracing thread will check this flag and * PTRACE_SYSCALL if necessary. */ if (current->ptrace & PT_DTRACE) current->thread.singlestep_syscall = is_syscall(PT_REGS_IP(¤t->thread.regs)); /* * if there's no signal to deliver, we just put the saved sigmask * back */ if (!handled_sig) restore_saved_sigmask(); return handled_sig; }
/* * 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. */ int do_signal(struct pt_regs *regs, sigset_t *oldset) { struct k_sigaction ka; siginfo_t info; 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(regs)) return 1; if (try_to_freeze()) goto no_signal; if (!oldset) oldset = ¤t->blocked; signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { /* Reenable any watchpoints before delivering the * signal to user space. The processor register will * have been cleared if the watchpoint triggered * inside the kernel. */ if (current->thread.debugreg7) set_debugreg(current->thread.debugreg7, 7); /* Whee! Actually deliver the signal. */ return handle_signal(signr, &info, &ka, oldset, regs); } no_signal: /* Did we come from a system call? */ if ((long)regs->orig_rax >= 0) { /* Restart the system call - no handlers present */ long res = regs->rax; if (res == -ERESTARTNOHAND || res == -ERESTARTSYS || res == -ERESTARTNOINTR) { regs->rax = regs->orig_rax; regs->rip -= 2; } if (regs->rax == (unsigned long)-ERESTART_RESTARTBLOCK) { regs->rax = test_thread_flag(TIF_IA32) ? __NR_ia32_restart_syscall : __NR_restart_syscall; regs->rip -= 2; } } 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. */ int do_signal(struct pt_regs *regs, sigset_t *oldset) { siginfo_t info; int signr; struct k_sigaction ka; if (!oldset) oldset = ¤t->blocked; signr = get_signal_to_deliver(&info, &ka, regs, NULL); /* Are we from a system call? */ if (regs->syscall >= 0) { /* If so, check system call restarting.. */ switch (regs->areg[2]) { case ERESTARTNOHAND: case ERESTART_RESTARTBLOCK: regs->areg[2] = -EINTR; break; case ERESTARTSYS: if (!(ka.sa.sa_flags & SA_RESTART)) { regs->areg[2] = -EINTR; break; } /* fallthrough */ case ERESTARTNOINTR: regs->areg[2] = regs->syscall; regs->pc -= 3; } } if (signr == 0) return 0; /* no signals delivered */ /* Whee! Actually deliver the signal. */ /* Set up the stack frame */ if (ka.sa.sa_flags & SA_SIGINFO) setup_rt_frame(signr, &ka, &info, oldset, regs); else setup_frame(signr, &ka, oldset, regs); if (ka.sa.sa_flags & SA_ONESHOT) ka.sa.sa_handler = SIG_DFL; 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); return 1; }
void do_signal(struct pt_regs *regs) { siginfo_t info; int signr; struct k_sigaction ka; sigset_t *oldset; 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) { if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { current_thread_info()->status &= ~TS_RESTORE_SIGMASK; } goto done; } if (regs->faultnum == INT_SWINT_1) { switch (regs->regs[0]) { case -ERESTARTNOHAND: case -ERESTARTSYS: case -ERESTARTNOINTR: regs->flags |= PT_FLAGS_CALLER_SAVES; regs->regs[0] = regs->orig_r0; regs->pc -= 8; break; case -ERESTART_RESTARTBLOCK: regs->flags |= PT_FLAGS_CALLER_SAVES; regs->regs[TREG_SYSCALL_NR] = __NR_restart_syscall; regs->pc -= 8; break; } } if (current_thread_info()->status & TS_RESTORE_SIGMASK) { current_thread_info()->status &= ~TS_RESTORE_SIGMASK; sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } done: regs->faultnum = INT_SWINT_1_SIGRETURN; }
static int do_signal(struct pt_regs *regs) { sigset_t *oldset = sigmask_to_save(); siginfo_t info; int signr; struct k_sigaction ka; int ret; int is32 = is_32bit_task(); 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) { /* No signal to deliver -- put the saved sigmask back */ restore_saved_sigmask(); 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.hw_brk.address && current->thread.hw_brk.type) set_breakpoint(¤t->thread.hw_brk); #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) { signal_delivered(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. */ int do_signal(struct pt_regs *regs, sigset_t *oldset, int syscall) { 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 0; 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, NULL); if (syscall) { switch (regs->r12) { case -ERESTART_RESTARTBLOCK: case -ERESTARTNOHAND: if (signr > 0) { regs->r12 = -EINTR; break; } /* fall through */ case -ERESTARTSYS: if (signr > 0 && !(ka.sa.sa_flags & SA_RESTART)) { regs->r12 = -EINTR; break; } /* fall through */ case -ERESTARTNOINTR: setup_syscall_restart(regs); } } if (signr == 0) { /* 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; } handle_signal(signr, &ka, &info, oldset, regs, syscall); return 1; }
/* * 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. */ int do_signal(struct pt_regs *regs, sigset_t *oldset) { siginfo_t info; int signr; struct k_sigaction ka; #ifdef CONFIG_PREEMPT_RT /* * Fully-preemptible kernel does not need interrupts disabled: */ local_irq_enable(); preempt_check_resched(); #endif /* * 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 (current->flags & PF_FREEZE) { refrigerator(0); goto no_signal; } if (!oldset) oldset = ¤t->blocked; signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { /* Whee! Actually deliver the signal. */ handle_signal(signr, &ka, &info, oldset, regs); return 1; } no_signal: /* 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] == -ERESTART_RESTARTBLOCK) { regs->pc -= 2; } } 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, int syscall) { struct k_sigaction ka; siginfo_t info; 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(regs)) return; signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { handle_signal(signr, &ka, &info, regs, syscall); return; } /* * No signal to deliver to the process - restart the syscall. */ if (syscall) { if (regs->UCreg_00 == -ERESTART_RESTARTBLOCK) { u32 __user *usp; regs->UCreg_sp -= 4; usp = (u32 __user *)regs->UCreg_sp; if (put_user(regs->UCreg_pc, usp) == 0) { regs->UCreg_pc = KERN_RESTART_CODE; } else { regs->UCreg_sp += 4; force_sigsegv(0, current); } } if (regs->UCreg_00 == -ERESTARTNOHAND || regs->UCreg_00 == -ERESTARTSYS || regs->UCreg_00 == -ERESTARTNOINTR) { setup_syscall_restart(regs); } } /* If there's no signal to deliver, we just put the saved * sigmask back. */ restore_saved_sigmask(); }
/* * 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. */ int do_signal(sigset_t *oldset, struct pt_regs *regs) { siginfo_t info; int signr; struct k_sigaction ka; /* * If the current thread is 32 bit - invoke the * 32 bit signal handling code */ if (test_thread_flag(TIF_32BIT)) return do_signal32(oldset, regs); if (!oldset) oldset = ¤t->blocked; signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { /* Whee! Actually deliver the signal. */ if (TRAP(regs) == 0x0C00) syscall_restart(regs, &ka); /* * 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); return handle_signal(signr, &ka, &info, oldset, regs); } if (TRAP(regs) == 0x0C00) { /* System Call! */ if ((int)regs->result == -ERESTARTNOHAND || (int)regs->result == -ERESTARTSYS || (int)regs->result == -ERESTARTNOINTR) { regs->gpr[3] = regs->orig_gpr3; regs->nip -= 4; /* Back up & retry system call */ regs->result = 0; } else if ((int)regs->result == -ERESTART_RESTARTBLOCK) { regs->gpr[0] = __NR_restart_syscall; regs->nip -= 4; regs->result = 0; } } 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. */ void do_signal(struct pt_regs *regs) { siginfo_t info; int signr; struct k_sigaction ka; sigset_t *oldset = sigmask_to_save(); /* * 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); else handle_signal(signr, &ka, &info, oldset, regs); return; }
static int kern_do_signal(struct pt_regs *regs) { struct k_sigaction ka_copy; siginfo_t info; sigset_t *oldset; int sig, handled_sig = 0; if (test_thread_flag(TIF_RESTORE_SIGMASK)) oldset = ¤t->saved_sigmask; else oldset = ¤t->blocked; while ((sig = get_signal_to_deliver(&info, &ka_copy, regs, NULL)) > 0) { handled_sig = 1; if (!handle_signal(regs, sig, &ka_copy, &info, oldset)) { if (test_thread_flag(TIF_RESTORE_SIGMASK)) clear_thread_flag(TIF_RESTORE_SIGMASK); break; } } if (!handled_sig && (PT_REGS_SYSCALL_NR(regs) >= 0)) { switch (PT_REGS_SYSCALL_RET(regs)) { case -ERESTARTNOHAND: case -ERESTARTSYS: case -ERESTARTNOINTR: PT_REGS_ORIG_SYSCALL(regs) = PT_REGS_SYSCALL_NR(regs); PT_REGS_RESTART_SYSCALL(regs); break; case -ERESTART_RESTARTBLOCK: PT_REGS_ORIG_SYSCALL(regs) = __NR_restart_syscall; PT_REGS_RESTART_SYSCALL(regs); break; } } if (current->ptrace & PT_DTRACE) current->thread.singlestep_syscall = is_syscall(PT_REGS_IP(¤t->thread.regs)); if (!handled_sig && test_thread_flag(TIF_RESTORE_SIGMASK)) { clear_thread_flag(TIF_RESTORE_SIGMASK); sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } return handled_sig; }
/* * 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); } }
/* * 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. */ int do_signal(struct pt_regs *regs, sigset_t *oldset) { struct k_sigaction ka; siginfo_t info; 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(regs)) return 1; if (current->flags & PF_FREEZE) { refrigerator(0); goto no_signal; } if (!oldset) oldset = ¤t->blocked; signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { handle_signal(signr, &info, &ka, oldset, regs); return 1; } no_signal: /* Did we come from a system call? */ if (regs->syscallno >= 0) { /* Restart the system call - no handlers present */ if (regs->gr8 == -ERESTARTNOHAND || regs->gr8 == -ERESTARTSYS || regs->gr8 == -ERESTARTNOINTR) { regs->gr8 = regs->orig_gr8; regs->pc -= 4; } if (regs->gr8 == -ERESTART_RESTARTBLOCK){ regs->gr8 = __NR_restart_syscall; regs->pc -= 4; } } return 0; } /* 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. * * "r0" and "r19" are the registers we need to restore for system call * restart. "r0" is also used as an indicator whether we can restart at * all (if we get here from anything but a syscall return, it will be 0) */ static int do_signal(sigset_t *oldset, struct pt_regs * regs, struct switch_stack * sw, unsigned long r0, unsigned long r19) { siginfo_t info; int signr; unsigned long single_stepping = ptrace_cancel_bpt(current); struct k_sigaction ka; if (!oldset) oldset = ¤t->blocked; /* This lets the debugger run, ... */ signr = get_signal_to_deliver(&info, &ka, regs, NULL); /* ... so re-check the single stepping. */ single_stepping |= ptrace_cancel_bpt(current); if (signr > 0) { /* Whee! Actually deliver the signal. */ if (r0) syscall_restart(r0, r19, regs, &ka); handle_signal(signr, &ka, &info, oldset, regs, sw); if (single_stepping) ptrace_set_bpt(current); /* re-set bpt */ return 1; } if (r0) { switch (regs->r0) { case ERESTARTNOHAND: case ERESTARTSYS: case ERESTARTNOINTR: /* Reset v0 and a3 and replay syscall. */ regs->r0 = r0; regs->r19 = r19; regs->pc -= 4; break; case ERESTART_RESTARTBLOCK: /* Force v0 to the restart syscall and reply. */ regs->r0 = __NR_restart_syscall; regs->pc -= 4; break; } } if (single_stepping) ptrace_set_bpt(current); /* re-set breakpoint */ 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. */ asmlinkage 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 ((regs->ccr & 0x10)) return 1; if (current->flags & PF_FREEZE) { refrigerator(0); goto no_signal; } current->thread.esp0 = (unsigned long) regs; if (!oldset) oldset = ¤t->blocked; signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { /* Whee! Actually deliver the signal. */ handle_signal(signr, &info, &ka, oldset, regs); return 1; } no_signal: /* Did we come from a system call? */ if (regs->orig_er0 >= 0) { /* Restart the system call - no handlers present */ if (regs->er0 == -ERESTARTNOHAND || regs->er0 == -ERESTARTSYS || regs->er0 == -ERESTARTNOINTR) { regs->er0 = regs->orig_er0; regs->pc -= 2; } if (regs->er0 == -ERESTART_RESTARTBLOCK){ regs->er0 = __NR_restart_syscall; regs->pc -= 2; } } 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. * * "r0" and "r19" are the registers we need to restore for system call * restart. "r0" is also used as an indicator whether we can restart at * all (if we get here from anything but a syscall return, it will be 0) */ static void do_signal(struct pt_regs *regs, unsigned long r0, unsigned long r19) { siginfo_t info; int signr; unsigned long single_stepping = ptrace_cancel_bpt(current); struct k_sigaction ka; /* This lets the debugger run, ... */ signr = get_signal_to_deliver(&info, &ka, regs, NULL); /* ... so re-check the single stepping. */ single_stepping |= ptrace_cancel_bpt(current); if (signr > 0) { /* Whee! Actually deliver the signal. */ if (r0) syscall_restart(r0, r19, regs, &ka); handle_signal(signr, &ka, &info, regs); if (single_stepping) ptrace_set_bpt(current); /* re-set bpt */ return; } if (r0) { switch (regs->r0) { case ERESTARTNOHAND: case ERESTARTSYS: case ERESTARTNOINTR: /* Reset v0 and a3 and replay syscall. */ regs->r0 = r0; regs->r19 = r19; regs->pc -= 4; break; case ERESTART_RESTARTBLOCK: /* Force v0 to the restart syscall and reply. */ regs->r0 = __NR_restart_syscall; regs->pc -= 4; break; } } /* If there's no signal to deliver, we just restore the saved mask. */ restore_saved_sigmask(); if (single_stepping) ptrace_set_bpt(current); /* re-set breakpoint */ }
/* 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 int do_signal(sigset_t *oldset, struct pt_regs * regs, unsigned long orig_i0, int restart_syscall) { siginfo_t info; struct signal_deliver_cookie cookie; struct k_sigaction ka; int signr; cookie.restart_syscall = restart_syscall; cookie.orig_i0 = orig_i0; if (!oldset) oldset = ¤t->blocked; #ifdef CONFIG_SPARC32_COMPAT if (test_thread_flag(TIF_32BIT)) { extern int do_signal32(sigset_t *, struct pt_regs *, unsigned long, int); return do_signal32(oldset, regs, orig_i0, cookie.restart_syscall); } #endif signr = get_signal_to_deliver(&info, &ka, regs, &cookie); if (signr > 0) { if (cookie.restart_syscall) syscall_restart(orig_i0, regs, &ka.sa); handle_signal(signr, &ka, &info, oldset, regs); return 1; } if (cookie.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] = cookie.orig_i0; regs->tpc -= 4; regs->tnpc -= 4; } if (cookie.restart_syscall && regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { regs->u_regs[UREG_G1] = __NR_restart_syscall; regs->tpc -= 4; regs->tnpc -= 4; } 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) { 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, 0); if (signr > 0) { handle_syscall_restart(regs, &ka.sa); /* Whee! Actually deliver the signal. */ handle_signal(signr, &info, &ka, regs); return; } /* 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 */ restore_saved_sigmask(); }
asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset) { siginfo_t info; int signr; struct k_sigaction ka; /* */ if ((regs->ccr & 0x10)) return 1; if (try_to_freeze()) goto no_signal; current->thread.esp0 = (unsigned long) regs; if (!oldset) oldset = ¤t->blocked; signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { /* */ handle_signal(signr, &info, &ka, oldset, regs); return 1; } no_signal: /* */ if (regs->orig_er0 >= 0) { /* */ if (regs->er0 == -ERESTARTNOHAND || regs->er0 == -ERESTARTSYS || regs->er0 == -ERESTARTNOINTR) { regs->er0 = regs->orig_er0; regs->pc -= 2; } if (regs->er0 == -ERESTART_RESTARTBLOCK){ regs->er0 = __NR_restart_syscall; regs->pc -= 2; } } return 0; }
int do_signal32(sigset_t *oldset, struct pt_regs *regs) { struct k_sigaction ka; siginfo_t info; 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(regs)) return 1; if (try_to_freeze()) goto no_signal; if (!oldset) oldset = ¤t->blocked; signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) return handle_signal(signr, &info, &ka, oldset, regs); no_signal: /* * Who's code doesn't conform to the restartable syscall convention * dies here!!! The li instruction, a single machine instruction, * must directly be followed by the syscall instruction. */ if (regs->regs[0]) { if (regs->regs[2] == ERESTARTNOHAND || regs->regs[2] == ERESTARTSYS || regs->regs[2] == ERESTARTNOINTR) { regs->regs[7] = regs->regs[26]; regs->cp0_epc -= 8; } if (regs->regs[2] == ERESTART_RESTARTBLOCK) { regs->regs[2] = __NR_O32_restart_syscall; regs->regs[7] = regs->regs[26]; regs->cp0_epc -= 4; } } 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. */ static 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 (signr > 0) { /* Re-enable any watchpoints before delivering the * signal to user space. The processor register will * have been cleared if the watchpoint triggered * inside the kernel. */ /* Whee! Actually deliver the signal. */ handle_signal(signr, &ka, &info, regs); return; } /* Did we come from a system call? */ if (regs->syscall_nr >= 0) { /* Restart the system call - no handlers present */ if (regs->r0 == -ERESTARTNOHAND || regs->r0 == -ERESTARTSYS || regs->r0 == -ERESTARTNOINTR) { regs->r0 = regs->orig_r0; prev_insn(regs); } else if (regs->r0 == -ERESTART_RESTARTBLOCK){ regs->r0 = regs->orig_r0; regs->r7 = __NR_restart_syscall; prev_insn(regs); } } restore_saved_sigmask(); }
static int kern_do_signal(struct pt_regs *regs, sigset_t *oldset, int error) { siginfo_t info; struct k_sigaction *ka; int err, sig; if (!oldset) oldset = ¤t->blocked; sig = get_signal_to_deliver(&info, regs, NULL); if(sig == 0) return(0); /* Whee! Actually deliver the signal. */ ka = ¤t->sig->action[sig -1 ]; err = handle_signal(regs, sig, ka, &info, oldset, error); if(!err) return(1); /* Did we come from a system call? */ if(PT_REGS_SYSCALL_NR(regs) >= 0){ /* Restart the system call - no handlers present */ if(PT_REGS_SYSCALL_RET(regs) == -ERESTARTNOHAND || PT_REGS_SYSCALL_RET(regs) == -ERESTARTSYS || PT_REGS_SYSCALL_RET(regs) == -ERESTARTNOINTR){ PT_REGS_ORIG_SYSCALL(regs) = PT_REGS_SYSCALL_NR(regs); PT_REGS_RESTART_SYSCALL(regs); } else if(PT_REGS_SYSCALL_RET(regs) == -ERESTART_RESTARTBLOCK){ PT_REGS_SYSCALL_RET(regs) = __NR_restart_syscall; PT_REGS_RESTART_SYSCALL(regs); } } /* This closes a way to execute a system call on the host. If * you set a breakpoint on a system call instruction and singlestep * from it, the tracing thread used to PTRACE_SINGLESTEP the process * rather than PTRACE_SYSCALL it, allowing the system call to execute * on the host. The tracing thread will check this flag and * PTRACE_SYSCALL if necessary. */ if((current->ptrace & PT_DTRACE) && is_syscall(PT_REGS_IP(¤t->thread.regs))) (void) CHOOSE_MODE(current->thread.mode.tt.singlestep_syscall = 1, 0); return(0); }