static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) { sigset_t *oldset = sigmask_to_save(); int ret; /* Are we from a system call? */ if (in_syscall(regs)) { /* Avoid additional syscall restarting via ret_from_exception */ forget_syscall(regs); /* If so, check system call restarting.. */ switch (regs->a0) { case -ERESTART_RESTARTBLOCK: case -ERESTARTNOHAND: regs->a0 = -EINTR; break; case -ERESTARTSYS: if (!(ksig->ka.sa.sa_flags & SA_RESTART)) { regs->a0 = -EINTR; break; } /* fallthrough */ case -ERESTARTNOINTR: regs->a0 = regs->orig_a0; regs->pc -= TRAP0_SIZE; break; } } /* Set up the stack frame */ ret = setup_rt_frame(ksig, oldset, regs); signal_setup_done(ret, ksig, 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) { 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(); }
/* * OK, we're invoking a handler */ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) { int ret; sigset_t *oldset = sigmask_to_save(); if (in_syscall(regs)) { /* Avoid additional syscall restarting via ret_slow_syscall. */ forget_syscall(regs); switch (regs->uregs[0]) { case -ERESTART_RESTARTBLOCK: case -ERESTARTNOHAND: regs->uregs[0] = -EINTR; break; case -ERESTARTSYS: if (!(ksig->ka.sa.sa_flags & SA_RESTART)) { regs->uregs[0] = -EINTR; break; } case -ERESTARTNOINTR: regs->uregs[0] = regs->orig_r0; regs->ipc -= 4; break; } } /* * Set up the stack frame */ ret = setup_rt_frame(ksig, oldset, regs); signal_setup_done(ret, ksig, 0); }
/* * OK, we're invoking a handler */ static int handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, sigset_t *oldset) { int ret; /* Are we from a system call? */ if (in_syscall(__frame)) { /* If so, check system call restarting.. */ switch (__frame->gr8) { case -ERESTART_RESTARTBLOCK: case -ERESTARTNOHAND: __frame->gr8 = -EINTR; break; case -ERESTARTSYS: if (!(ka->sa.sa_flags & SA_RESTART)) { __frame->gr8 = -EINTR; break; } /* fallthrough */ case -ERESTARTNOINTR: __frame->gr8 = __frame->orig_gr8; __frame->pc -= 4; } } /* Set up the stack frame */ if (ka->sa.sa_flags & SA_SIGINFO) ret = setup_rt_frame(sig, ka, info, oldset); else ret = setup_frame(sig, ka, oldset); if (ret == 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); } return ret; } /* end handle_signal() */
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(); }
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(); }