Commit 307627ee authored by Richard Weinberger's avatar Richard Weinberger Committed by Richard Weinberger

um: Use get_signal() signal_setup_done()

Use the more generic functions get_signal() signal_setup_done()
for signal delivery.
Signed-off-by: default avatarRichard Weinberger <richard@nod.at>
parent b3707c7e
...@@ -6,14 +6,10 @@ ...@@ -6,14 +6,10 @@
#ifndef __FRAME_KERN_H_ #ifndef __FRAME_KERN_H_
#define __FRAME_KERN_H_ #define __FRAME_KERN_H_
extern int setup_signal_stack_sc(unsigned long stack_top, int sig, extern int setup_signal_stack_sc(unsigned long stack_top, struct ksignal *ksig,
struct k_sigaction *ka, struct pt_regs *regs, sigset_t *mask);
struct pt_regs *regs, extern int setup_signal_stack_si(unsigned long stack_top, struct ksignal *ksig,
sigset_t *mask); struct pt_regs *regs, sigset_t *mask);
extern int setup_signal_stack_si(unsigned long stack_top, int sig,
struct k_sigaction *ka,
struct pt_regs *regs, struct siginfo *info,
sigset_t *mask);
#endif #endif
...@@ -18,8 +18,7 @@ EXPORT_SYMBOL(unblock_signals); ...@@ -18,8 +18,7 @@ EXPORT_SYMBOL(unblock_signals);
/* /*
* OK, we're invoking a handler * OK, we're invoking a handler
*/ */
static void handle_signal(struct pt_regs *regs, unsigned long signr, static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
struct k_sigaction *ka, struct siginfo *info)
{ {
sigset_t *oldset = sigmask_to_save(); sigset_t *oldset = sigmask_to_save();
int singlestep = 0; int singlestep = 0;
...@@ -39,7 +38,7 @@ static void handle_signal(struct pt_regs *regs, unsigned long signr, ...@@ -39,7 +38,7 @@ static void handle_signal(struct pt_regs *regs, unsigned long signr,
break; break;
case -ERESTARTSYS: case -ERESTARTSYS:
if (!(ka->sa.sa_flags & SA_RESTART)) { if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
PT_REGS_SYSCALL_RET(regs) = -EINTR; PT_REGS_SYSCALL_RET(regs) = -EINTR;
break; break;
} }
...@@ -52,32 +51,28 @@ static void handle_signal(struct pt_regs *regs, unsigned long signr, ...@@ -52,32 +51,28 @@ static void handle_signal(struct pt_regs *regs, unsigned long signr,
} }
sp = PT_REGS_SP(regs); sp = PT_REGS_SP(regs);
if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0)) if ((ksig->ka.sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0))
sp = current->sas_ss_sp + current->sas_ss_size; sp = current->sas_ss_sp + current->sas_ss_size;
#ifdef CONFIG_ARCH_HAS_SC_SIGNALS #ifdef CONFIG_ARCH_HAS_SC_SIGNALS
if (!(ka->sa.sa_flags & SA_SIGINFO)) if (!(ksig->ka.sa.sa_flags & SA_SIGINFO))
err = setup_signal_stack_sc(sp, signr, ka, regs, oldset); err = setup_signal_stack_sc(sp, ksig, regs, oldset);
else else
#endif #endif
err = setup_signal_stack_si(sp, signr, ka, regs, info, oldset); err = setup_signal_stack_si(sp, ksig, regs, oldset);
if (err) signal_setup_done(err, ksig, singlestep);
force_sigsegv(signr, current);
else
signal_delivered(signr, info, ka, regs, singlestep);
} }
static int kern_do_signal(struct pt_regs *regs) static int kern_do_signal(struct pt_regs *regs)
{ {
struct k_sigaction ka_copy; struct ksignal ksig;
struct siginfo info; int handled_sig = 0;
int sig, handled_sig = 0;
while ((sig = get_signal_to_deliver(&info, &ka_copy, regs, NULL)) > 0) { while (get_signal(&ksig)) {
handled_sig = 1; handled_sig = 1;
/* Whee! Actually deliver the signal. */ /* Whee! Actually deliver the signal. */
handle_signal(regs, sig, &ka_copy, &info); handle_signal(&ksig, regs);
} }
/* Did we come from a system call? */ /* Did we come from a system call? */
......
...@@ -370,13 +370,12 @@ struct rt_sigframe ...@@ -370,13 +370,12 @@ struct rt_sigframe
char retcode[8]; char retcode[8];
}; };
int setup_signal_stack_sc(unsigned long stack_top, int sig, int setup_signal_stack_sc(unsigned long stack_top, struct ksignal *ksig,
struct k_sigaction *ka, struct pt_regs *regs, struct pt_regs *regs, sigset_t *mask)
sigset_t *mask)
{ {
struct sigframe __user *frame; struct sigframe __user *frame;
void __user *restorer; void __user *restorer;
int err = 0; int err = 0, sig = ksig->sig;
/* This is the same calculation as i386 - ((sp + 4) & 15) == 0 */ /* This is the same calculation as i386 - ((sp + 4) & 15) == 0 */
stack_top = ((stack_top + 4) & -16UL) - 4; stack_top = ((stack_top + 4) & -16UL) - 4;
...@@ -385,8 +384,8 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig, ...@@ -385,8 +384,8 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig,
return 1; return 1;
restorer = frame->retcode; restorer = frame->retcode;
if (ka->sa.sa_flags & SA_RESTORER) if (ksig->ka.sa.sa_flags & SA_RESTORER)
restorer = ka->sa.sa_restorer; restorer = ksig->ka.sa.sa_restorer;
err |= __put_user(restorer, &frame->pretcode); err |= __put_user(restorer, &frame->pretcode);
err |= __put_user(sig, &frame->sig); err |= __put_user(sig, &frame->sig);
...@@ -410,20 +409,19 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig, ...@@ -410,20 +409,19 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig,
return err; return err;
PT_REGS_SP(regs) = (unsigned long) frame; PT_REGS_SP(regs) = (unsigned long) frame;
PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler; PT_REGS_IP(regs) = (unsigned long) ksig->ka.sa.sa_handler;
PT_REGS_AX(regs) = (unsigned long) sig; PT_REGS_AX(regs) = (unsigned long) sig;
PT_REGS_DX(regs) = (unsigned long) 0; PT_REGS_DX(regs) = (unsigned long) 0;
PT_REGS_CX(regs) = (unsigned long) 0; PT_REGS_CX(regs) = (unsigned long) 0;
return 0; return 0;
} }
int setup_signal_stack_si(unsigned long stack_top, int sig, int setup_signal_stack_si(unsigned long stack_top, struct ksignal *ksig,
struct k_sigaction *ka, struct pt_regs *regs, struct pt_regs *regs, sigset_t *mask)
siginfo_t *info, sigset_t *mask)
{ {
struct rt_sigframe __user *frame; struct rt_sigframe __user *frame;
void __user *restorer; void __user *restorer;
int err = 0; int err = 0, sig = ksig->sig;
stack_top &= -8UL; stack_top &= -8UL;
frame = (struct rt_sigframe __user *) stack_top - 1; frame = (struct rt_sigframe __user *) stack_top - 1;
...@@ -431,14 +429,14 @@ int setup_signal_stack_si(unsigned long stack_top, int sig, ...@@ -431,14 +429,14 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
return 1; return 1;
restorer = frame->retcode; restorer = frame->retcode;
if (ka->sa.sa_flags & SA_RESTORER) if (ksig->ka.sa.sa_flags & SA_RESTORER)
restorer = ka->sa.sa_restorer; restorer = ksig->ka.sa.sa_restorer;
err |= __put_user(restorer, &frame->pretcode); err |= __put_user(restorer, &frame->pretcode);
err |= __put_user(sig, &frame->sig); err |= __put_user(sig, &frame->sig);
err |= __put_user(&frame->info, &frame->pinfo); err |= __put_user(&frame->info, &frame->pinfo);
err |= __put_user(&frame->uc, &frame->puc); err |= __put_user(&frame->uc, &frame->puc);
err |= copy_siginfo_to_user(&frame->info, info); err |= copy_siginfo_to_user(&frame->info, &ksig->info);
err |= copy_ucontext_to_user(&frame->uc, &frame->fpstate, mask, err |= copy_ucontext_to_user(&frame->uc, &frame->fpstate, mask,
PT_REGS_SP(regs)); PT_REGS_SP(regs));
...@@ -457,7 +455,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig, ...@@ -457,7 +455,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
return err; return err;
PT_REGS_SP(regs) = (unsigned long) frame; PT_REGS_SP(regs) = (unsigned long) frame;
PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler; PT_REGS_IP(regs) = (unsigned long) ksig->ka.sa.sa_handler;
PT_REGS_AX(regs) = (unsigned long) sig; PT_REGS_AX(regs) = (unsigned long) sig;
PT_REGS_DX(regs) = (unsigned long) &frame->info; PT_REGS_DX(regs) = (unsigned long) &frame->info;
PT_REGS_CX(regs) = (unsigned long) &frame->uc; PT_REGS_CX(regs) = (unsigned long) &frame->uc;
...@@ -502,12 +500,11 @@ struct rt_sigframe ...@@ -502,12 +500,11 @@ struct rt_sigframe
struct _fpstate fpstate; struct _fpstate fpstate;
}; };
int setup_signal_stack_si(unsigned long stack_top, int sig, int setup_signal_stack_si(unsigned long stack_top, struct ksignal *ksig,
struct k_sigaction *ka, struct pt_regs * regs, struct pt_regs *regs, sigset_t *set)
siginfo_t *info, sigset_t *set)
{ {
struct rt_sigframe __user *frame; struct rt_sigframe __user *frame;
int err = 0; int err = 0, sig = ksig->sig;
frame = (struct rt_sigframe __user *) frame = (struct rt_sigframe __user *)
round_down(stack_top - sizeof(struct rt_sigframe), 16); round_down(stack_top - sizeof(struct rt_sigframe), 16);
...@@ -517,8 +514,8 @@ int setup_signal_stack_si(unsigned long stack_top, int sig, ...@@ -517,8 +514,8 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
goto out; goto out;
if (ka->sa.sa_flags & SA_SIGINFO) { if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
err |= copy_siginfo_to_user(&frame->info, info); err |= copy_siginfo_to_user(&frame->info, &ksig->info);
if (err) if (err)
goto out; goto out;
} }
...@@ -543,8 +540,8 @@ int setup_signal_stack_si(unsigned long stack_top, int sig, ...@@ -543,8 +540,8 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
* already in userspace. * already in userspace.
*/ */
/* x86-64 should always use SA_RESTORER. */ /* x86-64 should always use SA_RESTORER. */
if (ka->sa.sa_flags & SA_RESTORER) if (ksig->ka.sa.sa_flags & SA_RESTORER)
err |= __put_user(ka->sa.sa_restorer, &frame->pretcode); err |= __put_user(ksig->ka.sa.sa_restorer, &frame->pretcode);
else else
/* could use a vstub here */ /* could use a vstub here */
return err; return err;
...@@ -570,7 +567,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig, ...@@ -570,7 +567,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
*/ */
PT_REGS_SI(regs) = (unsigned long) &frame->info; PT_REGS_SI(regs) = (unsigned long) &frame->info;
PT_REGS_DX(regs) = (unsigned long) &frame->uc; PT_REGS_DX(regs) = (unsigned long) &frame->uc;
PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler; PT_REGS_IP(regs) = (unsigned long) ksig->ka.sa.sa_handler;
out: out:
return err; return err;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment