Loading arch/alpha/kernel/signal.c +45 −66 Original line number Diff line number Diff line Loading @@ -272,12 +272,9 @@ give_sigsegv: */ static inline void __user * get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size) get_sigframe(struct ksignal *ksig, unsigned long sp, size_t frame_size) { if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! sas_ss_flags(sp)) sp = current->sas_ss_sp + current->sas_ss_size; return (void __user *)((sp - frame_size) & -32ul); return (void __user *)((sigsp(sp, ksig) - frame_size) & -32ul); } static long Loading Loading @@ -338,14 +335,13 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, } static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, struct pt_regs *regs) setup_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs) { unsigned long oldsp, r26, err = 0; struct sigframe __user *frame; oldsp = rdusp(); frame = get_sigframe(ka, oldsp, sizeof(*frame)); frame = get_sigframe(ksig, oldsp, sizeof(*frame)); if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) return -EFAULT; Loading @@ -355,9 +351,8 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, /* Set up to return from userspace. If provided, use a stub already in userspace. */ if (ka->ka_restorer) { r26 = (unsigned long) ka->ka_restorer; } else { r26 = (unsigned long) ksig->ka.ka_restorer; if (!r26) { err |= __put_user(INSN_MOV_R30_R16, frame->retcode+0); err |= __put_user(INSN_LDI_R0+__NR_sigreturn, frame->retcode+1); err |= __put_user(INSN_CALLSYS, frame->retcode+2); Loading @@ -371,8 +366,8 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, /* "Return" to the handler */ regs->r26 = r26; regs->r27 = regs->pc = (unsigned long) ka->sa.sa_handler; regs->r16 = sig; /* a0: signal number */ regs->r27 = regs->pc = (unsigned long) ksig->ka.sa.sa_handler; regs->r16 = ksig->sig; /* a0: signal number */ regs->r17 = 0; /* a1: exception code */ regs->r18 = (unsigned long) &frame->sc; /* a2: sigcontext pointer */ wrusp((unsigned long) frame); Loading @@ -385,18 +380,17 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, } static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set, struct pt_regs *regs) setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs) { unsigned long oldsp, r26, err = 0; struct rt_sigframe __user *frame; oldsp = rdusp(); frame = get_sigframe(ka, oldsp, sizeof(*frame)); frame = get_sigframe(ksig, oldsp, sizeof(*frame)); if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) return -EFAULT; err |= copy_siginfo_to_user(&frame->info, info); err |= copy_siginfo_to_user(&frame->info, &ksig->info); /* Create the ucontext. */ err |= __put_user(0, &frame->uc.uc_flags); Loading @@ -411,9 +405,8 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, /* Set up to return from userspace. If provided, use a stub already in userspace. */ if (ka->ka_restorer) { r26 = (unsigned long) ka->ka_restorer; } else { r26 = (unsigned long) ksig->ka.ka_restorer; if (!r26) { err |= __put_user(INSN_MOV_R30_R16, frame->retcode+0); err |= __put_user(INSN_LDI_R0+__NR_rt_sigreturn, frame->retcode+1); Loading @@ -427,8 +420,8 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, /* "Return" to the handler */ regs->r26 = r26; regs->r27 = regs->pc = (unsigned long) ka->sa.sa_handler; regs->r16 = sig; /* a0: signal number */ regs->r27 = regs->pc = (unsigned long) ksig->ka.sa.sa_handler; regs->r16 = ksig->sig; /* a0: signal number */ regs->r17 = (unsigned long) &frame->info; /* a1: siginfo pointer */ regs->r18 = (unsigned long) &frame->uc; /* a2: ucontext pointer */ wrusp((unsigned long) frame); Loading @@ -446,22 +439,17 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, * OK, we're invoking a handler. */ static inline void handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, struct pt_regs * regs) handle_signal(struct ksignal *ksig, 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); if (ksig->ka.sa.sa_flags & SA_SIGINFO) ret = setup_rt_frame(ksig, oldset, regs); else ret = setup_frame(sig, ka, oldset, regs); ret = setup_frame(ksig, oldset, regs); if (ret) { force_sigsegv(sig, current); return; } signal_delivered(sig, info, ka, regs, 0); signal_setup_done(ret, ksig, 0); } static inline void Loading Loading @@ -504,27 +492,19 @@ syscall_restart(unsigned long r0, unsigned long r19, 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; struct ksignal ksig; /* This lets the debugger run, ... */ signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (get_signal(&ksig)) { /* ... 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; } syscall_restart(r0, r19, regs, &ksig.ka); handle_signal(&ksig, regs); } else { single_stepping |= ptrace_cancel_bpt(current); if (r0) { switch (regs->r0) { case ERESTARTNOHAND: Loading @@ -536,15 +516,14 @@ do_signal(struct pt_regs *regs, unsigned long r0, unsigned long r19) regs->pc -= 4; break; case ERESTART_RESTARTBLOCK: /* Force v0 to the restart syscall and reply. */ /* Set v0 to the restart_syscall and replay */ 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 */ } Loading Loading
arch/alpha/kernel/signal.c +45 −66 Original line number Diff line number Diff line Loading @@ -272,12 +272,9 @@ give_sigsegv: */ static inline void __user * get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size) get_sigframe(struct ksignal *ksig, unsigned long sp, size_t frame_size) { if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! sas_ss_flags(sp)) sp = current->sas_ss_sp + current->sas_ss_size; return (void __user *)((sp - frame_size) & -32ul); return (void __user *)((sigsp(sp, ksig) - frame_size) & -32ul); } static long Loading Loading @@ -338,14 +335,13 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, } static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, struct pt_regs *regs) setup_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs) { unsigned long oldsp, r26, err = 0; struct sigframe __user *frame; oldsp = rdusp(); frame = get_sigframe(ka, oldsp, sizeof(*frame)); frame = get_sigframe(ksig, oldsp, sizeof(*frame)); if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) return -EFAULT; Loading @@ -355,9 +351,8 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, /* Set up to return from userspace. If provided, use a stub already in userspace. */ if (ka->ka_restorer) { r26 = (unsigned long) ka->ka_restorer; } else { r26 = (unsigned long) ksig->ka.ka_restorer; if (!r26) { err |= __put_user(INSN_MOV_R30_R16, frame->retcode+0); err |= __put_user(INSN_LDI_R0+__NR_sigreturn, frame->retcode+1); err |= __put_user(INSN_CALLSYS, frame->retcode+2); Loading @@ -371,8 +366,8 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, /* "Return" to the handler */ regs->r26 = r26; regs->r27 = regs->pc = (unsigned long) ka->sa.sa_handler; regs->r16 = sig; /* a0: signal number */ regs->r27 = regs->pc = (unsigned long) ksig->ka.sa.sa_handler; regs->r16 = ksig->sig; /* a0: signal number */ regs->r17 = 0; /* a1: exception code */ regs->r18 = (unsigned long) &frame->sc; /* a2: sigcontext pointer */ wrusp((unsigned long) frame); Loading @@ -385,18 +380,17 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, } static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set, struct pt_regs *regs) setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs) { unsigned long oldsp, r26, err = 0; struct rt_sigframe __user *frame; oldsp = rdusp(); frame = get_sigframe(ka, oldsp, sizeof(*frame)); frame = get_sigframe(ksig, oldsp, sizeof(*frame)); if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) return -EFAULT; err |= copy_siginfo_to_user(&frame->info, info); err |= copy_siginfo_to_user(&frame->info, &ksig->info); /* Create the ucontext. */ err |= __put_user(0, &frame->uc.uc_flags); Loading @@ -411,9 +405,8 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, /* Set up to return from userspace. If provided, use a stub already in userspace. */ if (ka->ka_restorer) { r26 = (unsigned long) ka->ka_restorer; } else { r26 = (unsigned long) ksig->ka.ka_restorer; if (!r26) { err |= __put_user(INSN_MOV_R30_R16, frame->retcode+0); err |= __put_user(INSN_LDI_R0+__NR_rt_sigreturn, frame->retcode+1); Loading @@ -427,8 +420,8 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, /* "Return" to the handler */ regs->r26 = r26; regs->r27 = regs->pc = (unsigned long) ka->sa.sa_handler; regs->r16 = sig; /* a0: signal number */ regs->r27 = regs->pc = (unsigned long) ksig->ka.sa.sa_handler; regs->r16 = ksig->sig; /* a0: signal number */ regs->r17 = (unsigned long) &frame->info; /* a1: siginfo pointer */ regs->r18 = (unsigned long) &frame->uc; /* a2: ucontext pointer */ wrusp((unsigned long) frame); Loading @@ -446,22 +439,17 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, * OK, we're invoking a handler. */ static inline void handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, struct pt_regs * regs) handle_signal(struct ksignal *ksig, 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); if (ksig->ka.sa.sa_flags & SA_SIGINFO) ret = setup_rt_frame(ksig, oldset, regs); else ret = setup_frame(sig, ka, oldset, regs); ret = setup_frame(ksig, oldset, regs); if (ret) { force_sigsegv(sig, current); return; } signal_delivered(sig, info, ka, regs, 0); signal_setup_done(ret, ksig, 0); } static inline void Loading Loading @@ -504,27 +492,19 @@ syscall_restart(unsigned long r0, unsigned long r19, 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; struct ksignal ksig; /* This lets the debugger run, ... */ signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (get_signal(&ksig)) { /* ... 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; } syscall_restart(r0, r19, regs, &ksig.ka); handle_signal(&ksig, regs); } else { single_stepping |= ptrace_cancel_bpt(current); if (r0) { switch (regs->r0) { case ERESTARTNOHAND: Loading @@ -536,15 +516,14 @@ do_signal(struct pt_regs *regs, unsigned long r0, unsigned long r19) regs->pc -= 4; break; case ERESTART_RESTARTBLOCK: /* Force v0 to the restart syscall and reply. */ /* Set v0 to the restart_syscall and replay */ 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 */ } Loading