mips: Use get_signal() signal_setup_done()

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

Signed-off-by: Richard Weinberger <richard@nod.at>
This commit is contained in:
Richard Weinberger
2013-10-06 22:25:42 +02:00
committed by Richard Weinberger
parent 9c53c7ec14
commit 81d103bf80
5 changed files with 53 additions and 84 deletions

View File

@@ -428,20 +428,20 @@ badframe:
}
#ifdef CONFIG_TRAD_SIGNALS
static int setup_frame(void *sig_return, struct k_sigaction *ka,
struct pt_regs *regs, int signr, sigset_t *set)
static int setup_frame(void *sig_return, struct ksignal *ksig,
struct pt_regs *regs, sigset_t *set)
{
struct sigframe __user *frame;
int err = 0;
frame = get_sigframe(ka, regs, sizeof(*frame));
frame = get_sigframe(&ksig->ka, regs, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
goto give_sigsegv;
return -EFAULT;
err |= setup_sigcontext(regs, &frame->sf_sc);
err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set));
if (err)
goto give_sigsegv;
return -EFAULT;
/*
* Arguments to signal handler:
@@ -453,37 +453,32 @@ static int setup_frame(void *sig_return, struct k_sigaction *ka,
* $25 and c0_epc point to the signal handler, $29 points to the
* struct sigframe.
*/
regs->regs[ 4] = signr;
regs->regs[ 4] = ksig->sig;
regs->regs[ 5] = 0;
regs->regs[ 6] = (unsigned long) &frame->sf_sc;
regs->regs[29] = (unsigned long) frame;
regs->regs[31] = (unsigned long) sig_return;
regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
regs->cp0_epc = regs->regs[25] = (unsigned long) ksig->ka.sa.sa_handler;
DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
current->comm, current->pid,
frame, regs->cp0_epc, regs->regs[31]);
return 0;
give_sigsegv:
force_sigsegv(signr, current);
return -EFAULT;
}
#endif
static int setup_rt_frame(void *sig_return, struct k_sigaction *ka,
struct pt_regs *regs, int signr, sigset_t *set,
siginfo_t *info)
static int setup_rt_frame(void *sig_return, struct ksignal *ksig,
struct pt_regs *regs, sigset_t *set)
{
struct rt_sigframe __user *frame;
int err = 0;
frame = get_sigframe(ka, regs, sizeof(*frame));
frame = get_sigframe(&ksig->ka, regs, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
goto give_sigsegv;
return -EFAULT;
/* Create siginfo. */
err |= copy_siginfo_to_user(&frame->rs_info, info);
err |= copy_siginfo_to_user(&frame->rs_info, &ksig->info);
/* Create the ucontext. */
err |= __put_user(0, &frame->rs_uc.uc_flags);
@@ -493,7 +488,7 @@ static int setup_rt_frame(void *sig_return, struct k_sigaction *ka,
err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set));
if (err)
goto give_sigsegv;
return -EFAULT;
/*
* Arguments to signal handler:
@@ -505,22 +500,18 @@ static int setup_rt_frame(void *sig_return, struct k_sigaction *ka,
* $25 and c0_epc point to the signal handler, $29 points to
* the struct rt_sigframe.
*/
regs->regs[ 4] = signr;
regs->regs[ 4] = ksig->sig;
regs->regs[ 5] = (unsigned long) &frame->rs_info;
regs->regs[ 6] = (unsigned long) &frame->rs_uc;
regs->regs[29] = (unsigned long) frame;
regs->regs[31] = (unsigned long) sig_return;
regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
regs->cp0_epc = regs->regs[25] = (unsigned long) ksig->ka.sa.sa_handler;
DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
current->comm, current->pid,
frame, regs->cp0_epc, regs->regs[31]);
return 0;
give_sigsegv:
force_sigsegv(signr, current);
return -EFAULT;
}
struct mips_abi mips_abi = {
@@ -534,8 +525,7 @@ struct mips_abi mips_abi = {
.restart = __NR_restart_syscall
};
static void handle_signal(unsigned long sig, siginfo_t *info,
struct k_sigaction *ka, struct pt_regs *regs)
static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
{
sigset_t *oldset = sigmask_to_save();
int ret;
@@ -557,7 +547,7 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
regs->regs[2] = EINTR;
break;
case ERESTARTSYS:
if (!(ka->sa.sa_flags & SA_RESTART)) {
if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
regs->regs[2] = EINTR;
break;
}
@@ -571,29 +561,23 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
regs->regs[0] = 0; /* Don't deal with this again. */
}
if (sig_uses_siginfo(ka))
if (sig_uses_siginfo(&ksig->ka))
ret = abi->setup_rt_frame(vdso + abi->rt_signal_return_offset,
ka, regs, sig, oldset, info);
ksig, regs, oldset);
else
ret = abi->setup_frame(vdso + abi->signal_return_offset,
ka, regs, sig, oldset);
ret = abi->setup_frame(vdso + abi->signal_return_offset, ksig,
regs, oldset);
if (ret)
return;
signal_delivered(sig, info, ka, regs, 0);
signal_setup_done(ret, ksig, 0);
}
static void do_signal(struct pt_regs *regs)
{
struct k_sigaction ka;
siginfo_t info;
int signr;
struct ksignal ksig;
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) {
if (get_signal(&ksig)) {
/* Whee! Actually deliver the signal. */
handle_signal(signr, &info, &ka, regs);
handle_signal(&ksig, regs);
return;
}