/* * OK, we're invoking a handler */ static void handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, struct pt_regs *regs) { struct thread_info *thread = current_thread_info(); struct task_struct *tsk = current; sigset_t *oldset = sigmask_to_save(); 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; } signal_delivered(sig, info, ka, regs, 0); }
static void handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, struct pt_regs *regs) { /* Are we from a system call? */ if (regs->syscall_nr >= 0) { /* If so, check system call restarting.. */ switch (regs->r0) { case -ERESTART_RESTARTBLOCK: case -ERESTARTNOHAND: regs->r0 = -EINTR; break; case -ERESTARTSYS: if (!(ka->sa.sa_flags & SA_RESTART)) { regs->r0 = -EINTR; break; } /* fallthrough */ case -ERESTARTNOINTR: regs->r0 = regs->orig_r0; if (prev_insn(regs) < 0) return; } } /* Set up the stack frame */ if (setup_rt_frame(sig, ka, info, sigmask_to_save(), regs)) return; signal_delivered(sig, info, ka, regs, 0); }
/* * OK, we're invoking a handler */ static void handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, struct pt_regs * regs) { sigset_t *oldset = sigmask_to_save(); int ret; /* are we from a system call? */ if (regs->orig_er0 >= 0) { switch (regs->er0) { case -ERESTART_RESTARTBLOCK: case -ERESTARTNOHAND: regs->er0 = -EINTR; break; case -ERESTARTSYS: if (!(ka->sa.sa_flags & SA_RESTART)) { regs->er0 = -EINTR; break; } /* fallthrough */ case -ERESTARTNOINTR: regs->er0 = regs->orig_er0; regs->pc -= 2; } } /* set up the stack frame */ if (ka->sa.sa_flags & SA_SIGINFO) ret = setup_rt_frame(sig, ka, info, oldset, regs); else ret = setup_frame(sig, ka, oldset, regs); if (!ret) signal_delivered(sig, info, ka, regs, 0); }
/* * handle the actual delivery of a signal to userspace */ static void handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka, struct pt_regs *regs, int syscall) { int ret; /* Are we from a system call? */ if (syscall) { /* If so, check system call restarting.. */ switch (regs->a4) { case -ERESTART_RESTARTBLOCK: case -ERESTARTNOHAND: regs->a4 = -EINTR; break; case -ERESTARTSYS: if (!(ka->sa.sa_flags & SA_RESTART)) { regs->a4 = -EINTR; break; } /* fallthrough */ case -ERESTARTNOINTR: regs->a4 = regs->orig_a4; regs->pc -= 4; } } /* Set up the stack frame */ if (setup_rt_frame(sig, ka, info, sigmask_to_save(), regs) < 0) return; signal_delivered(sig, info, ka, regs, 0); }
/* * OK, we're invoking a handler */ static void handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, struct pt_regs *regs, int syscall) { struct thread_info *thread = current_thread_info(); struct task_struct *tsk = current; sigset_t *oldset = sigmask_to_save(); int usig = sig; int ret; /* * If we were from a system call, check for system call restarting... */ if (syscall) { switch (regs->UCreg_00) { case -ERESTART_RESTARTBLOCK: case -ERESTARTNOHAND: regs->UCreg_00 = -EINTR; break; case -ERESTARTSYS: if (!(ka->sa.sa_flags & SA_RESTART)) { regs->UCreg_00 = -EINTR; break; } /* fallthrough */ case -ERESTARTNOINTR: setup_syscall_restart(regs); } } /* * 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; } signal_delivered(sig, info, ka, regs, 0); }
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; }
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; signal_delivered(sig, info, ka, &scr->pt, test_thread_flag(TIF_SINGLESTEP)); return 1; }
static inline void 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; signal_delivered(signr, info, ka, regs, 0); }
static void handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, struct pt_regs *regs) { sigset_t *oldset = sigmask_to_save(); int ret; struct mips_abi *abi = current->thread.abi; #ifdef CONFIG_CPU_MICROMIPS void *vdso; unsigned int tmp = (unsigned int)current->mm->context.vdso; set_isa16_mode(tmp); vdso = (void *)tmp; #else void *vdso = current->mm->context.vdso; #endif if (regs->regs[0]) { switch(regs->regs[2]) { case ERESTART_RESTARTBLOCK: case ERESTARTNOHAND: regs->regs[2] = EINTR; break; case ERESTARTSYS: if (!(ka->sa.sa_flags & SA_RESTART)) { regs->regs[2] = EINTR; break; } /* fallthrough */ case ERESTARTNOINTR: regs->regs[7] = regs->regs[26]; regs->regs[2] = regs->regs[0]; regs->cp0_epc -= 4; } regs->regs[0] = 0; /* Don't deal with this again. */ } if (sig_uses_siginfo(ka)) ret = abi->setup_rt_frame(vdso + abi->rt_signal_return_offset, ka, regs, sig, oldset, info); else ret = abi->setup_frame(vdso + abi->signal_return_offset, ka, regs, sig, oldset); if (ret) return; signal_delivered(sig, info, ka, regs, 0); }
void handle_signal32(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *oldset, struct pt_regs *regs) { int ret; /* Set up the stack frame */ if (ka->sa.sa_flags & SA_SIGINFO) ret = setup_rt_frame32(sig, ka, info, oldset, regs); else ret = setup_frame32(sig, ka, oldset, regs); if (ret) return; signal_delivered(sig, info, ka, regs, test_thread_flag(TIF_SINGLE_STEP)); }
/* * OK, we're invoking a handler */ static void handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, struct pt_regs *regs) { sigset_t *oldset = sigmask_to_save(); int ret; /* Set up the stack frame */ ret = setup_rt_frame(sig, ka, info, oldset, regs); if (ret) force_sigsegv(sig, current); else signal_delivered(sig, info, ka, regs, 0); }
/* * OK, we're invoking a handler */ static void handle_signal(struct pt_regs *regs, unsigned long signr, struct k_sigaction *ka, siginfo_t *info) { sigset_t *oldset = sigmask_to_save(); unsigned long sp; int err; /* Always make any pending restarted system calls return -EINTR */ current_thread_info()->restart_block.fn = do_no_restart_syscall; /* Did we come from a system call? */ if (PT_REGS_SYSCALL_NR(regs) >= 0) { /* If so, check system call restarting.. */ switch (PT_REGS_SYSCALL_RET(regs)) { case -ERESTART_RESTARTBLOCK: case -ERESTARTNOHAND: PT_REGS_SYSCALL_RET(regs) = -EINTR; break; case -ERESTARTSYS: if (!(ka->sa.sa_flags & SA_RESTART)) { PT_REGS_SYSCALL_RET(regs) = -EINTR; break; } /* fallthrough */ case -ERESTARTNOINTR: PT_REGS_RESTART_SYSCALL(regs); PT_REGS_ORIG_SYSCALL(regs) = PT_REGS_SYSCALL_NR(regs); break; } } sp = PT_REGS_SP(regs); if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0)) sp = current->sas_ss_sp + current->sas_ss_size; #ifdef CONFIG_ARCH_HAS_SC_SIGNALS if (!(ka->sa.sa_flags & SA_SIGINFO)) err = setup_signal_stack_sc(sp, signr, ka, regs, oldset); else #endif err = setup_signal_stack_si(sp, signr, ka, regs, info, oldset); if (err) force_sigsegv(signr, current); else signal_delivered(signr, info, ka, regs, 0); }
/* * OK, we're invoking a handler */ static void handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka, struct pt_regs *regs) { /* are we from a system call? to see pt_regs->orig_p0 */ if (regs->orig_p0 >= 0) /* If so, check system call restarting.. */ handle_restart(regs, ka, 1); /* set up the stack frame */ if (setup_rt_frame(sig, ka, info, sigmask_to_save(), regs) < 0) force_sigsegv(sig, current); else signal_delivered(sig, info, ka, regs, test_thread_flag(TIF_SINGLESTEP)); }
static inline void handle_signal(unsigned long signr, struct k_sigaction *ka, siginfo_t *info, struct pt_regs *regs) { sigset_t *oldset = sigmask_to_save(); 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; signal_delivered(signr, info, ka, regs, 0); }
/* * OK, we're invoking a handler. */ static inline void handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, struct pt_regs * regs) { sigset_t *oldset = sigmask_to_save(); int ret; if (ka->sa.sa_flags & SA_SIGINFO) ret = setup_rt_frame(sig, ka, info, oldset, regs); else ret = setup_frame(sig, ka, oldset, regs); if (ret) { force_sigsegv(sig, current); return; } signal_delivered(sig, info, ka, regs, 0); }
static inline void handle_signal(int canrestart, unsigned long sig, siginfo_t *info, struct k_sigaction *ka, struct pt_regs *regs) { sigset_t *oldset = sigmask_to_save(); int ret; /* Are we from a system call? */ if (canrestart) { /* If so, check system call restarting.. */ switch (regs->r10) { case -ERESTART_RESTARTBLOCK: case -ERESTARTNOHAND: /* ERESTARTNOHAND means that the syscall should * only be restarted if there was no handler for * the signal, and since we only get here if there * is a handler, we don't restart */ regs->r10 = -EINTR; break; case -ERESTARTSYS: /* ERESTARTSYS means to restart the syscall if * there is no handler or the handler was * registered with SA_RESTART */ if (!(ka->sa.sa_flags & SA_RESTART)) { regs->r10 = -EINTR; break; } /* fallthrough */ case -ERESTARTNOINTR: /* ERESTARTNOINTR means that the syscall should * be called again after the signal handler returns. */ RESTART_CRIS_SYS(regs); } } /* Set up the stack frame */ if (ka->sa.sa_flags & SA_SIGINFO) ret = setup_rt_frame(sig, ka, info, oldset, regs); else ret = setup_frame(sig, ka, oldset, regs); if (ret == 0) signal_delivered(sig, info, ka, regs, 0); }
/* * Setup invocation of signal handler */ static void handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka, struct pt_regs *regs) { /* * If we're handling a signal that aborted a system call, * set up the error return value before adding the signal * frame to the stack. */ if (regs->syscall_nr >= 0) { switch (regs->r00) { case -ERESTART_RESTARTBLOCK: case -ERESTARTNOHAND: regs->r00 = -EINTR; break; case -ERESTARTSYS: if (!(ka->sa.sa_flags & SA_RESTART)) { regs->r00 = -EINTR; break; } /* Fall through */ case -ERESTARTNOINTR: regs->r06 = regs->syscall_nr; pt_set_elr(regs, pt_elr(regs) - 4); regs->r00 = regs->restart_r0; break; default: break; } } /* * Set up the stack frame; not doing the SA_SIGINFO thing. We * only set up the rt_frame flavor. */ /* If there was an error on setup, no signal was delivered. */ if (setup_rt_frame(sig, ka, info, sigmask_to_save(), regs) < 0) return; signal_delivered(sig, info, ka, regs, test_thread_flag(TIF_SINGLESTEP)); }
/* * handle the actual delivery of a signal to userspace */ static int handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka, struct pt_regs *regs) { sigset_t *oldset = sigmask_to_save(); int ret; /* Are we from a system call? */ if (regs->orig_d0 >= 0) { /* If so, check system call restarting.. */ switch (regs->d0) { case -ERESTART_RESTARTBLOCK: case -ERESTARTNOHAND: regs->d0 = -EINTR; break; case -ERESTARTSYS: if (!(ka->sa.sa_flags & SA_RESTART)) { regs->d0 = -EINTR; break; } /* fallthrough */ case -ERESTARTNOINTR: regs->d0 = regs->orig_d0; stepback(regs); } } /* Set up the stack frame */ if (ka->sa.sa_flags & SA_SIGINFO) ret = setup_rt_frame(sig, ka, info, oldset, regs); else ret = setup_frame(sig, ka, oldset, regs); if (ret) return ret; signal_delivered(sig, info, ka, regs, test_thread_flag(TIF_SINGLESTEP)); return 0; }
/* * OK, we're invoking a handler */ static void handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, struct pt_regs *regs) { struct task_struct *tsk = current; sigset_t *oldset = sigmask_to_save(); int usig = sig; int ret; /* * Set up the stack frame */ if (is_compat_task()) { if (ka->sa.sa_flags & SA_SIGINFO) ret = compat_setup_rt_frame(usig, ka, info, oldset, regs); else ret = compat_setup_frame(usig, ka, oldset, regs); } else { ret = setup_rt_frame(usig, ka, info, oldset, regs); } /* * Check that the resulting registers are actually sane. */ ret |= !valid_user_regs(®s->user_regs); if (ret != 0) { force_sigsegv(sig, tsk); return; } /* * Fast forward the stepping logic so we step into the signal * handler. */ user_fastforward_single_step(tsk); signal_delivered(sig, info, ka, regs, 0); }
static inline void handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, struct pt_regs *regs, int syscall) { int ret; /* * Set up the stack frame */ ret = setup_rt_frame(sig, ka, info, sigmask_to_save(), regs); /* * Check that the resulting registers are sane */ ret |= !valid_user_regs(regs); /* * Block the signal if we were successful. */ if (ret != 0) force_sigsegv(sig, current); else signal_delivered(sig, info, ka, regs, 0); }