hexagon: Use get_signal() signal_setup_done()

Use the more generic functions get_signal() signal_setup_done()
for signal delivery.

Acked-by: Richard Kuo <rkuo@codeaurora.org>
Signed-off-by: Richard Weinberger <richard@nod.at>
This commit is contained in:
Richard Weinberger 2013-10-07 13:50:08 +02:00 committed by Richard Weinberger
parent 720f36b983
commit ac44362449
1 changed files with 18 additions and 27 deletions

View File

@ -112,20 +112,20 @@ static int restore_sigcontext(struct pt_regs *regs,
/* /*
* Setup signal stack frame with siginfo structure * Setup signal stack frame with siginfo structure
*/ */
static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info, static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
sigset_t *set, struct pt_regs *regs) struct pt_regs *regs)
{ {
int err = 0; int err = 0;
struct rt_sigframe __user *frame; struct rt_sigframe __user *frame;
struct hexagon_vdso *vdso = current->mm->context.vdso; struct hexagon_vdso *vdso = current->mm->context.vdso;
frame = get_sigframe(ka, regs, sizeof(struct rt_sigframe)); frame = get_sigframe(&ksig->ka, regs, sizeof(struct rt_sigframe));
if (!access_ok(VERIFY_WRITE, frame, sizeof(struct rt_sigframe))) if (!access_ok(VERIFY_WRITE, frame, sizeof(struct rt_sigframe)))
goto sigsegv; return -EFAULT;
if (copy_siginfo_to_user(&frame->info, info)) if (copy_siginfo_to_user(&frame->info, &ksig->info))
goto sigsegv; return -EFAULT;
/* The on-stack signal trampoline is no longer executed; /* The on-stack signal trampoline is no longer executed;
* however, the libgcc signal frame unwinding code checks for * however, the libgcc signal frame unwinding code checks for
@ -137,29 +137,26 @@ static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
err |= __save_altstack(&frame->uc.uc_stack, user_stack_pointer(regs)); err |= __save_altstack(&frame->uc.uc_stack, user_stack_pointer(regs));
if (err) if (err)
goto sigsegv; return -EFAULT;
/* Load r0/r1 pair with signumber/siginfo pointer... */ /* Load r0/r1 pair with signumber/siginfo pointer... */
regs->r0100 = ((unsigned long long)((unsigned long)&frame->info) << 32) regs->r0100 = ((unsigned long long)((unsigned long)&frame->info) << 32)
| (unsigned long long)signr; | (unsigned long long)ksig->sig;
regs->r02 = (unsigned long) &frame->uc; regs->r02 = (unsigned long) &frame->uc;
regs->r31 = (unsigned long) vdso->rt_signal_trampoline; regs->r31 = (unsigned long) vdso->rt_signal_trampoline;
pt_psp(regs) = (unsigned long) frame; pt_psp(regs) = (unsigned long) frame;
pt_set_elr(regs, (unsigned long)ka->sa.sa_handler); pt_set_elr(regs, (unsigned long)ksig->ka.sa.sa_handler);
return 0; return 0;
sigsegv:
force_sigsegv(signr, current);
return -EFAULT;
} }
/* /*
* Setup invocation of signal handler * Setup invocation of signal handler
*/ */
static void handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka, static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
struct pt_regs *regs)
{ {
int ret;
/* /*
* If we're handling a signal that aborted a system call, * If we're handling a signal that aborted a system call,
* set up the error return value before adding the signal * set up the error return value before adding the signal
@ -173,7 +170,7 @@ static void handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
regs->r00 = -EINTR; regs->r00 = -EINTR;
break; break;
case -ERESTARTSYS: case -ERESTARTSYS:
if (!(ka->sa.sa_flags & SA_RESTART)) { if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
regs->r00 = -EINTR; regs->r00 = -EINTR;
break; break;
} }
@ -193,11 +190,9 @@ static void handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
* only set up the rt_frame flavor. * only set up the rt_frame flavor.
*/ */
/* If there was an error on setup, no signal was delivered. */ /* If there was an error on setup, no signal was delivered. */
if (setup_rt_frame(sig, ka, info, sigmask_to_save(), regs) < 0) ret = setup_rt_frame(ksig, sigmask_to_save(), regs);
return;
signal_delivered(sig, info, ka, regs, signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
test_thread_flag(TIF_SINGLESTEP));
} }
/* /*
@ -205,17 +200,13 @@ static void handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
*/ */
void do_signal(struct pt_regs *regs) void do_signal(struct pt_regs *regs)
{ {
struct k_sigaction sigact; struct ksignal ksig;
siginfo_t info;
int signo;
if (!user_mode(regs)) if (!user_mode(regs))
return; return;
signo = get_signal_to_deliver(&info, &sigact, regs, NULL); if (get_signal(&ksig)) {
handle_signal(&ksig, regs);
if (signo > 0) {
handle_signal(signo, &info, &sigact, regs);
return; return;
} }