/* * 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) { struct ksignal ksig; #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 if (get_signal(&ksig)) { /* Whee! Actually deliver the signal. */ if (in_syscall) handle_restart(regs, &ksig.ka, 1); handle_signal(&ksig, 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(); }
/* * 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 void do_signal(struct pt_regs *regs) { struct ksignal ksig; if (get_signal(&ksig)) { /* Actually deliver the signal */ handle_signal(&ksig, regs); return; } /* Did we come from a system call? */ if (regs->cause == EXC_SYSCALL) { /* Restart the system call - no handlers present */ switch (regs->v[0]) { case -ERESTARTNOHAND: case -ERESTARTSYS: case -ERESTARTNOINTR: regs->v[0] = regs->syscallno; regs->epc -= 0x4; break; case -ERESTART_RESTARTBLOCK: regs->v[0] = __NR_restart_syscall; regs->epc -= 0x4; break; } } /* If there is 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. * * 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) { struct ksignal ksig; if (get_signal(&ksig)) { handle_signal(&ksig, regs); return; } /* * If we were from a system call, check for system call restarting... */ if (in_syscall(regs)) { /* Restart the system call - no handlers present */ /* Avoid additional syscall restarting via ret_slow_syscall. */ forget_syscall(regs); switch (regs->uregs[0]) { case -ERESTART_RESTARTBLOCK: regs->uregs[15] = __NR_restart_syscall; case -ERESTARTNOHAND: case -ERESTARTSYS: case -ERESTARTNOINTR: regs->uregs[0] = regs->orig_r0; regs->ipc -= 0x4; break; } } restore_saved_sigmask(); }
/* * handle a potential signal */ static void do_signal(struct pt_regs *regs) { struct ksignal ksig; if (get_signal(&ksig)) { handle_signal(&ksig, regs); return; } /* did we come from a system call? */ if (regs->orig_d0 >= 0) { /* restart the system call - no handlers present */ switch (regs->d0) { case -ERESTARTNOHAND: case -ERESTARTSYS: case -ERESTARTNOINTR: regs->d0 = regs->orig_d0; stepback(regs); break; case -ERESTART_RESTARTBLOCK: regs->d0 = __NR_restart_syscall; stepback(regs); break; } } /* if there's no signal to deliver, we just put the saved sigmask * back */ restore_saved_sigmask(); }
static void do_signal(struct pt_regs *regs) { struct ksignal ksig; if (get_signal(&ksig)) { /* Whee! Actually deliver the signal. */ handle_signal(&ksig, regs); return; } if (regs->regs[0]) { switch (regs->regs[2]) { case ERESTARTNOHAND: case ERESTARTSYS: case ERESTARTNOINTR: regs->regs[2] = regs->regs[0]; regs->regs[7] = regs->regs[26]; regs->cp0_epc -= 4; break; case ERESTART_RESTARTBLOCK: regs->regs[2] = current->thread.abi->restart; regs->regs[7] = regs->regs[26]; regs->cp0_epc -= 4; break; } regs->regs[0] = 0; /* Don't deal with this again. */ } /* * 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. */ static void do_signal(void) { struct ksignal ksig; if (get_signal(&ksig)) { handle_signal(&ksig); return; } /* 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 */ restore_saved_sigmask(); } /* end do_signal() */
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; }
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. * * 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(); }
void do_signal(int canrestart, 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) { /* Whee! Actually deliver the signal. */ if (handle_signal(canrestart, signr, &info, &ka, 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->r9 = __NR_restart_syscall; regs->irp -= 2; } } /* 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. * * 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 in_syscall) { struct ksignal ksig; /* Did we come from a system call? */ if (get_signal(&ksig)) { if (in_syscall) { switch (regs->r1) { case -ERESTART_RESTARTBLOCK: case -ERESTARTNOHAND: regs->r1 = -EINTR; break; case -ERESTARTSYS: if (!(ksig.ka.sa.sa_flags & SA_RESTART)) { regs->r1 = -EINTR; break; } /* fallthrough */ case -ERESTARTNOINTR: regs->ea -= 4; /* Size of scall insn. */ regs->r1 = regs->orig_r1; break; default: break; } } handle_signal(&ksig, regs); } else { /* If there is no handler always restart */ if (in_syscall) { switch (regs->r1) { case -ERESTART_RESTARTBLOCK: regs->r8 = __NR_restart_syscall; /* fallthrough */ case -ERESTARTNOHAND: case -ERESTARTSYS: case -ERESTARTNOINTR: regs->ea -= 4; /* Size of scall insn. */ regs->r1 = regs->orig_r1; break; default: break; } } 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. * * 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. * * 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(); }
/* * 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(); }
/* * 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) { struct ksignal ksig; current->thread.esp0 = (unsigned long) regs; if (get_signal(&ksig)) { /* Whee! Actually deliver the signal. */ handle_signal(&ksig, regs); return; } /* Did we come from a system call? */ if (regs->orig_er0 >= 0) handle_restart(regs, NULL); /* If there's no signal to deliver, we just restore the saved mask. */ 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. * * 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; /* * 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_syscall_restart(save_r0, regs, &ka.sa); /* Whee! Actually deliver the signal. */ handle_signal(signr, &ka, &info, regs, save_r0); 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. */ 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. */ void do_signal(struct pt_regs *regs) { struct ksignal ksig; /* * i386 will check if we're coming from kernel mode and bail out * here. In my experience this just turns weird crashes into * weird spin-hangs. But if we find a case where this seems * helpful, we can reinstate the check on "!user_mode(regs)". */ if (get_signal(&ksig)) { /* Whee! Actually deliver the signal. */ handle_signal(&ksig, regs); goto done; } /* Did we come from a system call? */ if (regs->faultnum == INT_SWINT_1) { /* Restart the system call - no handlers present */ 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 there's no signal to deliver, just put the saved sigmask back. */ restore_saved_sigmask(); done: /* Avoid double syscall restart if there are nested signals. */ regs->faultnum = INT_SWINT_1_SIGRETURN; }
/* * 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, 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; 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 */ restore_saved_sigmask(); return; } handle_signal(signr, &ka, &info, regs, syscall); }
static void do_signal(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; signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { /* Whee! Actually deliver the signal. */ handle_signal(signr, &info, &ka, regs); return; } if (regs->regs[0]) { if (regs->regs[2] == ERESTARTNOHAND || regs->regs[2] == ERESTARTSYS || regs->regs[2] == ERESTARTNOINTR) { regs->regs[2] = regs->regs[0]; regs->regs[7] = regs->regs[26]; regs->cp0_epc -= 4; } if (regs->regs[2] == ERESTART_RESTARTBLOCK) { regs->regs[2] = current->thread.abi->restart; regs->regs[7] = regs->regs[26]; regs->cp0_epc -= 4; } regs->regs[0] = 0; /* Don't deal with this again. */ } /* * 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. */ 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 ((regs->ccr & 0x10)) return; current->thread.esp0 = (unsigned long) regs; signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { /* Whee! Actually deliver the signal. */ handle_signal(signr, &info, &ka, regs); return; } /* 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; } } /* If there's no signal to deliver, we just restore the saved mask. */ restore_saved_sigmask(); }
void do_signal(int canrestart, 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) { /* Whee! Actually deliver the signal. */ handle_signal(canrestart, signr, &info, &ka, regs); 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->r9 = __NR_restart_syscall; regs->irp -= 2; } } /* if there's no signal to deliver, we just put the saved sigmask * back */ restore_saved_sigmask(); }
/* * handle a potential signal */ 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 */ if (!user_mode(regs)) return; signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { handle_signal(signr, &info, &ka, regs, syscall); 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 */ restore_saved_sigmask(); }
/* * 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; signo = get_signal_to_deliver(&info, &sigact, regs, NULL); if (signo > 0) { handle_signal(signo, &info, &sigact, regs); return; } /* * 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 */ restore_saved_sigmask(); }
static void do_signal(struct pt_regs *regs) { struct k_sigaction ka; siginfo_t info; int signr; signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { /* Whee! Actually deliver the signal. */ handle_signal(signr, &info, &ka, regs); return; } if (regs->regs[0]) { switch (regs->regs[2]) { case ERESTARTNOHAND: case ERESTARTSYS: case ERESTARTNOINTR: regs->regs[2] = regs->regs[0]; regs->regs[7] = regs->regs[26]; regs->cp0_epc -= 4; break; case ERESTART_RESTARTBLOCK: regs->regs[2] = current->thread.abi->restart; regs->regs[7] = regs->regs[26]; regs->cp0_epc -= 4; break; } regs->regs[0] = 0; /* Don't deal with this again. */ } /* * If there's no signal to deliver, we just put the saved sigmask * back */ restore_saved_sigmask(); }
static void do_signal(struct pt_regs *regs) { struct ksignal ksig; if (get_signal(&ksig)) { /* Actually deliver the signal */ handle_signal(&ksig, regs); return; } /* Did we come from a system call? */ if (in_syscall(regs)) { /* Avoid additional syscall restarting via ret_from_exception */ forget_syscall(regs); /* Restart the system call - no handlers present */ switch (regs->a0) { case -ERESTARTNOHAND: case -ERESTARTSYS: case -ERESTARTNOINTR: regs->a0 = regs->orig_a0; regs->pc -= TRAP0_SIZE; break; case -ERESTART_RESTARTBLOCK: regs->a0 = regs->orig_a0; regs_syscallid(regs) = __NR_restart_syscall; regs->pc -= TRAP0_SIZE; break; } } /* * If there is no signal to deliver, we just put the saved * sigmask back. */ restore_saved_sigmask(); }
/* * handle a potential signal */ static void do_signal(struct pt_regs *regs) { struct k_sigaction ka; siginfo_t info; int signr; signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { if (handle_signal(signr, &info, &ka, regs) == 0) { } return; } /* did we come from a system call? */ if (regs->orig_d0 >= 0) { /* restart the system call - no handlers present */ switch (regs->d0) { case -ERESTARTNOHAND: case -ERESTARTSYS: case -ERESTARTNOINTR: regs->d0 = regs->orig_d0; stepback(regs); break; case -ERESTART_RESTARTBLOCK: regs->d0 = __NR_restart_syscall; stepback(regs); break; } } /* 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. * * 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; current->thread.esp0 = (unsigned long)regs; signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { /* Whee! Actually deliver the signal. */ handle_signal(signr, &info, &ka, regs); return; } /* 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 */ restore_saved_sigmask(); }
void do_signal(struct pt_regs *regs) { struct k_sigaction ka; siginfo_t info; int signr; int restart_scall; signr = get_signal_to_deliver(&info, &ka, regs, NULL); restart_scall = in_syscall(regs) && syscall_restartable(regs); if (signr > 0) { if (restart_scall) { arc_restart_syscall(&ka, regs); syscall_wont_restart(regs); /* No more restarts */ } handle_signal(signr, &ka, &info, regs); return; } if (restart_scall) { /* No handler for syscall: restart it */ if (regs->r0 == -ERESTARTNOHAND || regs->r0 == -ERESTARTSYS || regs->r0 == -ERESTARTNOINTR) { regs->r0 = regs->orig_r0; regs->ret -= 4; } else if (regs->r0 == -ERESTART_RESTARTBLOCK) { regs->r8 = __NR_restart_syscall; regs->ret -= 4; } syscall_wont_restart(regs); /* No more restarts */ } /* If there's no signal to deliver, restore 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. */ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) { struct k_sigaction ka; int restart_syscall; sigset_t *oldset = sigmask_to_save(); siginfo_t info; int signr; /* It's a lot of work and synchronization to add a new ptrace * register for GDB to save and restore in order to get * orig_i0 correct for syscall restarts when debugging. * * Although it should be the case that most of the global * registers are volatile across a system call, glibc already * depends upon that fact that we preserve them. So we can't * just use any global register to save away the orig_i0 value. * * In particular %g2, %g3, %g4, and %g5 are all assumed to be * preserved across a system call trap by various pieces of * code in glibc. * * %g7 is used as the "thread register". %g6 is not used in * any fixed manner. %g6 is used as a scratch register and * a compiler temporary, but it's value is never used across * a system call. Therefore %g6 is usable for orig_i0 storage. */ if (pt_regs_is_syscall(regs) && (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) regs->u_regs[UREG_G6] = orig_i0; #ifdef CONFIG_COMPAT if (test_thread_flag(TIF_32BIT)) { extern void do_signal32(sigset_t *, struct pt_regs *); do_signal32(oldset, regs); return; } #endif signr = get_signal_to_deliver(&info, &ka, regs, NULL); restart_syscall = 0; if (pt_regs_is_syscall(regs) && (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) { restart_syscall = 1; orig_i0 = regs->u_regs[UREG_G6]; } if (signr > 0) { if (restart_syscall) syscall_restart(orig_i0, regs, &ka.sa); handle_signal(signr, &ka, &info, oldset, regs); 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; pt_regs_clear_syscall(regs); } if (restart_syscall && regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { regs->u_regs[UREG_G1] = __NR_restart_syscall; regs->tpc -= 4; regs->tnpc -= 4; pt_regs_clear_syscall(regs); } /* If there's no signal to deliver, we just put the saved sigmask * back */ restore_saved_sigmask(); }