diff options
Diffstat (limited to 'arch/cris/arch-v10/kernel/signal.c')
-rw-r--r-- | arch/cris/arch-v10/kernel/signal.c | 89 |
1 files changed, 35 insertions, 54 deletions
diff --git a/arch/cris/arch-v10/kernel/signal.c b/arch/cris/arch-v10/kernel/signal.c index 61ce6273a895..9b32d338838b 100644 --- a/arch/cris/arch-v10/kernel/signal.c +++ b/arch/cris/arch-v10/kernel/signal.c @@ -203,15 +203,9 @@ static int setup_sigcontext(struct sigcontext __user *sc, * - usually on the stack. */ static inline void __user * -get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) +get_sigframe(struct ksignal *ksig, size_t frame_size) { - unsigned long sp = rdusp(); - - /* This is the X/Open sanctioned signal stack switching. */ - if (ka->sa.sa_flags & SA_ONSTACK) { - if (! on_sig_stack(sp)) - sp = current->sas_ss_sp + current->sas_ss_size; - } + unsigned long sp = sigsp(rdusp(), ksig); /* make sure the frame is dword-aligned */ @@ -228,33 +222,33 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) * user-mode trampoline. */ -static int setup_frame(int sig, struct k_sigaction *ka, - sigset_t *set, struct pt_regs *regs) +static int setup_frame(struct ksignal *ksig, sigset_t *set, + struct pt_regs *regs) { struct sigframe __user *frame; unsigned long return_ip; int err = 0; - frame = get_sigframe(ka, regs, sizeof(*frame)); + frame = get_sigframe(ksig, sizeof(*frame)); if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) - goto give_sigsegv; + return -EFAULT; err |= setup_sigcontext(&frame->sc, regs, set->sig[0]); if (err) - goto give_sigsegv; + return -EFAULT; if (_NSIG_WORDS > 1) { err |= __copy_to_user(frame->extramask, &set->sig[1], sizeof(frame->extramask)); } if (err) - goto give_sigsegv; + return -EFAULT; /* Set up to return from userspace. If provided, use a stub already in userspace. */ - if (ka->sa.sa_flags & SA_RESTORER) { - return_ip = (unsigned long)ka->sa.sa_restorer; + if (ksig->ka.sa.sa_flags & SA_RESTORER) { + return_ip = (unsigned long)ksig->ka.sa.sa_restorer; } else { /* trampoline - the desired return ip is the retcode itself */ return_ip = (unsigned long)&frame->retcode; @@ -265,42 +259,38 @@ static int setup_frame(int sig, struct k_sigaction *ka, } if (err) - goto give_sigsegv; + return -EFAULT; /* Set up registers for signal handler */ - regs->irp = (unsigned long) ka->sa.sa_handler; /* what we enter NOW */ + regs->irp = (unsigned long) ksig->ka.sa.sa_handler; /* what we enter NOW */ regs->srp = return_ip; /* what we enter LATER */ - regs->r10 = sig; /* first argument is signo */ + regs->r10 = ksig->sig; /* first argument is signo */ /* actually move the usp to reflect the stacked frame */ wrusp((unsigned long)frame); return 0; - -give_sigsegv: - force_sigsegv(sig, current); - return -EFAULT; } -static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, - sigset_t *set, struct pt_regs *regs) +static int setup_rt_frame(struct ksignal *ksig, sigset_t *set, + struct pt_regs *regs) { struct rt_sigframe __user *frame; unsigned long return_ip; int err = 0; - frame = get_sigframe(ka, regs, sizeof(*frame)); + frame = get_sigframe(ksig, sizeof(*frame)); if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) - goto give_sigsegv; + return -EFAULT; err |= __put_user(&frame->info, &frame->pinfo); err |= __put_user(&frame->uc, &frame->puc); - err |= copy_siginfo_to_user(&frame->info, info); + err |= copy_siginfo_to_user(&frame->info, &ksig->info); if (err) - goto give_sigsegv; + return -EFAULT; /* Clear all the bits of the ucontext we don't use. */ err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext)); @@ -312,12 +302,12 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, err |= __save_altstack(&frame->uc.uc_stack, rdusp()); if (err) - goto give_sigsegv; + return -EFAULT; /* Set up to return from userspace. If provided, use a stub already in userspace. */ - if (ka->sa.sa_flags & SA_RESTORER) { - return_ip = (unsigned long)ka->sa.sa_restorer; + if (ksig->ka.sa.sa_flags & SA_RESTORER) { + return_ip = (unsigned long)ksig->ka.sa.sa_restorer; } else { /* trampoline - the desired return ip is the retcode itself */ return_ip = (unsigned long)&frame->retcode; @@ -329,18 +319,18 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, } if (err) - goto give_sigsegv; + return -EFAULT; /* TODO what is the current->exec_domain stuff and invmap ? */ /* Set up registers for signal handler */ /* What we enter NOW */ - regs->irp = (unsigned long) ka->sa.sa_handler; + regs->irp = (unsigned long) ksig->ka.sa.sa_handler; /* What we enter LATER */ regs->srp = return_ip; /* First argument is signo */ - regs->r10 = sig; + regs->r10 = ksig->sig; /* Second argument is (siginfo_t *) */ regs->r11 = (unsigned long)&frame->info; /* Third argument is unused */ @@ -350,19 +340,14 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, wrusp((unsigned long)frame); return 0; - -give_sigsegv: - force_sigsegv(sig, current); - return -EFAULT; } /* * OK, we're invoking a handler */ -static inline void handle_signal(int canrestart, unsigned long sig, - siginfo_t *info, struct k_sigaction *ka, - struct pt_regs *regs) +static inline void handle_signal(int canrestart, struct ksignal *ksig, + struct pt_regs *regs) { sigset_t *oldset = sigmask_to_save(); int ret; @@ -383,7 +368,7 @@ static inline void handle_signal(int canrestart, unsigned long sig, /* 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)) { + if (!(ksig->ka.sa.sa_flags & SA_RESTART)) { regs->r10 = -EINTR; break; } @@ -396,13 +381,12 @@ static inline void handle_signal(int canrestart, unsigned long sig, } /* Set up the stack frame */ - 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 == 0) - signal_delivered(sig, info, ka, regs, 0); + signal_setup_done(ret, ksig, 0); } /* @@ -419,9 +403,7 @@ static inline void handle_signal(int canrestart, unsigned long sig, void do_signal(int canrestart, struct pt_regs *regs) { - siginfo_t info; - int signr; - struct k_sigaction ka; + struct ksignal ksig; /* * We want the common case to go fast, which @@ -432,10 +414,9 @@ void do_signal(int canrestart, struct pt_regs *regs) if (!user_mode(regs)) return; - signr = get_signal_to_deliver(&info, &ka, regs, NULL); - if (signr > 0) { + if (get_signal(&ksig)) { /* Whee! Actually deliver the signal. */ - handle_signal(canrestart, signr, &info, &ka, regs); + handle_signal(canrestart, &ksig, regs); return; } |