Commit 63b12bdb authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'signal-cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/misc

Pull arch signal handling cleanup from Richard Weinberger:
 "This patch series moves all remaining archs to the get_signal(),
  signal_setup_done() and sigsp() functions.

  Currently these archs use open coded variants of the said functions.
  Further, unused parameters get removed from get_signal_to_deliver(),
  tracehook_signal_handler() and signal_delivered().

  At the end of the day we save around 500 lines of code."

* 'signal-cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/misc: (43 commits)
  powerpc: Use sigsp()
  openrisc: Use sigsp()
  mn10300: Use sigsp()
  mips: Use sigsp()
  microblaze: Use sigsp()
  metag: Use sigsp()
  m68k: Use sigsp()
  m32r: Use sigsp()
  hexagon: Use sigsp()
  frv: Use sigsp()
  cris: Use sigsp()
  c6x: Use sigsp()
  blackfin: Use sigsp()
  avr32: Use sigsp()
  arm64: Use sigsp()
  arc: Use sigsp()
  sas_ss_flags: Remove nested ternary if
  Rip out get_signal_to_deliver()
  Clean up signal_delivered()
  tracehook_signal_handler: Remove sig, info, ka and regs
  ...
parents ad1f5caf 059ade65
......@@ -141,17 +141,13 @@ SYSCALL_DEFINE0(rt_sigreturn)
/*
* Determine which stack to use..
*/
static inline void __user *get_sigframe(struct k_sigaction *ka,
static inline void __user *get_sigframe(struct ksignal *ksig,
struct pt_regs *regs,
unsigned long framesize)
{
unsigned long sp = regs->sp;
unsigned long sp = sigsp(regs->sp, ksig);
void __user *frame;
/* This is the X/Open sanctioned signal stack switching */
if ((ka->sa.sa_flags & SA_ONSTACK) && !sas_ss_flags(sp))
sp = current->sas_ss_sp + current->sas_ss_size;
/* No matter what happens, 'sp' must be word
* aligned otherwise nasty things could happen
*/
......@@ -179,14 +175,13 @@ static inline int map_sig(int sig)
}
static int
setup_rt_frame(int signo, 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)
{
struct rt_sigframe __user *sf;
unsigned int magic = 0;
int err = 0;
sf = get_sigframe(ka, regs, sizeof(struct rt_sigframe));
sf = get_sigframe(ksig, regs, sizeof(struct rt_sigframe));
if (!sf)
return 1;
......@@ -205,8 +200,8 @@ setup_rt_frame(int signo, struct k_sigaction *ka, siginfo_t *info,
* #2: struct siginfo
* #3: struct ucontext (completely populated)
*/
if (unlikely(ka->sa.sa_flags & SA_SIGINFO)) {
err |= copy_siginfo_to_user(&sf->info, info);
if (unlikely(ksig->ka.sa.sa_flags & SA_SIGINFO)) {
err |= copy_siginfo_to_user(&sf->info, &ksig->info);
err |= __put_user(0, &sf->uc.uc_flags);
err |= __put_user(NULL, &sf->uc.uc_link);
err |= __save_altstack(&sf->uc.uc_stack, regs->sp);
......@@ -227,16 +222,16 @@ setup_rt_frame(int signo, struct k_sigaction *ka, siginfo_t *info,
return err;
/* #1 arg to the user Signal handler */
regs->r0 = map_sig(signo);
regs->r0 = map_sig(ksig->sig);
/* setup PC of user space signal handler */
regs->ret = (unsigned long)ka->sa.sa_handler;
regs->ret = (unsigned long)ksig->ka.sa.sa_handler;
/*
* handler returns using sigreturn stub provided already by userpsace
*/
BUG_ON(!(ka->sa.sa_flags & SA_RESTORER));
regs->blink = (unsigned long)ka->sa.sa_restorer;
BUG_ON(!(ksig->ka.sa.sa_flags & SA_RESTORER));
regs->blink = (unsigned long)ksig->ka.sa.sa_restorer;
/* User Stack for signal handler will be above the frame just carved */
regs->sp = (unsigned long)sf;
......@@ -298,38 +293,30 @@ static void arc_restart_syscall(struct k_sigaction *ka, struct pt_regs *regs)
* OK, we're invoking a handler
*/
static void
handle_signal(unsigned long 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;
/* Set up the stack frame */
ret = setup_rt_frame(sig, ka, info, oldset, regs);
ret = setup_rt_frame(ksig, oldset, regs);
if (ret)
force_sigsegv(sig, current);
else
signal_delivered(sig, info, ka, regs, 0);
signal_setup_done(ret, ksig, 0);
}
void do_signal(struct pt_regs *regs)
{
struct k_sigaction ka;
siginfo_t info;
int signr;
struct ksignal ksig;
int restart_scall;
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
restart_scall = in_syscall(regs) && syscall_restartable(regs);
if (signr > 0) {
if (get_signal(&ksig)) {
if (restart_scall) {
arc_restart_syscall(&ka, regs);
arc_restart_syscall(&ksig.ka, regs);
syscall_wont_restart(regs); /* No more restarts */
}
handle_signal(signr, &ka, &info, regs);
handle_signal(&ksig, regs);
return;
}
......
......@@ -24,22 +24,21 @@
extern const compat_ulong_t aarch32_sigret_code[6];
int compat_setup_frame(int usig, struct k_sigaction *ka, sigset_t *set,
int compat_setup_frame(int usig, struct ksignal *ksig, sigset_t *set,
struct pt_regs *regs);
int compat_setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
sigset_t *set, struct pt_regs *regs);
int compat_setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set,
struct pt_regs *regs);
void compat_setup_restart_syscall(struct pt_regs *regs);
#else
static inline int compat_setup_frame(int usid, struct k_sigaction *ka,
static inline int compat_setup_frame(int usid, struct ksignal *ksig,
sigset_t *set, struct pt_regs *regs)
{
return -ENOSYS;
}
static inline int compat_setup_rt_frame(int usig, struct k_sigaction *ka,
siginfo_t *info, sigset_t *set,
static inline int compat_setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set,
struct pt_regs *regs)
{
return -ENOSYS;
......
......@@ -209,19 +209,13 @@ static int setup_sigframe(struct rt_sigframe __user *sf,
return err;
}
static struct rt_sigframe __user *get_sigframe(struct k_sigaction *ka,
static struct rt_sigframe __user *get_sigframe(struct ksignal *ksig,
struct pt_regs *regs)
{
unsigned long sp, sp_top;
struct rt_sigframe __user *frame;
sp = sp_top = regs->sp;
/*
* This is the X/Open sanctioned signal stack switching.
*/
if ((ka->sa.sa_flags & SA_ONSTACK) && !sas_ss_flags(sp))
sp = sp_top = current->sas_ss_sp + current->sas_ss_size;
sp = sp_top = sigsp(regs->sp, ksig);
sp = (sp - sizeof(struct rt_sigframe)) & ~15;
frame = (struct rt_sigframe __user *)sp;
......@@ -253,13 +247,13 @@ static void setup_return(struct pt_regs *regs, struct k_sigaction *ka,
regs->regs[30] = (unsigned long)sigtramp;
}
static int setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
sigset_t *set, struct pt_regs *regs)
static int setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set,
struct pt_regs *regs)
{
struct rt_sigframe __user *frame;
int err = 0;
frame = get_sigframe(ka, regs);
frame = get_sigframe(ksig, regs);
if (!frame)
return 1;
......@@ -269,9 +263,9 @@ static int setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
err |= __save_altstack(&frame->uc.uc_stack, regs->sp);
err |= setup_sigframe(frame, regs, set);
if (err == 0) {
setup_return(regs, ka, frame, usig);
if (ka->sa.sa_flags & SA_SIGINFO) {
err |= copy_siginfo_to_user(&frame->info, info);
setup_return(regs, &ksig->ka, frame, usig);
if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
err |= copy_siginfo_to_user(&frame->info, &ksig->info);
regs->regs[1] = (unsigned long)&frame->info;
regs->regs[2] = (unsigned long)&frame->uc;
}
......@@ -291,13 +285,12 @@ static void setup_restart_syscall(struct pt_regs *regs)
/*
* OK, we're invoking a handler
*/
static void handle_signal(unsigned long sig, struct k_sigaction *ka,
siginfo_t *info, struct pt_regs *regs)
static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
{
struct thread_info *thread = current_thread_info();
struct task_struct *tsk = current;
sigset_t *oldset = sigmask_to_save();
int usig = sig;
int usig = ksig->sig;
int ret;
/*
......@@ -310,13 +303,12 @@ static void handle_signal(unsigned long sig, struct k_sigaction *ka,
* Set up the stack frame
*/
if (is_compat_task()) {
if (ka->sa.sa_flags & SA_SIGINFO)
ret = compat_setup_rt_frame(usig, ka, info, oldset,
regs);
if (ksig->ka.sa.sa_flags & SA_SIGINFO)
ret = compat_setup_rt_frame(usig, ksig, oldset, regs);
else
ret = compat_setup_frame(usig, ka, oldset, regs);
ret = compat_setup_frame(usig, ksig, oldset, regs);
} else {
ret = setup_rt_frame(usig, ka, info, oldset, regs);
ret = setup_rt_frame(usig, ksig, oldset, regs);
}
/*
......@@ -324,18 +316,14 @@ static void handle_signal(unsigned long sig, struct k_sigaction *ka,
*/
ret |= !valid_user_regs(&regs->user_regs);
if (ret != 0) {
force_sigsegv(sig, tsk);
return;
}
/*
* Fast forward the stepping logic so we step into the signal
* handler.
*/
user_fastforward_single_step(tsk);
if (!ret)
user_fastforward_single_step(tsk);
signal_delivered(sig, info, ka, regs, 0);
signal_setup_done(ret, ksig, 0);
}
/*
......@@ -350,10 +338,9 @@ static void handle_signal(unsigned long sig, struct k_sigaction *ka,
static void do_signal(struct pt_regs *regs)
{
unsigned long continue_addr = 0, restart_addr = 0;
struct k_sigaction ka;
siginfo_t info;
int signr, retval = 0;
int retval = 0;
int syscall = (int)regs->syscallno;
struct ksignal ksig;
/*
* If we were from a system call, check for system call restarting...
......@@ -387,8 +374,7 @@ static void do_signal(struct pt_regs *regs)
* Get the signal to deliver. When running under ptrace, at this point
* the debugger may change all of our registers.
*/
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) {
if (get_signal(&ksig)) {
/*
* Depending on the signal settings, we may need to revert the
* decision to restart the system call, but skip this if a
......@@ -398,12 +384,12 @@ static void do_signal(struct pt_regs *regs)
(retval == -ERESTARTNOHAND ||
retval == -ERESTART_RESTARTBLOCK ||
(retval == -ERESTARTSYS &&
!(ka.sa.sa_flags & SA_RESTART)))) {
!(ksig.ka.sa.sa_flags & SA_RESTART)))) {
regs->regs[0] = -EINTR;
regs->pc = continue_addr;
}
handle_signal(signr, &ka, &info, regs);
handle_signal(&ksig, regs);
return;
}
......
......@@ -407,19 +407,13 @@ asmlinkage int compat_sys_rt_sigreturn(struct pt_regs *regs)
return 0;
}
static void __user *compat_get_sigframe(struct k_sigaction *ka,
static void __user *compat_get_sigframe(struct ksignal *ksig,
struct pt_regs *regs,
int framesize)
{
compat_ulong_t sp = regs->compat_sp;
compat_ulong_t sp = sigsp(regs->compat_sp, ksig);
void __user *frame;
/*
* This is the X/Open sanctioned signal stack switching.
*/
if ((ka->sa.sa_flags & SA_ONSTACK) && !sas_ss_flags(sp))
sp = current->sas_ss_sp + current->sas_ss_size;
/*
* ATPCS B01 mandates 8-byte alignment
*/
......@@ -520,18 +514,18 @@ static int compat_setup_sigframe(struct compat_sigframe __user *sf,
/*
* 32-bit signal handling routines called from signal.c
*/
int compat_setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
int compat_setup_rt_frame(int usig, struct ksignal *ksig,
sigset_t *set, struct pt_regs *regs)
{
struct compat_rt_sigframe __user *frame;
int err = 0;
frame = compat_get_sigframe(ka, regs, sizeof(*frame));
frame = compat_get_sigframe(ksig, regs, sizeof(*frame));
if (!frame)
return 1;
err |= copy_siginfo_to_user32(&frame->info, info);
err |= copy_siginfo_to_user32(&frame->info, &ksig->info);
__put_user_error(0, &frame->sig.uc.uc_flags, err);
__put_user_error(0, &frame->sig.uc.uc_link, err);
......@@ -541,7 +535,7 @@ int compat_setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
err |= compat_setup_sigframe(&frame->sig, regs, set);
if (err == 0) {
compat_setup_return(regs, ka, frame->sig.retcode, frame, usig);
compat_setup_return(regs, &ksig->ka, frame->sig.retcode, frame, usig);
regs->regs[1] = (compat_ulong_t)(unsigned long)&frame->info;
regs->regs[2] = (compat_ulong_t)(unsigned long)&frame->sig.uc;
}
......@@ -549,13 +543,13 @@ int compat_setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
return err;
}
int compat_setup_frame(int usig, struct k_sigaction *ka, sigset_t *set,
int compat_setup_frame(int usig, struct ksignal *ksig, sigset_t *set,
struct pt_regs *regs)
{
struct compat_sigframe __user *frame;
int err = 0;
frame = compat_get_sigframe(ka, regs, sizeof(*frame));
frame = compat_get_sigframe(ksig, regs, sizeof(*frame));
if (!frame)
return 1;
......@@ -564,7 +558,7 @@ int compat_setup_frame(int usig, struct k_sigaction *ka, sigset_t *set,
err |= compat_setup_sigframe(frame, regs, set);
if (err == 0)
compat_setup_return(regs, ka, frame->retcode, frame, usig);
compat_setup_return(regs, &ksig->ka, frame->retcode, frame, usig);
return err;
}
......
......@@ -127,24 +127,20 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs)
}
static inline void __user *
get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, int framesize)
get_sigframe(struct ksignal *ksig, struct pt_regs *regs, int framesize)
{
unsigned long sp = regs->sp;
if ((ka->sa.sa_flags & SA_ONSTACK) && !sas_ss_flags(sp))
sp = current->sas_ss_sp + current->sas_ss_size;
unsigned long sp = sigsp(regs->sp, ksig);
return (void __user *)((sp - framesize) & ~3);
}
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)
{
struct rt_sigframe __user *frame;
int err = 0;
frame = get_sigframe(ka, regs, sizeof(*frame));
frame = get_sigframe(ksig, regs, sizeof(*frame));
err = -EFAULT;
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
goto out;
......@@ -164,7 +160,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
err = __put_user(0x3008d733 | (__NR_rt_sigreturn << 20),
&frame->retcode);
err |= copy_siginfo_to_user(&frame->info, info);
err |= copy_siginfo_to_user(&frame->info, &ksig->info);
/* Set up the ucontext */
err |= __put_user(0, &frame->uc.uc_flags);
......@@ -176,12 +172,12 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
if (err)
goto out;
regs->r12 = sig;
regs->r12 = ksig->sig;
regs->r11 = (unsigned long) &frame->info;
regs->r10 = (unsigned long) &frame->uc;
regs->sp = (unsigned long) frame;
if (ka->sa.sa_flags & SA_RESTORER)
regs->lr = (unsigned long)ka->sa.sa_restorer;
if (ksig->ka.sa.sa_flags & SA_RESTORER)
regs->lr = (unsigned long)ksig->ka.sa.sa_restorer;
else {
printk(KERN_NOTICE "[%s:%d] did not set SA_RESTORER\n",
current->comm, current->pid);
......@@ -189,10 +185,10 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
}
pr_debug("SIG deliver [%s:%d]: sig=%d sp=0x%lx pc=0x%lx->0x%p lr=0x%lx\n",
current->comm, current->pid, sig, regs->sp,
regs->pc, ka->sa.sa_handler, regs->lr);
current->comm, current->pid, ksig->sig, regs->sp,
regs->pc, ksig->ka.sa.sa_handler, regs->lr);
regs->pc = (unsigned long) ka->sa.sa_handler;
regs->pc = (unsigned long)ksig->ka.sa.sa_handler;
out:
return err;
......@@ -208,15 +204,14 @@ static inline void setup_syscall_restart(struct pt_regs *regs)
}
static inline void
handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
struct pt_regs *regs, int syscall)
handle_signal(struct ksignal *ksig, struct pt_regs *regs, int syscall)
{
int ret;
/*
* Set up the stack frame
*/
ret = setup_rt_frame(sig, ka, info, sigmask_to_save(), regs);
ret = setup_rt_frame(ksig, sigmask_to_save(), regs);
/*
* Check that the resulting registers are sane
......@@ -226,10 +221,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
/*
* Block the signal if we were successful.
*/
if (ret != 0)
force_sigsegv(sig, current);
else
signal_delivered(sig, info, ka, regs, 0);
signal_setup_done(ret, ksig, 0);
}
/*
......@@ -239,9 +231,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
*/
static void do_signal(struct pt_regs *regs, int syscall)
{
siginfo_t info;
int signr;
struct k_sigaction ka;
struct ksignal ksig;
/*
* We want the common case to go fast, which is why we may in
......@@ -251,18 +241,18 @@ static void do_signal(struct pt_regs *regs, int syscall)
if (!user_mode(regs))
return;
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
get_signal(&ksig);
if (syscall) {
switch (regs->r12) {
case -ERESTART_RESTARTBLOCK:
case -ERESTARTNOHAND:
if (signr > 0) {
if (ksig.sig > 0) {
regs->r12 = -EINTR;
break;
}
/* fall through */
case -ERESTARTSYS:
if (signr > 0 && !(ka.sa.sa_flags & SA_RESTART)) {
if (ksig.sig > 0 && !(ksig.ka.sa.sa_flags & SA_RESTART)) {
regs->r12 = -EINTR;
break;
}
......@@ -272,13 +262,13 @@ static void do_signal(struct pt_regs *regs, int syscall)
}
}
if (signr == 0) {
if (!ksig.sig) {
/* No signal to deliver -- put the saved sigmask back */
restore_saved_sigmask();
return;
}
handle_signal(signr, &ka, &info, regs, syscall);
handle_signal(&ksig, regs, syscall);
}
asmlinkage void do_notify_resume(struct pt_regs *regs, struct thread_info *ti)
......
......@@ -135,40 +135,31 @@ static inline int rt_setup_sigcontext(struct sigcontext *sc, struct pt_regs *reg
return err;
}
static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
static inline void *get_sigframe(struct ksignal *ksig,
size_t frame_size)
{
unsigned long usp;
unsigned long usp = sigsp(rdusp(), ksig);
/* Default to using normal stack. */
usp = rdusp();
/* This is the X/Open sanctioned signal stack switching. */
if (ka->sa.sa_flags & SA_ONSTACK) {
if (!on_sig_stack(usp))
usp = current->sas_ss_sp + current->sas_ss_size;
}
return (void *)((usp - frame_size) & -8UL);
}
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)
{
struct rt_sigframe *frame;
int err = 0;
frame = get_sigframe(ka, regs, sizeof(*frame));
frame = get_sigframe(ksig, sizeof(*frame));
err |= __put_user((current_thread_info()->exec_domain
&& current_thread_info()->exec_domain->signal_invmap
&& sig < 32
&& ksig->sig < 32
? current_thread_info()->exec_domain->
signal_invmap[sig] : sig), &frame->sig);
signal_invmap[ksig->sig] : ksig->sig), &frame->sig);
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);
/* Create the ucontext. */
err |= __put_user(0, &frame->uc.uc_flags);
......@@ -183,7 +174,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info,
/* Set up registers for signal handler */
if (current->personality & FDPIC_FUNCPTRS) {
struct fdpic_func_descriptor __user *funcptr =
(struct fdpic_func_descriptor *) ka->sa.sa_handler;
(struct fdpic_func_descriptor *) ksig->ka.sa.sa_handler;
u32 pc, p3;
err |= __get_user(pc, &funcptr->text);
err |= __get_user(p3, &funcptr->GOT);
......@@ -192,7 +183,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info,
regs->pc = pc;
regs->p3 = p3;
} else
regs->pc = (unsigned long)ka->sa.sa_handler;
regs->pc = (unsigned long)ksig->ka.sa.sa_handler;
wrusp((unsigned long)frame);
regs->rets = SIGRETURN_STUB;
......@@ -237,20 +228,19 @@ handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
* OK, we're invoking a handler
*/
static void
handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
struct pt_regs *regs)
handle_signal(struct ksignal *ksig, struct pt_regs *regs)
{
int ret;
/* are we from a system call? to see pt_regs->orig_p0 */
if (regs->orig_p0 >= 0)
/* If so, check system call restarting.. */
handle_restart(regs, ka, 1);
handle_restart(regs, &ksig->ka, 1);
/* set up the stack frame */
if (setup_rt_frame(sig, ka, info, sigmask_to_save(), regs) < 0)
force_sigsegv(sig, current);
else
signal_delivered(sig, info, ka, regs,
test_thread_flag(TIF_SINGLESTEP));
ret = setup_rt_frame(ksig, sigmask_to_save(), regs);
signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
}
/*
......@@ -264,16 +254,13 @@ handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
*/
asmlinkage void do_signal(struct pt_regs *regs)
{
siginfo_t info;
int signr;
struct k_sigaction ka;
struct ksignal ksig;
current->thread.esp0 = (unsigned long)regs;
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;
}
......
......@@ -127,17 +127,11 @@ static int setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
return err;
}
static inline void __user *get_sigframe(struct k_sigaction *ka,
static inline void __user *get_sigframe(struct ksignal *ksig,
struct pt_regs *regs,
unsigned long framesize)
{
unsigned long sp = regs->sp;
/*
* This is the X/Open sanctioned signal stack switching.
*/
if ((ka->sa.sa_flags & SA_ONSTACK) && sas_ss_flags(sp) == 0)
sp = current->sas_ss_sp + current->sas_ss_size;
unsigned long sp = sigsp(regs->sp, ksig);
/*
* No matter what happens, 'sp' must be dword
......@@ -146,21 +140,21 @@ static inline void __user *get_sigframe(struct k_sigaction *ka,
return (void __user *)((sp - framesize) & ~7);
}
static int setup_rt_frame(int signr, 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 __user *retcode;
int err = 0;
frame = get_sigframe(ka, regs, sizeof(*frame));
frame = get_sigframe(ksig, regs, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
goto segv_and_exit;
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);
/* Clear all the bits of the ucontext we don't use. */
err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));
......@@ -188,7 +182,7 @@ static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
#undef COPY
if (err)
goto segv_and_exit;
return -EFAULT;
flush_icache_range((unsigned long) &frame->retcode,
(unsigned long) &frame->retcode + RETCODE_SIZE);
......@@ -198,10 +192,10 @@ static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
/* Change user context to branch to signal handler */
regs->sp = (unsigned long) frame - 8;
regs->b3 = (unsigned long) retcode;
regs->pc = (unsigned long) ka->sa.sa_handler;
regs->pc = (unsigned long) ksig->ka.sa.sa_handler;
/* Give the signal number to the handler */
regs->a4 = signr;
regs->a4 = ksig->sig;
/*
* For realtime signals we must also set the second and third
......@@ -212,10 +206,6 @@ static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
regs->a6 = (unsigned long)&frame->uc;
return 0;
segv_and_exit:
force_sigsegv(signr, current);
return -EFAULT;
}
static inline void
......@@ -245,10 +235,11 @@ handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
/*
* handle the actual delivery of a signal to userspace
*/
static void handle_signal(int sig,
siginfo_t *info, struct k_sigaction *ka,
struct pt_regs *regs, int syscall)
static void handle_signal(struct ksignal *ksig, struct pt_regs *regs,
int syscall)
{
int ret;
/* Are we from a system call? */
if (syscall) {
/* If so, check system call restarting.. */
......@@ -259,7 +250,7 @@ static void handle_signal(int sig,
break;
case -ERESTARTSYS:
if (!(ka->sa.sa_flags & SA_RESTART)) {
if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
regs->a4 = -EINTR;
break;
}
......@@ -272,9 +263,8 @@ static void handle_signal(int sig,
}
/* Set up the stack frame */
if (setup_rt_frame(sig, ka, info, sigmask_to_save(), regs) < 0)
return;
signal_delivered(sig, info, ka, regs, 0);
ret = setup_rt_frame(ksig, sigmask_to_save(), regs);
signal_setup_done(ret, ksig, 0);
}
/*
......@@ -282,18 +272,15 @@ static void handle_signal(int sig,
*/
static void do_signal(struct pt_regs *regs, int syscall)
{
struct k_sigaction ka;
siginfo_t info;
int signr;
struct ksignal ksig;
/* we want the common case to go fast, which is why we may in certain
* cases get here from kernel mode */
if (!user_mode(regs))
return;
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) {
handle_signal(signr, &info, &ka, regs, syscall);
if (get_signal(&ksig)) {
handle_signal(&ksig, regs, syscall);
return;
}
......
......@@ -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;
}
......
......@@ -189,17 +189,9 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
/* Figure out where to put the new signal frame - 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;
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. */
sp &= ~3;
......@@ -215,23 +207,22 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
* trampoline.
*/
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)
{
int err;
unsigned long return_ip;
struct signal_frame __user *frame;
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],
......@@ -239,14 +230,14 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
}
if (err)
goto give_sigsegv;
return -EFAULT;
/*
* Set up to return from user-space. If provided, use a stub
* already located in user-space.
*/
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 in the signal return page. */
return_ip = cris_signal_return_page;
......@@ -264,7 +255,7 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
}
if (err)
goto give_sigsegv;
return -EFAULT;
/*
* Set up registers for signal handler.
......@@ -273,42 +264,37 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
* Where the code enter later.
* First argument, signo.
*/
regs->erp = (unsigned long) ka->sa.sa_handler;
regs->erp = (unsigned long) ksig->ka.sa.sa_handler;
regs->srp = return_ip;
regs->r10 = sig;
regs->r10 = ksig->sig;
/* 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)
setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs)
{
int err;
unsigned long return_ip;
struct rt_signal_frame __user *frame;
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;
/* TODO: what is the current->exec_domain stuff and invmap ? */
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));
......@@ -317,14 +303,14 @@ 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 user-space. If provided, use a stub
* already located in user-space.
*/
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 in the signal return page. */
return_ip = cris_signal_return_page + 6;
......@@ -345,7 +331,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
}
if (err)
goto give_sigsegv;
return -EFAULT;
/*
* Set up registers for signal handler.
......@@ -356,9 +342,9 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
* Second argument is (siginfo_t *).
* Third argument is unused.
*/
regs->erp = (unsigned long) ka->sa.sa_handler;
regs->erp = (unsigned long) ksig->ka.sa.sa_handler;
regs->srp = return_ip;
regs->r10 = sig;
regs->r10 = ksig->sig;
regs->r11 = (unsigned long) &frame->info;
regs->r12 = 0;
......@@ -366,17 +352,11 @@ 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;
}
/* Invoke a signal handler to, well, handle the signal. */
static inline void
handle_signal(int canrestart, unsigned long sig,
siginfo_t *info, struct k_sigaction *ka,
struct pt_regs * regs)
handle_signal(int canrestart, struct ksignal *ksig, struct pt_regs *regs)
{
sigset_t *oldset = sigmask_to_save();
int ret;
......@@ -404,7 +384,7 @@ handle_signal(int canrestart, unsigned long sig,
* 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;
}
......@@ -423,13 +403,12 @@ 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);
}
/*
......@@ -446,9 +425,7 @@ handle_signal(int canrestart, unsigned long sig,
void
do_signal(int canrestart, struct pt_regs *regs)
{
int signr;
siginfo_t info;
struct k_sigaction ka;
struct ksignal ksig;
/*
* The common case should go fast, which is why this point is
......@@ -458,11 +435,9 @@ 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;
}
......
......@@ -158,19 +158,10 @@ static int setup_sigcontext(struct sigcontext __user *sc, unsigned long mask)
/*
* Determine which stack to use..
*/
static inline void __user *get_sigframe(struct k_sigaction *ka,
static inline void __user *get_sigframe(struct ksignal *ksig,
size_t frame_size)
{
unsigned long sp;
/* Default to using normal stack */
sp = __frame->sp;
/* This is the X/Open sanctioned signal stack switching. */
if (ka->sa.sa_flags & SA_ONSTACK) {
if (! sas_ss_flags(sp))
sp = current->sas_ss_sp + current->sas_ss_size;
}
unsigned long sp = sigsp(__frame->sp, ksig);
return (void __user *) ((sp - frame_size) & ~7UL);
......@@ -180,17 +171,17 @@ static inline void __user *get_sigframe(struct k_sigaction *ka,
/*
*
*/
static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
static int setup_frame(struct ksignal *ksig, sigset_t *set)
{
struct sigframe __user *frame;
int rsig;
int rsig, sig = ksig->sig;
set_fs(USER_DS);
frame = get_sigframe(ka, sizeof(*frame));
frame = get_sigframe(ksig, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
goto give_sigsegv;
return -EFAULT;
rsig = sig;
if (sig < 32 &&
......@@ -199,22 +190,22 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
rsig = __current_thread_info->exec_domain->signal_invmap[sig];
if (__put_user(rsig, &frame->sig) < 0)
goto give_sigsegv;
return -EFAULT;
if (setup_sigcontext(&frame->sc, set->sig[0]))
goto give_sigsegv;
return -EFAULT;
if (_NSIG_WORDS > 1) {
if (__copy_to_user(frame->extramask, &set->sig[1],
sizeof(frame->extramask)))
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) {
if (__put_user(ka->sa.sa_restorer, &frame->pretcode) < 0)
goto give_sigsegv;
if (ksig->ka.sa.sa_flags & SA_RESTORER) {
if (__put_user(ksig->ka.sa.sa_restorer, &frame->pretcode) < 0)
return -EFAULT;
}
else {
/* Set up the following code on the stack:
......@@ -224,7 +215,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
if (__put_user((__sigrestore_t)frame->retcode, &frame->pretcode) ||
__put_user(0x8efc0000|__NR_sigreturn, &frame->retcode[0]) ||
__put_user(0xc0700000, &frame->retcode[1]))
goto give_sigsegv;
return -EFAULT;
flush_icache_range((unsigned long) frame->retcode,
(unsigned long) (frame->retcode + 2));
......@@ -233,14 +224,14 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
/* Set up registers for the signal handler */
if (current->personality & FDPIC_FUNCPTRS) {
struct fdpic_func_descriptor __user *funcptr =
(struct fdpic_func_descriptor __user *) ka->sa.sa_handler;
(struct fdpic_func_descriptor __user *) ksig->ka.sa.sa_handler;
struct fdpic_func_descriptor desc;
if (copy_from_user(&desc, funcptr, sizeof(desc)))
goto give_sigsegv;
return -EFAULT;
__frame->pc = desc.text;
__frame->gr15 = desc.GOT;
} else {
__frame->pc = (unsigned long) ka->sa.sa_handler;
__frame->pc = (unsigned long) ksig->ka.sa.sa_handler;
__frame->gr15 = 0;
}
......@@ -255,29 +246,23 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
#endif
return 0;
give_sigsegv:
force_sigsegv(sig, current);
return -EFAULT;
} /* end setup_frame() */
/*****************************************************************************/
/*
*
*/
static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
sigset_t *set)
static int setup_rt_frame(struct ksignal *ksig, sigset_t *set)
{
struct rt_sigframe __user *frame;
int rsig;
int rsig, sig = ksig->sig;
set_fs(USER_DS);
frame = get_sigframe(ka, sizeof(*frame));
frame = get_sigframe(ksig, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
goto give_sigsegv;
return -EFAULT;
rsig = sig;
if (sig < 32 &&
......@@ -288,28 +273,28 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
if (__put_user(rsig, &frame->sig) ||
__put_user(&frame->info, &frame->pinfo) ||
__put_user(&frame->uc, &frame->puc))
goto give_sigsegv;
return -EFAULT;
if (copy_siginfo_to_user(&frame->info, info))
goto give_sigsegv;
if (copy_siginfo_to_user(&frame->info, &ksig->info))
return -EFAULT;
/* Create the ucontext. */
if (__put_user(0, &frame->uc.uc_flags) ||
__put_user(NULL, &frame->uc.uc_link) ||
__save_altstack(&frame->uc.uc_stack, __frame->sp))
goto give_sigsegv;
return -EFAULT;
if (setup_sigcontext(&frame->uc.uc_mcontext, set->sig[0]))
goto give_sigsegv;
return -EFAULT;
if (__copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)))
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) {
if (__put_user(ka->sa.sa_restorer, &frame->pretcode))
goto give_sigsegv;
if (ksig->ka.sa.sa_flags & SA_RESTORER) {
if (__put_user(ksig->ka.sa.sa_restorer, &frame->pretcode))
return -EFAULT;
}
else {
/* Set up the following code on the stack:
......@@ -319,7 +304,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
if (__put_user((__sigrestore_t)frame->retcode, &frame->pretcode) ||
__put_user(0x8efc0000|__NR_rt_sigreturn, &frame->retcode[0]) ||
__put_user(0xc0700000, &frame->retcode[1]))
goto give_sigsegv;
return -EFAULT;
flush_icache_range((unsigned long) frame->retcode,
(unsigned long) (frame->retcode + 2));
......@@ -328,14 +313,14 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
/* Set up registers for signal handler */
if (current->personality & FDPIC_FUNCPTRS) {
struct fdpic_func_descriptor __user *funcptr =
(struct fdpic_func_descriptor __user *) ka->sa.sa_handler;
(struct fdpic_func_descriptor __user *) ksig->ka.sa.sa_handler;
struct fdpic_func_descriptor desc;
if (copy_from_user(&desc, funcptr, sizeof(desc)))
goto give_sigsegv;
return -EFAULT;
__frame->pc = desc.text;
__frame->gr15 = desc.GOT;
} else {
__frame->pc = (unsigned long) ka->sa.sa_handler;
__frame->pc = (unsigned long) ksig->ka.sa.sa_handler;
__frame->gr15 = 0;
}
......@@ -349,21 +334,15 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
sig, current->comm, current->pid, frame, __frame->pc,
frame->pretcode);
#endif
return 0;
give_sigsegv:
force_sigsegv(sig, current);
return -EFAULT;
} /* end setup_rt_frame() */
/*****************************************************************************/
/*
* OK, we're invoking a handler
*/
static void handle_signal(unsigned long sig, siginfo_t *info,
struct k_sigaction *ka)
static void handle_signal(struct ksignal *ksig)
{
sigset_t *oldset = sigmask_to_save();
int ret;
......@@ -378,7 +357,7 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
break;
case -ERESTARTSYS:
if (!(ka->sa.sa_flags & SA_RESTART)) {
if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
__frame->gr8 = -EINTR;
break;
}
......@@ -392,16 +371,12 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
}
/* Set up the stack frame */
if (ka->sa.sa_flags & SA_SIGINFO)
ret = setup_rt_frame(sig, ka, info, oldset);
if (ksig->ka.sa.sa_flags & SA_SIGINFO)
ret = setup_rt_frame(ksig, oldset);
else
ret = setup_frame(sig, ka, oldset);
if (ret)
return;
ret = setup_frame(ksig, oldset);
signal_delivered(sig, info, ka, __frame,
test_thread_flag(TIF_SINGLESTEP));
signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
} /* end handle_signal() */
/*****************************************************************************/
......@@ -412,13 +387,10 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
*/
static void do_signal(void)
{
struct k_sigaction ka;
siginfo_t info;
int signr;
struct ksignal ksig;
signr = get_signal_to_deliver(&info, &ka, __frame, NULL);
if (signr > 0) {
handle_signal(signr, &info, &ka);
if (get_signal(&ksig)) {
handle_signal(&ksig);
return;
}
......
......@@ -36,18 +36,10 @@ struct rt_sigframe {
struct ucontext uc;
};
static void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
static void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs,
size_t frame_size)
{
unsigned long sp = regs->r29;
/* check if we would overflow the alt stack */
if (on_sig_stack(sp) && !likely(on_sig_stack(sp - frame_size)))
return (void __user __force *)-1UL;
/* Switch to signal stack if appropriate */
if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0))
sp = current->sas_ss_sp + current->sas_ss_size;
unsigned long sp = sigsp(regs->r29, ksig);
return (void __user *)((sp - frame_size) & ~(sizeof(long long) - 1));
}
......@@ -112,20 +104,20 @@ static int restore_sigcontext(struct pt_regs *regs,
/*
* Setup signal stack frame with siginfo structure
*/
static int setup_rt_frame(int signr, 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)
{
int err = 0;
struct rt_sigframe __user *frame;
struct hexagon_vdso *vdso = current->mm->context.vdso;
frame = get_sigframe(ka, regs, sizeof(struct rt_sigframe));
frame = get_sigframe(ksig, regs, 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))
goto sigsegv;
if (copy_siginfo_to_user(&frame->info, &ksig->info))
return -EFAULT;
/* The on-stack signal trampoline is no longer executed;
* however, the libgcc signal frame unwinding code checks for
......@@ -137,29 +129,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 |= __save_altstack(&frame->uc.uc_stack, user_stack_pointer(regs));
if (err)
goto sigsegv;
return -EFAULT;
/* Load r0/r1 pair with signumber/siginfo pointer... */
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->r31 = (unsigned long) vdso->rt_signal_trampoline;
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;
sigsegv:
force_sigsegv(signr, current);
return -EFAULT;
}
/*
* Setup invocation of signal handler
*/
static void handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
struct pt_regs *regs)
static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
{
int ret;
/*
* If we're handling a signal that aborted a system call,
* set up the error return value before adding the signal
......@@ -173,7 +162,7 @@ static void handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
regs->r00 = -EINTR;
break;
case -ERESTARTSYS:
if (!(ka->sa.sa_flags & SA_RESTART)) {
if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
regs->r00 = -EINTR;
break;
}
......@@ -193,11 +182,9 @@ static void handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
* only set up the rt_frame flavor.
*/
/* If there was an error on setup, no signal was delivered. */
if (setup_rt_frame(sig, ka, info, sigmask_to_save(), regs) < 0)
return;
ret = setup_rt_frame(ksig, sigmask_to_save(), regs);
signal_delivered(sig, info, ka, regs,
test_thread_flag(TIF_SINGLESTEP));
signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
}
/*
......@@ -205,17 +192,13 @@ static void handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
*/
void do_signal(struct pt_regs *regs)
{
struct k_sigaction sigact;
siginfo_t info;
int signo;
struct ksignal ksig;
if (!user_mode(regs))
return;
signo = get_signal_to_deliver(&info, &sigact, regs, NULL);
if (signo > 0) {
handle_signal(signo, &info, &sigact, regs);
if (get_signal(&ksig)) {
handle_signal(&ksig, regs);
return;
}
......
......@@ -309,12 +309,11 @@ force_sigsegv_info (int sig, void __user *addr)
si.si_uid = from_kuid_munged(current_user_ns(), current_uid());
si.si_addr = addr;
force_sig_info(SIGSEGV, &si, current);
return 0;
return 1;
}
static long
setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set,
struct sigscratch *scr)
setup_frame(struct ksignal *ksig, sigset_t *set, struct sigscratch *scr)
{
extern char __kernel_sigtramp[];
unsigned long tramp_addr, new_rbs = 0, new_sp;
......@@ -323,7 +322,7 @@ setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set,
new_sp = scr->pt.r12;
tramp_addr = (unsigned long) __kernel_sigtramp;
if (ka->sa.sa_flags & SA_ONSTACK) {
if (ksig->ka.sa.sa_flags & SA_ONSTACK) {
int onstack = sas_ss_flags(new_sp);
if (onstack == 0) {
......@@ -347,29 +346,29 @@ setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set,
*/
check_sp = (new_sp - sizeof(*frame)) & -STACK_ALIGN;
if (!likely(on_sig_stack(check_sp)))
return force_sigsegv_info(sig, (void __user *)
return force_sigsegv_info(ksig->sig, (void __user *)
check_sp);
}
}
frame = (void __user *) ((new_sp - sizeof(*frame)) & -STACK_ALIGN);
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
return force_sigsegv_info(sig, frame);
return force_sigsegv_info(ksig->sig, frame);
err = __put_user(sig, &frame->arg0);
err = __put_user(ksig->sig, &frame->arg0);
err |= __put_user(&frame->info, &frame->arg1);
err |= __put_user(&frame->sc, &frame->arg2);
err |= __put_user(new_rbs, &frame->sc.sc_rbs_base);
err |= __put_user(0, &frame->sc.sc_loadrs); /* initialize to zero */
err |= __put_user(ka->sa.sa_handler, &frame->handler);
err |= __put_user(ksig->ka.sa.sa_handler, &frame->handler);
err |= copy_siginfo_to_user(&frame->info, info);
err |= copy_siginfo_to_user(&frame->info, &ksig->info);
err |= __save_altstack(&frame->sc.sc_stack, scr->pt.r12);
err |= setup_sigcontext(&frame->sc, set, scr);
if (unlikely(err))
return force_sigsegv_info(sig, frame);
return force_sigsegv_info(ksig->sig, frame);
scr->pt.r12 = (unsigned long) frame - 16; /* new stack pointer */
scr->pt.ar_fpsr = FPSR_DEFAULT; /* reset fpsr for signal handler */
......@@ -394,22 +393,20 @@ setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set,
#if DEBUG_SIG
printk("SIG deliver (%s:%d): sig=%d sp=%lx ip=%lx handler=%p\n",
current->comm, current->pid, sig, scr->pt.r12, frame->sc.sc_ip, frame->handler);
current->comm, current->pid, ksig->sig, scr->pt.r12, frame->sc.sc_ip, frame->handler);
#endif
return 1;
return 0;
}
static long
handle_signal (unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
struct sigscratch *scr)
handle_signal (struct ksignal *ksig, struct sigscratch *scr)
{
if (!setup_frame(sig, ka, info, sigmask_to_save(), scr))
return 0;
int ret = setup_frame(ksig, sigmask_to_save(), scr);
signal_delivered(sig, info, ka, &scr->pt,
test_thread_flag(TIF_SINGLESTEP));
if (!ret)
signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
return 1;
return ret;
}
/*
......@@ -419,17 +416,16 @@ handle_signal (unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
void
ia64_do_signal (struct sigscratch *scr, long in_syscall)
{
struct k_sigaction ka;
siginfo_t info;
long restart = in_syscall;
long errno = scr->pt.r8;
struct ksignal ksig;
/*
* This only loops in the rare cases of handle_signal() failing, in which case we
* need to push through a forced SIGSEGV.
*/
while (1) {
int signr = get_signal_to_deliver(&info, &ka, &scr->pt, NULL);
get_signal(&ksig);
/*
* get_signal_to_deliver() may have run a debugger (via notify_parent())
......@@ -446,7 +442,7 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall)
*/
restart = 0;
if (signr <= 0)
if (ksig.sig <= 0)
break;
if (unlikely(restart)) {
......@@ -458,7 +454,7 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall)
break;
case ERESTARTSYS:
if ((ka.sa.sa_flags & SA_RESTART) == 0) {
if ((ksig.ka.sa.sa_flags & SA_RESTART) == 0) {
scr->pt.r8 = EINTR;
/* note: scr->pt.r10 is already -1 */
break;
......@@ -473,7 +469,7 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall)
* Whee! Actually deliver the signal. If the delivery failed, we need to
* continue to iterate in this loop so we can deliver the SIGSEGV...
*/
if (handle_signal(signr, &ka, &info, scr))
if (handle_signal(&ksig, scr))
return;
}
......
......@@ -162,28 +162,22 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
* Determine which stack to use..
*/
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)
{
/* This is the X/Open sanctioned signal stack switching. */
if (ka->sa.sa_flags & SA_ONSTACK) {
if (sas_ss_flags(sp) == 0)
sp = current->sas_ss_sp + current->sas_ss_size;
}
return (void __user *)((sp - frame_size) & -8ul);
return (void __user *)((sigsp(sp, ksig) - frame_size) & -8ul);
}
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;
int err = 0;
int signal;
int signal, sig = ksig->sig;
frame = get_sigframe(ka, regs->spu, sizeof(*frame));
frame = get_sigframe(ksig, regs->spu, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
goto give_sigsegv;
return -EFAULT;
signal = current_thread_info()->exec_domain
&& current_thread_info()->exec_domain->signal_invmap
......@@ -193,13 +187,13 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
err |= __put_user(signal, &frame->sig);
if (err)
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;
/* Create the ucontext. */
err |= __put_user(0, &frame->uc.uc_flags);
......@@ -208,17 +202,17 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0]);
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
if (err)
goto give_sigsegv;
return -EFAULT;
/* Set up to return from userspace. */
regs->lr = (unsigned long)ka->sa.sa_restorer;
regs->lr = (unsigned long)ksig->ka.sa.sa_restorer;
/* Set up registers for signal handler */
regs->spu = (unsigned long)frame;
regs->r0 = signal; /* Arg for signal handler */
regs->r1 = (unsigned long)&frame->info;
regs->r2 = (unsigned long)&frame->uc;
regs->bpc = (unsigned long)ka->sa.sa_handler;
regs->bpc = (unsigned long)ksig->ka.sa.sa_handler;
set_fs(USER_DS);
......@@ -228,10 +222,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
#endif
return 0;
give_sigsegv:
force_sigsegv(sig, current);
return -EFAULT;
}
static int prev_insn(struct pt_regs *regs)
......@@ -252,9 +242,10 @@ static int prev_insn(struct pt_regs *regs)
*/
static void
handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
struct pt_regs *regs)
handle_signal(struct ksignal *ksig, struct pt_regs *regs)
{
int ret;
/* Are we from a system call? */
if (regs->syscall_nr >= 0) {
/* If so, check system call restarting.. */
......@@ -265,7 +256,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
break;
case -ERESTARTSYS:
if (!(ka->sa.sa_flags & SA_RESTART)) {
if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
regs->r0 = -EINTR;
break;
}
......@@ -278,10 +269,9 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
}
/* Set up the stack frame */
if (setup_rt_frame(sig, ka, info, sigmask_to_save(), regs))
return;
ret = setup_rt_frame(ksig, sigmask_to_save(), regs);
signal_delivered(sig, info, ka, regs, 0);
signal_setup_done(ret, ksig, 0);
}
/*
......@@ -291,9 +281,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
*/
static void do_signal(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
......@@ -304,8 +292,7 @@ static void do_signal(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)) {
/* Re-enable any watchpoints before delivering the
* signal to user space. The processor register will
* have been cleared if the watchpoint triggered
......@@ -313,7 +300,7 @@ static void do_signal(struct pt_regs *regs)
*/
/* Whee! Actually deliver the signal. */
handle_signal(signr, &ka, &info, regs);
handle_signal(&ksig, regs);
return;
}
......
......@@ -835,38 +835,30 @@ static inline int rt_setup_ucontext(struct ucontext __user *uc, struct pt_regs *
}
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 usp;
/* Default to using normal stack. */
usp = rdusp();
unsigned long usp = sigsp(rdusp(), ksig);
/* This is the X/Open sanctioned signal stack switching. */
if (ka->sa.sa_flags & SA_ONSTACK) {
if (!sas_ss_flags(usp))
usp = current->sas_ss_sp + current->sas_ss_size;
}
return (void __user *)((usp - frame_size) & -8UL);
}
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;
int fsize = frame_extra_sizes(regs->format);
struct sigcontext context;
int err = 0;
int err = 0, sig = ksig->sig;
if (fsize < 0) {
#ifdef DEBUG
printk ("setup_frame: Unknown frame format %#x\n",
regs->format);
#endif
goto give_sigsegv;
return -EFAULT;
}
frame = get_sigframe(ka, regs, sizeof(*frame) + fsize);
frame = get_sigframe(ksig, sizeof(*frame) + fsize);
if (fsize)
err |= copy_to_user (frame + 1, regs + 1, fsize);
......@@ -899,7 +891,7 @@ static int setup_frame (int sig, struct k_sigaction *ka,
#endif
if (err)
goto give_sigsegv;
return -EFAULT;
push_cache ((unsigned long) &frame->retcode);
......@@ -908,7 +900,7 @@ static int setup_frame (int sig, struct k_sigaction *ka,
* to destroy is successfully copied to sigframe.
*/
wrusp ((unsigned long) frame);
regs->pc = (unsigned long) ka->sa.sa_handler;
regs->pc = (unsigned long) ksig->ka.sa.sa_handler;
adjustformat(regs);
/*
......@@ -934,28 +926,24 @@ static int setup_frame (int sig, struct k_sigaction *ka,
tregs->sr = regs->sr;
}
return 0;
give_sigsegv:
force_sigsegv(sig, current);
return err;
}
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;
int fsize = frame_extra_sizes(regs->format);
int err = 0;
int err = 0, sig = ksig->sig;
if (fsize < 0) {
#ifdef DEBUG
printk ("setup_frame: Unknown frame format %#x\n",
regs->format);
#endif
goto give_sigsegv;
return -EFAULT;
}
frame = get_sigframe(ka, regs, sizeof(*frame));
frame = get_sigframe(ksig, sizeof(*frame));
if (fsize)
err |= copy_to_user (&frame->uc.uc_extra, regs + 1, fsize);
......@@ -968,7 +956,7 @@ static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
&frame->sig);
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);
/* Create the ucontext. */
err |= __put_user(0, &frame->uc.uc_flags);
......@@ -996,7 +984,7 @@ static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
#endif /* CONFIG_MMU */
if (err)
goto give_sigsegv;
return -EFAULT;
push_cache ((unsigned long) &frame->retcode);
......@@ -1005,7 +993,7 @@ static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
* to destroy is successfully copied to sigframe.
*/
wrusp ((unsigned long) frame);
regs->pc = (unsigned long) ka->sa.sa_handler;
regs->pc = (unsigned long) ksig->ka.sa.sa_handler;
adjustformat(regs);
/*
......@@ -1031,10 +1019,6 @@ static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
tregs->sr = regs->sr;
}
return 0;
give_sigsegv:
force_sigsegv(sig, current);
return err;
}
static inline void
......@@ -1074,26 +1058,22 @@ handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
* OK, we're invoking a handler
*/
static 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 err;
/* are we from a system call? */
if (regs->orig_d0 >= 0)
/* If so, check system call restarting.. */
handle_restart(regs, ka, 1);
handle_restart(regs, &ksig->ka, 1);
/* set up the stack frame */
if (ka->sa.sa_flags & SA_SIGINFO)
err = setup_rt_frame(sig, ka, info, oldset, regs);
if (ksig->ka.sa.sa_flags & SA_SIGINFO)
err = setup_rt_frame(ksig, oldset, regs);
else
err = setup_frame(sig, ka, oldset, regs);
if (err)
return;
err = setup_frame(ksig, oldset, regs);
signal_delivered(sig, info, ka, regs, 0);
signal_setup_done(err, ksig, 0);
if (test_thread_flag(TIF_DELAYED_TRACE)) {
regs->sr &= ~0x8000;
......@@ -1108,16 +1088,13 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
*/
static void do_signal(struct pt_regs *regs)
{
siginfo_t info;
struct k_sigaction ka;
int signr;
struct ksignal ksig;
current->thread.esp0 = (unsigned long) regs;
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) {
if (get_signal(&ksig)) {
/* Whee! Actually deliver the signal. */
handle_signal(signr, &ka, &info, regs);
handle_signal(&ksig, regs);
return;
}
......
......@@ -140,13 +140,9 @@ static int setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
/*
* Determine which stack to use..
*/
static void __user *get_sigframe(struct k_sigaction *ka, unsigned long sp,
size_t frame_size)
static void __user *get_sigframe(struct ksignal *ksig, unsigned long sp)
{
/* Meta stacks grows upwards */
if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0))
sp = current->sas_ss_sp;
sp = sigsp(sp, ksig);
sp = (sp + 7) & ~7; /* 8byte align stack */
return (void __user *)sp;
......@@ -159,7 +155,7 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
int err;
unsigned long code;
frame = get_sigframe(&ksig->ka, regs->REG_SP, sizeof(*frame));
frame = get_sigframe(ksig, regs->REG_SP);
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
return -EFAULT;
......
......@@ -145,22 +145,19 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
* Determine which stack to use..
*/
static inline void __user *
get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
get_sigframe(struct ksignal *ksig, struct pt_regs *regs, size_t frame_size)
{
/* Default to using normal stack */
unsigned long sp = regs->r1;
if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && !on_sig_stack(sp))
sp = current->sas_ss_sp + current->sas_ss_size;
unsigned long sp = sigsp(regs->r1, ksig);
return (void __user *)((sp - frame_size) & -8UL);
}
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;
int err = 0;
int err = 0, sig = ksig->sig;
int signal;
unsigned long address = 0;
#ifdef CONFIG_MMU
......@@ -168,10 +165,10 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
pte_t *ptep;
#endif
frame = get_sigframe(ka, regs, sizeof(*frame));
frame = get_sigframe(ksig, regs, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
goto give_sigsegv;
return -EFAULT;
signal = current_thread_info()->exec_domain
&& current_thread_info()->exec_domain->signal_invmap
......@@ -179,8 +176,8 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
? current_thread_info()->exec_domain->signal_invmap[sig]
: sig;
if (info)
err |= copy_siginfo_to_user(&frame->info, info);
if (ksig->ka.sa.sa_flags & SA_SIGINFO)
err |= copy_siginfo_to_user(&frame->info, &ksig->info);
/* Create the ucontext. */
err |= __put_user(0, &frame->uc.uc_flags);
......@@ -227,7 +224,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
flush_dcache_range(address, address + 8);
#endif
if (err)
goto give_sigsegv;
return -EFAULT;
/* Set up registers for signal handler */
regs->r1 = (unsigned long) frame;
......@@ -237,7 +234,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
regs->r6 = (unsigned long) &frame->info; /* arg 1: siginfo */
regs->r7 = (unsigned long) &frame->uc; /* arg2: ucontext */
/* Offset to handle microblaze rtid r14, 0 */
regs->pc = (unsigned long)ka->sa.sa_handler;
regs->pc = (unsigned long)ksig->ka.sa.sa_handler;
set_fs(USER_DS);
......@@ -247,10 +244,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
#endif
return 0;
give_sigsegv:
force_sigsegv(sig, current);
return -EFAULT;
}
/* Handle restarting system calls */
......@@ -283,23 +276,15 @@ handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
*/
static void
handle_signal(unsigned long 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;
/* Set up the stack frame */
if (ka->sa.sa_flags & SA_SIGINFO)
ret = setup_rt_frame(sig, ka, info, oldset, regs);
else
ret = setup_rt_frame(sig, ka, NULL, oldset, regs);
ret = setup_rt_frame(ksig, oldset, regs);
if (ret)
return;
signal_delivered(sig, info, ka, regs,
test_thread_flag(TIF_SINGLESTEP));
signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
}
/*
......@@ -313,21 +298,19 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
*/
static void do_signal(struct pt_regs *regs, int in_syscall)
{
siginfo_t info;
int signr;
struct k_sigaction ka;
struct ksignal ksig;
#ifdef DEBUG_SIG
pr_info("do signal: %p %d\n", regs, in_syscall);
pr_info("do signal2: %lx %lx %ld [%lx]\n", regs->pc, regs->r1,
regs->r12, current_thread_info()->flags);
#endif
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) {
if (get_signal(&ksig)) {
/* Whee! Actually deliver the signal. */
if (in_syscall)
handle_restart(regs, &ka, 1);
handle_signal(signr, &ka, &info, regs);
handle_restart(regs, &ksig.ka, 1);
handle_signal(&ksig, regs);
return;
}
......
......@@ -13,13 +13,11 @@
#include <asm/siginfo.h>
struct mips_abi {
int (* const setup_frame)(void *sig_return, struct k_sigaction *ka,
struct pt_regs *regs, int signr,
sigset_t *set);
int (* const setup_frame)(void *sig_return, struct ksignal *ksig,
struct pt_regs *regs, sigset_t *set);
const unsigned long signal_return_offset;
int (* const setup_rt_frame)(void *sig_return, struct k_sigaction *ka,
struct pt_regs *regs, int signr,
sigset_t *set, siginfo_t *info);
int (* const setup_rt_frame)(void *sig_return, struct ksignal *ksig,
struct pt_regs *regs, sigset_t *set);
const unsigned long rt_signal_return_offset;
const unsigned long restart;
};
......
......@@ -22,7 +22,7 @@
/*
* Determine which stack to use..
*/
extern void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
extern void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs,
size_t frame_size);
/* Check and clear pending FPU exceptions in saved CSR */
extern int fpcsr_pending(unsigned int __user *fpcsr);
......
......@@ -280,7 +280,7 @@ int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
return err;
}
void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs,
size_t frame_size)
{
unsigned long sp;
......@@ -295,9 +295,7 @@ void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
*/
sp -= 32;
/* This is the X/Open sanctioned signal stack switching. */
if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
sp = current->sas_ss_sp + current->sas_ss_size;
sp = sigsp(sp, ksig);
return (void __user *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? ~(cpu_icache_line_size()-1) : ALMASK));
}
......@@ -428,20 +426,20 @@ asmlinkage void sys_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
}
#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, 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 +451,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, 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 +486,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 +498,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 +523,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 +545,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 +559,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);
if (ret)
return;
ret = abi->setup_frame(vdso + abi->signal_return_offset, ksig,
regs, oldset);
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;
}
......
......@@ -490,21 +490,21 @@ asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
force_sig(SIGSEGV, current);
}
static int setup_frame_32(void *sig_return, struct k_sigaction *ka,
struct pt_regs *regs, int signr, sigset_t *set)
static int setup_frame_32(void *sig_return, struct ksignal *ksig,
struct pt_regs *regs, sigset_t *set)
{
struct sigframe32 __user *frame;
int err = 0;
frame = get_sigframe(ka, regs, sizeof(*frame));
frame = get_sigframe(ksig, regs, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
goto give_sigsegv;
return -EFAULT;
err |= setup_sigcontext32(regs, &frame->sf_sc);
err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
if (err)
goto give_sigsegv;
return -EFAULT;
/*
* Arguments to signal handler:
......@@ -516,37 +516,32 @@ static int setup_frame_32(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;
}
static int setup_rt_frame_32(void *sig_return, struct k_sigaction *ka,
struct pt_regs *regs, int signr, sigset_t *set,
siginfo_t *info)
static int setup_rt_frame_32(void *sig_return, struct ksignal *ksig,
struct pt_regs *regs, sigset_t *set)
{
struct rt_sigframe32 __user *frame;
int err = 0;
frame = get_sigframe(ka, regs, sizeof(*frame));
frame = get_sigframe(ksig, regs, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
goto give_sigsegv;
return -EFAULT;
/* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
err |= copy_siginfo_to_user32(&frame->rs_info, info);
err |= copy_siginfo_to_user32(&frame->rs_info, &ksig->info);
/* Create the ucontext. */
err |= __put_user(0, &frame->rs_uc.uc_flags);
......@@ -556,7 +551,7 @@ static int setup_rt_frame_32(void *sig_return, struct k_sigaction *ka,
err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
if (err)
goto give_sigsegv;
return -EFAULT;
/*
* Arguments to signal handler:
......@@ -568,22 +563,18 @@ static int setup_rt_frame_32(void *sig_return, struct k_sigaction *ka,
* $25 and c0_epc point to the signal handler, $29 points to
* the struct rt_sigframe32.
*/
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;
}
/*
......
......@@ -102,18 +102,18 @@ asmlinkage void sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
force_sig(SIGSEGV, current);
}
static int setup_rt_frame_n32(void *sig_return, struct k_sigaction *ka,
struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info)
static int setup_rt_frame_n32(void *sig_return, struct ksignal *ksig,
struct pt_regs *regs, sigset_t *set)
{
struct rt_sigframe_n32 __user *frame;
int err = 0;
frame = get_sigframe(ka, regs, sizeof(*frame));
frame = get_sigframe(ksig, regs, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
goto give_sigsegv;
return -EFAULT;
/* Create siginfo. */
err |= copy_siginfo_to_user32(&frame->rs_info, info);
err |= copy_siginfo_to_user32(&frame->rs_info, &ksig->info);
/* Create the ucontext. */
err |= __put_user(0, &frame->rs_uc.uc_flags);
......@@ -123,7 +123,7 @@ static int setup_rt_frame_n32(void *sig_return, struct k_sigaction *ka,
err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
if (err)
goto give_sigsegv;
return -EFAULT;
/*
* Arguments to signal handler:
......@@ -135,22 +135,18 @@ static int setup_rt_frame_n32(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_n32 = {
......
......@@ -186,20 +186,11 @@ static int setup_sigcontext(struct sigcontext __user *sc,
/*
* determine which stack to use..
*/
static inline void __user *get_sigframe(struct k_sigaction *ka,
static inline void __user *get_sigframe(struct ksignal *ksig,
struct pt_regs *regs,
size_t frame_size)
{
unsigned long sp;
/* default to using normal stack */
sp = regs->sp;
/* this is the X/Open sanctioned signal stack switching. */
if (ka->sa.sa_flags & SA_ONSTACK) {
if (sas_ss_flags(sp) == 0)
sp = current->sas_ss_sp + current->sas_ss_size;
}
unsigned long sp = sigsp(regs->sp, ksig);
return (void __user *) ((sp - frame_size) & ~7UL);
}
......@@ -207,16 +198,16 @@ static inline void __user *get_sigframe(struct k_sigaction *ka,
/*
* set up a normal signal frame
*/
static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
static int setup_frame(struct ksignal *ksig, sigset_t *set,
struct pt_regs *regs)
{
struct sigframe __user *frame;
int rsig;
int rsig, sig = ksig->sig;
frame = get_sigframe(ka, regs, sizeof(*frame));
frame = get_sigframe(ksig, regs, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
goto give_sigsegv;
return -EFAULT;
rsig = sig;
if (sig < 32 &&
......@@ -226,40 +217,40 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
if (__put_user(rsig, &frame->sig) < 0 ||
__put_user(&frame->sc, &frame->psc) < 0)
goto give_sigsegv;
return -EFAULT;
if (setup_sigcontext(&frame->sc, &frame->fpuctx, regs, set->sig[0]))
goto give_sigsegv;
return -EFAULT;
if (_NSIG_WORDS > 1) {
if (__copy_to_user(frame->extramask, &set->sig[1],
sizeof(frame->extramask)))
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) {
if (__put_user(ka->sa.sa_restorer, &frame->pretcode))
goto give_sigsegv;
if (ksig->ka.sa.sa_flags & SA_RESTORER) {
if (__put_user(ksig->ka.sa.sa_restorer, &frame->pretcode))
return -EFAULT;
} else {
if (__put_user((void (*)(void))frame->retcode,
&frame->pretcode))
goto give_sigsegv;
return -EFAULT;
/* this is mov $,d0; syscall 0 */
if (__put_user(0x2c, (char *)(frame->retcode + 0)) ||
__put_user(__NR_sigreturn, (char *)(frame->retcode + 1)) ||
__put_user(0x00, (char *)(frame->retcode + 2)) ||
__put_user(0xf0, (char *)(frame->retcode + 3)) ||
__put_user(0xe0, (char *)(frame->retcode + 4)))
goto give_sigsegv;
return -EFAULT;
flush_icache_range((unsigned long) frame->retcode,
(unsigned long) frame->retcode + 5);
}
/* set up registers for signal handler */
regs->sp = (unsigned long) frame;
regs->pc = (unsigned long) ka->sa.sa_handler;
regs->pc = (unsigned long) ksig->ka.sa.sa_handler;
regs->d0 = sig;
regs->d1 = (unsigned long) &frame->sc;
......@@ -270,25 +261,21 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
#endif
return 0;
give_sigsegv:
force_sigsegv(sig, current);
return -EFAULT;
}
/*
* set up a realtime signal frame
*/
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;
int rsig;
int rsig, sig = ksig->sig;
frame = get_sigframe(ka, regs, sizeof(*frame));
frame = get_sigframe(ksig, regs, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
goto give_sigsegv;
return -EFAULT;
rsig = sig;
if (sig < 32 &&
......@@ -299,8 +286,8 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
if (__put_user(rsig, &frame->sig) ||
__put_user(&frame->info, &frame->pinfo) ||
__put_user(&frame->uc, &frame->puc) ||
copy_siginfo_to_user(&frame->info, info))
goto give_sigsegv;
copy_siginfo_to_user(&frame->info, &ksig->info))
return -EFAULT;
/* create the ucontext. */
if (__put_user(0, &frame->uc.uc_flags) ||
......@@ -309,13 +296,14 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
setup_sigcontext(&frame->uc.uc_mcontext,
&frame->fpuctx, regs, set->sig[0]) ||
__copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)))
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) {
if (__put_user(ka->sa.sa_restorer, &frame->pretcode))
goto give_sigsegv;
if (ksig->ka.sa.sa_flags & SA_RESTORER) {
if (__put_user(ksig->ka.sa.sa_restorer, &frame->pretcode))
return -EFAULT;
} else {
if (__put_user((void(*)(void))frame->retcode,
&frame->pretcode) ||
......@@ -326,7 +314,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
__put_user(0x00, (char *)(frame->retcode + 2)) ||
__put_user(0xf0, (char *)(frame->retcode + 3)) ||
__put_user(0xe0, (char *)(frame->retcode + 4)))
goto give_sigsegv;
return -EFAULT;
flush_icache_range((u_long) frame->retcode,
(u_long) frame->retcode + 5);
......@@ -334,7 +322,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
/* Set up registers for signal handler */
regs->sp = (unsigned long) frame;
regs->pc = (unsigned long) ka->sa.sa_handler;
regs->pc = (unsigned long) ksig->ka.sa.sa_handler;
regs->d0 = sig;
regs->d1 = (long) &frame->info;
......@@ -345,10 +333,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
#endif
return 0;
give_sigsegv:
force_sigsegv(sig, current);
return -EFAULT;
}
static inline void stepback(struct pt_regs *regs)
......@@ -360,9 +344,7 @@ static inline void stepback(struct pt_regs *regs)
/*
* handle the actual delivery of a signal to userspace
*/
static int handle_signal(int sig,
siginfo_t *info, struct k_sigaction *ka,
struct pt_regs *regs)
static int handle_signal(struct ksignal *ksig, struct pt_regs *regs)
{
sigset_t *oldset = sigmask_to_save();
int ret;
......@@ -377,7 +359,7 @@ static int handle_signal(int sig,
break;
case -ERESTARTSYS:
if (!(ka->sa.sa_flags & SA_RESTART)) {
if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
regs->d0 = -EINTR;
break;
}
......@@ -390,15 +372,12 @@ static int handle_signal(int 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);
if (ret)
return ret;
ret = setup_frame(ksig, oldset, regs);
signal_delivered(sig, info, ka, regs,
test_thread_flag(TIF_SINGLESTEP));
signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
return 0;
}
......@@ -407,15 +386,10 @@ static int handle_signal(int sig,
*/
static void do_signal(struct pt_regs *regs)
{
struct k_sigaction ka;
siginfo_t info;
int signr;
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) {
if (handle_signal(signr, &info, &ka, regs) == 0) {
}
struct ksignal ksig;
if (get_signal(&ksig)) {
handle_signal(&ksig, regs);
return;
}
......
......@@ -132,30 +132,16 @@ static inline unsigned long align_sigframe(unsigned long sp)
* or the alternate stack.
*/
static inline void __user *get_sigframe(struct k_sigaction *ka,
static inline void __user *get_sigframe(struct ksignal *ksig,
struct pt_regs *regs, size_t frame_size)
{
unsigned long sp = regs->sp;
int onsigstack = on_sig_stack(sp);
/* redzone */
sp -= STACK_FRAME_OVERHEAD;
/* This is the X/Open sanctioned signal stack switching. */
if ((ka->sa.sa_flags & SA_ONSTACK) && !onsigstack) {
if (current->sas_ss_size)
sp = current->sas_ss_sp + current->sas_ss_size;
}
sp = sigsp(sp, ksig);
sp = align_sigframe(sp - frame_size);
/*
* If we are on the alternate signal stack and would overflow it, don't.
* Return an always-bogus address instead so we will die with SIGSEGV.
*/
if (onsigstack && !likely(on_sig_stack(sp)))
return (void __user *)-1L;
return (void __user *)sp;
}
......@@ -173,7 +159,7 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
unsigned long return_ip;
int err = 0;
frame = get_sigframe(&ksig->ka, regs, sizeof(*frame));
frame = get_sigframe(ksig, regs, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
return -EFAULT;
......
......@@ -227,8 +227,8 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, int in_sysc
}
static long
setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
sigset_t *set, struct pt_regs *regs, int in_syscall)
setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs,
int in_syscall)
{
struct rt_sigframe __user *frame;
unsigned long rp, usp;
......@@ -241,10 +241,10 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
usp = (regs->gr[30] & ~(0x01UL));
/*FIXME: frame_size parameter is unused, remove it. */
frame = get_sigframe(ka, usp, sizeof(*frame));
frame = get_sigframe(&ksig->ka, usp, sizeof(*frame));
DBG(1,"SETUP_RT_FRAME: START\n");
DBG(1,"setup_rt_frame: frame %p info %p\n", frame, info);
DBG(1,"setup_rt_frame: frame %p info %p\n", frame, ksig->info);
#ifdef CONFIG_64BIT
......@@ -253,7 +253,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
if (is_compat_task()) {
DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &compat_frame->info);
err |= copy_siginfo_to_user32(&compat_frame->info, info);
err |= copy_siginfo_to_user32(&compat_frame->info, &ksig->info);
err |= __compat_save_altstack( &compat_frame->uc.uc_stack, regs->gr[30]);
DBG(1,"setup_rt_frame: frame->uc = 0x%p\n", &compat_frame->uc);
DBG(1,"setup_rt_frame: frame->uc.uc_mcontext = 0x%p\n", &compat_frame->uc.uc_mcontext);
......@@ -265,7 +265,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
#endif
{
DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &frame->info);
err |= copy_siginfo_to_user(&frame->info, info);
err |= copy_siginfo_to_user(&frame->info, &ksig->info);
err |= __save_altstack(&frame->uc.uc_stack, regs->gr[30]);
DBG(1,"setup_rt_frame: frame->uc = 0x%p\n", &frame->uc);
DBG(1,"setup_rt_frame: frame->uc.uc_mcontext = 0x%p\n", &frame->uc.uc_mcontext);
......@@ -275,7 +275,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
}
if (err)
goto give_sigsegv;
return -EFAULT;
/* Set up to return from userspace. If provided, use a stub
already in userspace. The first words of tramp are used to
......@@ -312,9 +312,9 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
rp = (unsigned long) &frame->tramp[SIGRESTARTBLOCK_TRAMP];
if (err)
goto give_sigsegv;
return -EFAULT;
haddr = A(ka->sa.sa_handler);
haddr = A(ksig->ka.sa.sa_handler);
/* The sa_handler may be a pointer to a function descriptor */
#ifdef CONFIG_64BIT
if (is_compat_task()) {
......@@ -326,7 +326,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
err = __copy_from_user(&fdesc, ufdesc, sizeof(fdesc));
if (err)
goto give_sigsegv;
return -EFAULT;
haddr = fdesc.addr;
regs->gr[19] = fdesc.gp;
......@@ -339,7 +339,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
err = __copy_from_user(&fdesc, ufdesc, sizeof(fdesc));
if (err)
goto give_sigsegv;
return -EFAULT;
haddr = fdesc.addr;
regs->gr[19] = fdesc.gp;
......@@ -386,7 +386,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
}
regs->gr[2] = rp; /* userland return pointer */
regs->gr[26] = sig; /* signal number */
regs->gr[26] = ksig->sig; /* signal number */
#ifdef CONFIG_64BIT
if (is_compat_task()) {
......@@ -410,11 +410,6 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
current->comm, current->pid, frame, regs->gr[30],
regs->iaoq[0], regs->iaoq[1], rp);
return 1;
give_sigsegv:
DBG(1,"setup_rt_frame: sending SIGSEGV\n");
force_sigsegv(sig, current);
return 0;
}
......@@ -423,20 +418,19 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
*/
static void
handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
struct pt_regs *regs, int in_syscall)
handle_signal(struct ksignal *ksig, struct pt_regs *regs, int in_syscall)
{
int ret;
sigset_t *oldset = sigmask_to_save();
DBG(1,"handle_signal: sig=%ld, ka=%p, info=%p, oldset=%p, regs=%p\n",
sig, ka, info, oldset, regs);
ksig->sig, ksig->ka, ksig->info, oldset, regs);
/* Set up the stack frame */
if (!setup_rt_frame(sig, ka, info, oldset, regs, in_syscall))
return;
ret = setup_rt_frame(ksig, oldset, regs, in_syscall);
signal_delivered(sig, info, ka, regs,
test_thread_flag(TIF_SINGLESTEP) ||
test_thread_flag(TIF_BLOCKSTEP));
signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP) ||
test_thread_flag(TIF_BLOCKSTEP));
DBG(1,KERN_DEBUG "do_signal: Exit (success), regs->gr[28] = %ld\n",
regs->gr[28]);
......@@ -544,22 +538,18 @@ insert_restart_trampoline(struct pt_regs *regs)
asmlinkage void
do_signal(struct pt_regs *regs, long in_syscall)
{
siginfo_t info;
struct k_sigaction ka;
int signr;
struct ksignal ksig;
DBG(1,"\ndo_signal: regs=0x%p, sr7 %#lx, in_syscall=%d\n",
regs, regs->sr[7], in_syscall);
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
DBG(3,"do_signal: signr = %d, regs->gr[28] = %ld\n", signr, regs->gr[28]);
if (signr > 0) {
if (get_signal(&ksig)) {
DBG(3,"do_signal: signr = %d, regs->gr[28] = %ld\n", signr, regs->gr[28]);
/* Restart a system call if necessary. */
if (in_syscall)
syscall_restart(regs, &ka);
syscall_restart(regs, &ksig.ka);
handle_signal(signr, &info, &ka, regs, in_syscall);
handle_signal(&ksig, regs, in_syscall);
return;
}
......
......@@ -31,20 +31,14 @@ int show_unhandled_signals = 1;
/*
* Allocate space for the signal frame
*/
void __user * get_sigframe(struct k_sigaction *ka, unsigned long sp,
void __user *get_sigframe(struct ksignal *ksig, unsigned long sp,
size_t frame_size, int is_32)
{
unsigned long oldsp, newsp;
/* Default to using normal stack */
oldsp = get_clean_sp(sp, is_32);
/* Check for alt stack */
if ((ka->sa.sa_flags & SA_ONSTACK) &&
current->sas_ss_size && !on_sig_stack(oldsp))
oldsp = (current->sas_ss_sp + current->sas_ss_size);
/* Get aligned frame */
oldsp = sigsp(oldsp, ksig);
newsp = (oldsp - frame_size) & ~0xFUL;
/* Check access */
......@@ -105,25 +99,23 @@ static void check_syscall_restart(struct pt_regs *regs, struct k_sigaction *ka,
}
}
static int do_signal(struct pt_regs *regs)
static void do_signal(struct pt_regs *regs)
{
sigset_t *oldset = sigmask_to_save();
siginfo_t info;
int signr;
struct k_sigaction ka;
struct ksignal ksig;
int ret;
int is32 = is_32bit_task();
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
get_signal(&ksig);
/* Is there any syscall restart business here ? */
check_syscall_restart(regs, &ka, signr > 0);
check_syscall_restart(regs, &ksig.ka, ksig.sig > 0);
if (signr <= 0) {
if (ksig.sig <= 0) {
/* No signal to deliver -- put the saved sigmask back */
restore_saved_sigmask();
regs->trap = 0;
return 0; /* no signals delivered */
return; /* no signals delivered */
}
#ifndef CONFIG_PPC_ADV_DEBUG_REGS
......@@ -140,23 +132,16 @@ static int do_signal(struct pt_regs *regs)
thread_change_pc(current, regs);
if (is32) {
if (ka.sa.sa_flags & SA_SIGINFO)
ret = handle_rt_signal32(signr, &ka, &info, oldset,
regs);
if (ksig.ka.sa.sa_flags & SA_SIGINFO)
ret = handle_rt_signal32(&ksig, oldset, regs);
else
ret = handle_signal32(signr, &ka, &info, oldset,
regs);
ret = handle_signal32(&ksig, oldset, regs);
} else {
ret = handle_rt_signal64(signr, &ka, &info, oldset, regs);
ret = handle_rt_signal64(&ksig, oldset, regs);
}
regs->trap = 0;
if (ret) {
signal_delivered(signr, &info, &ka, regs,
test_thread_flag(TIF_SINGLESTEP));
}
return ret;
signal_setup_done(ret, &ksig, test_thread_flag(TIF_SINGLESTEP));
}
void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags)
......
......@@ -12,15 +12,13 @@
extern void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags);
extern void __user * get_sigframe(struct k_sigaction *ka, unsigned long sp,
extern void __user *get_sigframe(struct ksignal *ksig, unsigned long sp,
size_t frame_size, int is_32);
extern int handle_signal32(unsigned long sig, struct k_sigaction *ka,
siginfo_t *info, sigset_t *oldset,
extern int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
struct pt_regs *regs);
extern int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
siginfo_t *info, sigset_t *oldset,
extern int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
struct pt_regs *regs);
extern unsigned long copy_fpr_to_user(void __user *to,
......@@ -44,14 +42,12 @@ extern unsigned long copy_transact_vsx_from_user(struct task_struct *task,
#ifdef CONFIG_PPC64
extern int handle_rt_signal64(int signr, struct k_sigaction *ka,
siginfo_t *info, sigset_t *set,
extern int handle_rt_signal64(struct ksignal *ksig, sigset_t *set,
struct pt_regs *regs);
#else /* CONFIG_PPC64 */
static inline int handle_rt_signal64(int signr, struct k_sigaction *ka,
siginfo_t *info, sigset_t *set,
static inline int handle_rt_signal64(struct ksignal *ksig, sigset_t *set,
struct pt_regs *regs)
{
return -EFAULT;
......
......@@ -981,9 +981,8 @@ int copy_siginfo_from_user32(siginfo_t *to, struct compat_siginfo __user *from)
* Set up a signal frame for a "real-time" signal handler
* (one which gets siginfo).
*/
int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
siginfo_t *info, sigset_t *oldset,
struct pt_regs *regs)
int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
struct pt_regs *regs)
{
struct rt_sigframe __user *rt_sf;
struct mcontext __user *frame;
......@@ -995,13 +994,13 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
/* Set up Signal Frame */
/* Put a Real Time Context onto stack */
rt_sf = get_sigframe(ka, get_tm_stackpointer(regs), sizeof(*rt_sf), 1);
rt_sf = get_sigframe(ksig, get_tm_stackpointer(regs), sizeof(*rt_sf), 1);
addr = rt_sf;
if (unlikely(rt_sf == NULL))
goto badframe;
/* Put the siginfo & fill in most of the ucontext */
if (copy_siginfo_to_user(&rt_sf->info, info)
if (copy_siginfo_to_user(&rt_sf->info, &ksig->info)
|| __put_user(0, &rt_sf->uc.uc_flags)
|| __save_altstack(&rt_sf->uc.uc_stack, regs->gpr[1])
|| __put_user(to_user_ptr(&rt_sf->uc.uc_mcontext),
......@@ -1051,15 +1050,15 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
/* Fill registers for signal handler */
regs->gpr[1] = newsp;
regs->gpr[3] = sig;
regs->gpr[3] = ksig->sig;
regs->gpr[4] = (unsigned long) &rt_sf->info;
regs->gpr[5] = (unsigned long) &rt_sf->uc;
regs->gpr[6] = (unsigned long) rt_sf;
regs->nip = (unsigned long) ka->sa.sa_handler;
regs->nip = (unsigned long) ksig->ka.sa.sa_handler;
/* enter the signal handler in native-endian mode */
regs->msr &= ~MSR_LE;
regs->msr |= (MSR_KERNEL & MSR_LE);
return 1;
return 0;
badframe:
if (show_unhandled_signals)
......@@ -1069,8 +1068,7 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
current->comm, current->pid,
addr, regs->nip, regs->link);
force_sigsegv(sig, current);
return 0;
return 1;
}
static int do_setcontext(struct ucontext __user *ucp, struct pt_regs *regs, int sig)
......@@ -1409,8 +1407,7 @@ int sys_debug_setcontext(struct ucontext __user *ctx,
/*
* OK, we're invoking a handler
*/
int handle_signal32(unsigned long sig, struct k_sigaction *ka,
siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
int handle_signal32(struct ksignal *ksig, sigset_t *oldset, struct pt_regs *regs)
{
struct sigcontext __user *sc;
struct sigframe __user *frame;
......@@ -1420,7 +1417,7 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka,
unsigned long tramp;
/* Set up Signal Frame */
frame = get_sigframe(ka, get_tm_stackpointer(regs), sizeof(*frame), 1);
frame = get_sigframe(ksig, get_tm_stackpointer(regs), sizeof(*frame), 1);
if (unlikely(frame == NULL))
goto badframe;
sc = (struct sigcontext __user *) &frame->sctx;
......@@ -1428,7 +1425,7 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka,
#if _NSIG != 64
#error "Please adjust handle_signal()"
#endif
if (__put_user(to_user_ptr(ka->sa.sa_handler), &sc->handler)
if (__put_user(to_user_ptr(ksig->ka.sa.sa_handler), &sc->handler)
|| __put_user(oldset->sig[0], &sc->oldmask)
#ifdef CONFIG_PPC64
|| __put_user((oldset->sig[0] >> 32), &sc->_unused[3])
......@@ -1436,7 +1433,7 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka,
|| __put_user(oldset->sig[1], &sc->_unused[3])
#endif
|| __put_user(to_user_ptr(&frame->mctx), &sc->regs)
|| __put_user(sig, &sc->signal))
|| __put_user(ksig->sig, &sc->signal))
goto badframe;
if (vdso32_sigtramp && current->mm->context.vdso_base) {
......@@ -1471,12 +1468,12 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka,
goto badframe;
regs->gpr[1] = newsp;
regs->gpr[3] = sig;
regs->gpr[3] = ksig->sig;
regs->gpr[4] = (unsigned long) sc;
regs->nip = (unsigned long) ka->sa.sa_handler;
regs->nip = (unsigned long) (unsigned long)ksig->ka.sa.sa_handler;
/* enter the signal handler in big-endian mode */
regs->msr &= ~MSR_LE;
return 1;
return 0;
badframe:
if (show_unhandled_signals)
......@@ -1486,8 +1483,7 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka,
current->comm, current->pid,
frame, regs->nip, regs->link);
force_sigsegv(sig, current);
return 0;
return 1;
}
/*
......
......@@ -708,20 +708,19 @@ int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
return 0;
}
int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
sigset_t *set, struct pt_regs *regs)
int handle_rt_signal64(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs)
{
struct rt_sigframe __user *frame;
unsigned long newsp = 0;
long err = 0;
frame = get_sigframe(ka, get_tm_stackpointer(regs), sizeof(*frame), 0);
frame = get_sigframe(ksig, get_tm_stackpointer(regs), sizeof(*frame), 0);
if (unlikely(frame == NULL))
goto badframe;
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 badframe;
......@@ -736,15 +735,15 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
err |= __put_user(&frame->uc_transact, &frame->uc.uc_link);
err |= setup_tm_sigcontexts(&frame->uc.uc_mcontext,
&frame->uc_transact.uc_mcontext,
regs, signr,
regs, ksig->sig,
NULL,
(unsigned long)ka->sa.sa_handler);
(unsigned long)ksig->ka.sa.sa_handler);
} else
#endif
{
err |= __put_user(0, &frame->uc.uc_link);
err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, signr,
NULL, (unsigned long)ka->sa.sa_handler,
err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, ksig->sig,
NULL, (unsigned long)ksig->ka.sa.sa_handler,
1);
}
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
......@@ -770,7 +769,7 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
/* Set up "regs" so we "return" to the signal handler. */
if (is_elf2_task()) {
regs->nip = (unsigned long) ka->sa.sa_handler;
regs->nip = (unsigned long) ksig->ka.sa.sa_handler;
regs->gpr[12] = regs->nip;
} else {
/* Handler is *really* a pointer to the function descriptor for
......@@ -779,7 +778,7 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
* entry is the TOC value we need to use.
*/
func_descr_t __user *funct_desc_ptr =
(func_descr_t __user *) ka->sa.sa_handler;
(func_descr_t __user *) ksig->ka.sa.sa_handler;
err |= get_user(regs->nip, &funct_desc_ptr->entry);
err |= get_user(regs->gpr[2], &funct_desc_ptr->toc);
......@@ -789,9 +788,9 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
regs->msr &= ~MSR_LE;
regs->msr |= (MSR_KERNEL & MSR_LE);
regs->gpr[1] = newsp;
regs->gpr[3] = signr;
regs->gpr[3] = ksig->sig;
regs->result = 0;
if (ka->sa.sa_flags & SA_SIGINFO) {
if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
err |= get_user(regs->gpr[4], (unsigned long __user *)&frame->pinfo);
err |= get_user(regs->gpr[5], (unsigned long __user *)&frame->puc);
regs->gpr[6] = (unsigned long) frame;
......@@ -801,7 +800,7 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
if (err)
goto badframe;
return 1;
return 0;
badframe:
if (show_unhandled_signals)
......@@ -809,6 +808,5 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
current->comm, current->pid, "setup_rt_frame",
(long)frame, regs->nip, regs->link);
force_sigsegv(signr, current);
return 0;
return 1;
}
......@@ -320,38 +320,39 @@ static inline int map_signal(int sig)
return sig;
}
static int setup_frame32(int sig, struct k_sigaction *ka,
sigset_t *set, struct pt_regs * regs)
static int setup_frame32(struct ksignal *ksig, sigset_t *set,
struct pt_regs *regs)
{
sigframe32 __user *frame = get_sigframe(ka, regs, sizeof(sigframe32));
int sig = ksig->sig;
sigframe32 __user *frame = get_sigframe(&ksig->ka, regs, sizeof(sigframe32));
if (frame == (void __user *) -1UL)
goto give_sigsegv;
return -EFAULT;
if (__copy_to_user(&frame->sc.oldmask, &set->sig, _SIGMASK_COPY_SIZE32))
goto give_sigsegv;
return -EFAULT;
if (save_sigregs32(regs, &frame->sregs))
goto give_sigsegv;
return -EFAULT;
if (save_sigregs_gprs_high(regs, frame->gprs_high))
goto give_sigsegv;
return -EFAULT;
if (__put_user((unsigned long) &frame->sregs, &frame->sc.sregs))
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) {
regs->gprs[14] = (__u64 __force) ka->sa.sa_restorer | PSW32_ADDR_AMODE;
if (ksig->ka.sa.sa_flags & SA_RESTORER) {
regs->gprs[14] = (__u64 __force) ksig->ka.sa.sa_restorer | PSW32_ADDR_AMODE;
} else {
regs->gprs[14] = (__u64 __force) frame->retcode | PSW32_ADDR_AMODE;
if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn,
(u16 __force __user *)(frame->retcode)))
goto give_sigsegv;
return -EFAULT;
}
/* Set up backchain. */
if (__put_user(regs->gprs[15], (unsigned int __user *) frame))
goto give_sigsegv;
return -EFAULT;
/* Set up registers for signal handler */
regs->gprs[15] = (__force __u64) frame;
......@@ -359,7 +360,7 @@ static int setup_frame32(int sig, struct k_sigaction *ka,
regs->psw.mask = PSW_MASK_BA |
(PSW_USER_BITS & PSW_MASK_ASC) |
(regs->psw.mask & ~PSW_MASK_ASC);
regs->psw.addr = (__force __u64) ka->sa.sa_handler;
regs->psw.addr = (__force __u64) ksig->ka.sa.sa_handler;
regs->gprs[2] = map_signal(sig);
regs->gprs[3] = (__force __u64) &frame->sc;
......@@ -376,25 +377,21 @@ static int setup_frame32(int sig, struct k_sigaction *ka,
/* Place signal number on stack to allow backtrace from handler. */
if (__put_user(regs->gprs[2], (int __force __user *) &frame->signo))
goto give_sigsegv;
return -EFAULT;
return 0;
give_sigsegv:
force_sigsegv(sig, current);
return -EFAULT;
}
static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
sigset_t *set, struct pt_regs * regs)
static int setup_rt_frame32(struct ksignal *ksig, sigset_t *set,
struct pt_regs *regs)
{
int err = 0;
rt_sigframe32 __user *frame = get_sigframe(ka, regs, sizeof(rt_sigframe32));
rt_sigframe32 __user *frame = get_sigframe(&ksig->ka, regs, sizeof(rt_sigframe32));
if (frame == (void __user *) -1UL)
goto give_sigsegv;
return -EFAULT;
if (copy_siginfo_to_user32(&frame->info, info))
goto give_sigsegv;
if (copy_siginfo_to_user32(&frame->info, &ksig->info))
return -EFAULT;
/* Create the ucontext. */
err |= __put_user(UC_EXTENDED, &frame->uc.uc_flags);
......@@ -404,22 +401,22 @@ static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
err |= save_sigregs_gprs_high(regs, frame->gprs_high);
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
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) {
regs->gprs[14] = (__u64 __force) ka->sa.sa_restorer | PSW32_ADDR_AMODE;
if (ksig->ka.sa.sa_flags & SA_RESTORER) {
regs->gprs[14] = (__u64 __force) ksig->ka.sa.sa_restorer | PSW32_ADDR_AMODE;
} else {
regs->gprs[14] = (__u64 __force) frame->retcode | PSW32_ADDR_AMODE;
if (__put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn,
(u16 __force __user *)(frame->retcode)))
goto give_sigsegv;
return -EFAULT;
}
/* Set up backchain. */
if (__put_user(regs->gprs[15], (unsigned int __force __user *) frame))
goto give_sigsegv;
return -EFAULT;
/* Set up registers for signal handler */
regs->gprs[15] = (__force __u64) frame;
......@@ -427,36 +424,30 @@ static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
regs->psw.mask = PSW_MASK_BA |
(PSW_USER_BITS & PSW_MASK_ASC) |
(regs->psw.mask & ~PSW_MASK_ASC);
regs->psw.addr = (__u64 __force) ka->sa.sa_handler;
regs->psw.addr = (__u64 __force) ksig->ka.sa.sa_handler;
regs->gprs[2] = map_signal(sig);
regs->gprs[2] = map_signal(ksig->sig);
regs->gprs[3] = (__force __u64) &frame->info;
regs->gprs[4] = (__force __u64) &frame->uc;
regs->gprs[5] = task_thread_info(current)->last_break;
return 0;
give_sigsegv:
force_sigsegv(sig, current);
return -EFAULT;
}
/*
* OK, we're invoking a handler
*/
void handle_signal32(unsigned long sig, struct k_sigaction *ka,
siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
void handle_signal32(struct ksignal *ksig, sigset_t *oldset,
struct pt_regs *regs)
{
int ret;
/* Set up the stack frame */
if (ka->sa.sa_flags & SA_SIGINFO)
ret = setup_rt_frame32(sig, ka, info, oldset, regs);
if (ksig->ka.sa.sa_flags & SA_SIGINFO)
ret = setup_rt_frame32(ksig, oldset, regs);
else
ret = setup_frame32(sig, ka, oldset, regs);
if (ret)
return;
signal_delivered(sig, info, ka, regs,
test_thread_flag(TIF_SINGLE_STEP));
ret = setup_frame32(ksig, oldset, regs);
signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLE_STEP));
}
......@@ -48,8 +48,8 @@ void do_per_trap(struct pt_regs *regs);
void syscall_trace(struct pt_regs *regs, int entryexit);
void kernel_stack_overflow(struct pt_regs * regs);
void do_signal(struct pt_regs *regs);
void handle_signal32(unsigned long sig, struct k_sigaction *ka,
siginfo_t *info, sigset_t *oldset, struct pt_regs *regs);
void handle_signal32(struct ksignal *ksig, sigset_t *oldset,
struct pt_regs *regs);
void do_notify_resume(struct pt_regs *regs);
void __init init_IRQ(void);
......
......@@ -200,15 +200,15 @@ static int setup_frame(int sig, struct k_sigaction *ka,
frame = get_sigframe(ka, regs, sizeof(sigframe));
if (frame == (void __user *) -1UL)
goto give_sigsegv;
return -EFAULT;
if (__copy_to_user(&frame->sc.oldmask, &set->sig, _SIGMASK_COPY_SIZE))
goto give_sigsegv;
return -EFAULT;
if (save_sigregs(regs, &frame->sregs))
goto give_sigsegv;
return -EFAULT;
if (__put_user(&frame->sregs, &frame->sc.sregs))
goto give_sigsegv;
return -EFAULT;
/* Set up to return from userspace. If provided, use a stub
already in userspace. */
......@@ -220,12 +220,12 @@ static int setup_frame(int sig, struct k_sigaction *ka,
frame->retcode | PSW_ADDR_AMODE;
if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn,
(u16 __user *)(frame->retcode)))
goto give_sigsegv;
return -EFAULT;
}
/* Set up backchain. */
if (__put_user(regs->gprs[15], (addr_t __user *) frame))
goto give_sigsegv;
return -EFAULT;
/* Set up registers for signal handler */
regs->gprs[15] = (unsigned long) frame;
......@@ -250,27 +250,23 @@ static int setup_frame(int sig, struct k_sigaction *ka,
/* Place signal number on stack to allow backtrace from handler. */
if (__put_user(regs->gprs[2], (int __user *) &frame->signo))
goto give_sigsegv;
return -EFAULT;
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)
{
int err = 0;
rt_sigframe __user *frame;
frame = get_sigframe(ka, regs, sizeof(rt_sigframe));
frame = get_sigframe(&ksig->ka, regs, sizeof(rt_sigframe));
if (frame == (void __user *) -1UL)
goto give_sigsegv;
return -EFAULT;
if (copy_siginfo_to_user(&frame->info, info))
goto give_sigsegv;
if (copy_siginfo_to_user(&frame->info, &ksig->info))
return -EFAULT;
/* Create the ucontext. */
err |= __put_user(0, &frame->uc.uc_flags);
......@@ -279,24 +275,24 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
err |= save_sigregs(regs, &frame->uc.uc_mcontext);
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
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) {
if (ksig->ka.sa.sa_flags & SA_RESTORER) {
regs->gprs[14] = (unsigned long)
ka->sa.sa_restorer | PSW_ADDR_AMODE;
ksig->ka.sa.sa_restorer | PSW_ADDR_AMODE;
} else {
regs->gprs[14] = (unsigned long)
frame->retcode | PSW_ADDR_AMODE;
if (__put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn,
(u16 __user *)(frame->retcode)))
goto give_sigsegv;
return -EFAULT;
}
/* Set up backchain. */
if (__put_user(regs->gprs[15], (addr_t __user *) frame))
goto give_sigsegv;
return -EFAULT;
/* Set up registers for signal handler */
regs->gprs[15] = (unsigned long) frame;
......@@ -304,34 +300,27 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA |
(PSW_USER_BITS & PSW_MASK_ASC) |
(regs->psw.mask & ~PSW_MASK_ASC);
regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE;
regs->psw.addr = (unsigned long) ksig->ka.sa.sa_handler | PSW_ADDR_AMODE;
regs->gprs[2] = map_signal(sig);
regs->gprs[2] = map_signal(ksig->sig);
regs->gprs[3] = (unsigned long) &frame->info;
regs->gprs[4] = (unsigned long) &frame->uc;
regs->gprs[5] = task_thread_info(current)->last_break;
return 0;
give_sigsegv:
force_sigsegv(sig, current);
return -EFAULT;
}
static void handle_signal(unsigned long sig, struct k_sigaction *ka,
siginfo_t *info, sigset_t *oldset,
struct pt_regs *regs)
static void handle_signal(struct ksignal *ksig, sigset_t *oldset,
struct pt_regs *regs)
{
int ret;
/* 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);
if (ret)
return;
signal_delivered(sig, info, ka, regs,
test_thread_flag(TIF_SINGLE_STEP));
ret = setup_frame(ksig->sig, &ksig->ka, oldset, regs);
signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLE_STEP));
}
/*
......@@ -345,9 +334,7 @@ static void handle_signal(unsigned long sig, struct k_sigaction *ka,
*/
void do_signal(struct pt_regs *regs)
{
siginfo_t info;
int signr;
struct k_sigaction ka;
struct ksignal ksig;
sigset_t *oldset = sigmask_to_save();
/*
......@@ -357,9 +344,8 @@ void do_signal(struct pt_regs *regs)
*/
current_thread_info()->system_call =
test_pt_regs_flag(regs, PIF_SYSCALL) ? regs->int_code : 0;
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) {
if (get_signal(&ksig)) {
/* Whee! Actually deliver the signal. */
if (current_thread_info()->system_call) {
regs->int_code = current_thread_info()->system_call;
......@@ -370,7 +356,7 @@ void do_signal(struct pt_regs *regs)
regs->gprs[2] = -EINTR;
break;
case -ERESTARTSYS:
if (!(ka.sa.sa_flags & SA_RESTART)) {
if (!(ksig.ka.sa.sa_flags & SA_RESTART)) {
regs->gprs[2] = -EINTR;
break;
}
......@@ -387,9 +373,9 @@ void do_signal(struct pt_regs *regs)
clear_pt_regs_flag(regs, PIF_SYSCALL);
if (is_compat_task())
handle_signal32(signr, &ka, &info, oldset, regs);
handle_signal32(&ksig, oldset, regs);
else
handle_signal(signr, &ka, &info, oldset, regs);
handle_signal(&ksig, oldset, regs);
return;
}
......
......@@ -173,15 +173,15 @@ score_rt_sigreturn(struct pt_regs *regs)
return 0;
}
static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
int signr, sigset_t *set, siginfo_t *info)
static int setup_rt_frame(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;
/*
* Set up the return code ...
......@@ -194,7 +194,7 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
err |= __put_user(0x80008002, frame->rs_code + 1);
flush_cache_sigtramp((unsigned long) frame->rs_code);
err |= copy_siginfo_to_user(&frame->rs_info, info);
err |= copy_siginfo_to_user(&frame->rs_info, &ksig->info);
err |= __put_user(0, &frame->rs_uc.uc_flags);
err |= __put_user(NULL, &frame->rs_uc.uc_link);
err |= __save_altstack(&frame->rs_uc.uc_stack, regs->regs[0]);
......@@ -202,26 +202,23 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set));
if (err)
goto give_sigsegv;
return -EFAULT;
regs->regs[0] = (unsigned long) frame;
regs->regs[3] = (unsigned long) frame->rs_code;
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) ka->sa.sa_handler;
regs->cp0_epc = (unsigned long) ka->sa.sa_handler;
regs->regs[29] = (unsigned long) ksig->ka.sa.sa_handler;
regs->cp0_epc = (unsigned long) ksig->ka.sa.sa_handler;
return 0;
give_sigsegv:
force_sigsegv(signr, current);
return -EFAULT;
}
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)
{
int ret;
if (regs->is_syscall) {
switch (regs->regs[4]) {
case ERESTART_RESTARTBLOCK:
......@@ -229,7 +226,7 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
regs->regs[4] = EINTR;
break;
case ERESTARTSYS:
if (!(ka->sa.sa_flags & SA_RESTART)) {
if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
regs->regs[4] = EINTR;
break;
}
......@@ -245,17 +242,14 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
/*
* Set up the stack frame
*/
if (setup_rt_frame(ka, regs, sig, sigmask_to_save(), info) < 0)
return;
ret = setup_rt_frame(ksig, regs, sigmask_to_save());
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;
/*
* We want the common case to go fast, which is why we may in certain
......@@ -265,10 +259,9 @@ static void do_signal(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)) {
/* Actually deliver the signal. */
handle_signal(signr, &info, &ka, regs);
handle_signal(&ksig, regs);
return;
}
......
......@@ -262,17 +262,17 @@ get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
extern void __kernel_sigreturn(void);
extern void __kernel_rt_sigreturn(void);
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;
int err = 0;
int err = 0, sig = ksig->sig;
int signal;
frame = get_sigframe(ka, regs->regs[15], sizeof(*frame));
frame = get_sigframe(&ksig->ka, regs->regs[15], sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
goto give_sigsegv;
return -EFAULT;
signal = current_thread_info()->exec_domain
&& current_thread_info()->exec_domain->signal_invmap
......@@ -288,8 +288,8 @@ static int setup_frame(int sig, struct k_sigaction *ka,
/* Set up to return from userspace. If provided, use a stub
already in userspace. */
if (ka->sa.sa_flags & SA_RESTORER) {
regs->pr = (unsigned long) ka->sa.sa_restorer;
if (ksig->ka.sa.sa_flags & SA_RESTORER) {
regs->pr = (unsigned long) ksig->ka.sa.sa_restorer;
#ifdef CONFIG_VSYSCALL
} else if (likely(current->mm->context.vdso)) {
regs->pr = VDSO_SYM(&__kernel_sigreturn);
......@@ -309,7 +309,7 @@ static int setup_frame(int sig, struct k_sigaction *ka,
}
if (err)
goto give_sigsegv;
return -EFAULT;
/* Set up registers for signal handler */
regs->regs[15] = (unsigned long) frame;
......@@ -319,15 +319,15 @@ static int setup_frame(int sig, struct k_sigaction *ka,
if (current->personality & FDPIC_FUNCPTRS) {
struct fdpic_func_descriptor __user *funcptr =
(struct fdpic_func_descriptor __user *)ka->sa.sa_handler;
(struct fdpic_func_descriptor __user *)ksig->ka.sa.sa_handler;
err |= __get_user(regs->pc, &funcptr->text);
err |= __get_user(regs->regs[12], &funcptr->GOT);
} else
regs->pc = (unsigned long)ka->sa.sa_handler;
regs->pc = (unsigned long)ksig->ka.sa.sa_handler;
if (err)
goto give_sigsegv;
return -EFAULT;
set_fs(USER_DS);
......@@ -335,23 +335,19 @@ static int setup_frame(int sig, struct k_sigaction *ka,
current->comm, task_pid_nr(current), frame, regs->pc, regs->pr);
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;
int err = 0;
int err = 0, sig = ksig->sig;
int signal;
frame = get_sigframe(ka, regs->regs[15], sizeof(*frame));
frame = get_sigframe(&ksig->ka, regs->regs[15], sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
goto give_sigsegv;
return -EFAULT;
signal = current_thread_info()->exec_domain
&& current_thread_info()->exec_domain->signal_invmap
......@@ -359,7 +355,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
? current_thread_info()->exec_domain->signal_invmap[sig]
: sig;
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);
......@@ -371,8 +367,8 @@ static int 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->sa.sa_flags & SA_RESTORER) {
regs->pr = (unsigned long) ka->sa.sa_restorer;
if (ksig->ka.sa.sa_flags & SA_RESTORER) {
regs->pr = (unsigned long) ksig->ka.sa.sa_restorer;
#ifdef CONFIG_VSYSCALL
} else if (likely(current->mm->context.vdso)) {
regs->pr = VDSO_SYM(&__kernel_rt_sigreturn);
......@@ -392,7 +388,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
}
if (err)
goto give_sigsegv;
return -EFAULT;
/* Set up registers for signal handler */
regs->regs[15] = (unsigned long) frame;
......@@ -402,15 +398,15 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
if (current->personality & FDPIC_FUNCPTRS) {
struct fdpic_func_descriptor __user *funcptr =
(struct fdpic_func_descriptor __user *)ka->sa.sa_handler;
(struct fdpic_func_descriptor __user *)ksig->ka.sa.sa_handler;
err |= __get_user(regs->pc, &funcptr->text);
err |= __get_user(regs->regs[12], &funcptr->GOT);
} else
regs->pc = (unsigned long)ka->sa.sa_handler;
regs->pc = (unsigned long)ksig->ka.sa.sa_handler;
if (err)
goto give_sigsegv;
return -EFAULT;
set_fs(USER_DS);
......@@ -418,10 +414,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
current->comm, task_pid_nr(current), frame, regs->pc, regs->pr);
return 0;
give_sigsegv:
force_sigsegv(sig, current);
return -EFAULT;
}
static inline void
......@@ -455,22 +447,18 @@ handle_syscall_restart(unsigned long save_r0, struct pt_regs *regs,
* OK, we're invoking a handler
*/
static void
handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
struct pt_regs *regs, unsigned int save_r0)
handle_signal(struct ksignal *ksig, struct pt_regs *regs, unsigned int save_r0)
{
sigset_t *oldset = sigmask_to_save();
int ret;
/* 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)
return;
signal_delivered(sig, info, ka, regs,
test_thread_flag(TIF_SINGLESTEP));
signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
}
/*
......@@ -484,9 +472,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
*/
static void do_signal(struct pt_regs *regs, unsigned int save_r0)
{
siginfo_t info;
int signr;
struct k_sigaction ka;
struct ksignal ksig;
/*
* We want the common case to go fast, which
......@@ -497,12 +483,11 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0)
if (!user_mode(regs))
return;
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) {
handle_syscall_restart(save_r0, regs, &ka.sa);
if (get_signal(&ksig)) {
handle_syscall_restart(save_r0, regs, &ksig.ka.sa);
/* Whee! Actually deliver the signal. */
handle_signal(signr, &ka, &info, regs, save_r0);
handle_signal(&ksig, regs, save_r0);
return;
}
......
......@@ -41,8 +41,7 @@
#define DEBUG_SIG 0
static void
handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
struct pt_regs * regs);
handle_signal(struct ksignal *ksig, struct pt_regs *regs);
static inline void
handle_syscall_restart(struct pt_regs *regs, struct sigaction *sa)
......@@ -82,9 +81,7 @@ handle_syscall_restart(struct pt_regs *regs, struct sigaction *sa)
*/
static void do_signal(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
......@@ -95,12 +92,11 @@ static void do_signal(struct pt_regs *regs)
if (!user_mode(regs))
return;
signr = get_signal_to_deliver(&info, &ka, regs, 0);
if (signr > 0) {
handle_syscall_restart(regs, &ka.sa);
if (get_signal(&ksig)) {
handle_syscall_restart(regs, &ksig.ka.sa);
/* Whee! Actually deliver the signal. */
handle_signal(signr, &info, &ka, regs);
handle_signal(&ksig, regs);
return;
}
......@@ -378,17 +374,16 @@ get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
void sa_default_restorer(void); /* See comments below */
void sa_default_rt_restorer(void); /* See comments below */
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;
int err = 0;
int err = 0, sig = ksig->sig;
int signal;
frame = get_sigframe(ka, regs->regs[REG_SP], sizeof(*frame));
frame = get_sigframe(&ksig->ka, regs->regs[REG_SP], sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
goto give_sigsegv;
return -EFAULT;
signal = current_thread_info()->exec_domain
&& current_thread_info()->exec_domain->signal_invmap
......@@ -400,7 +395,7 @@ static int setup_frame(int sig, struct k_sigaction *ka,
/* Give up earlier as i386, in case */
if (err)
goto give_sigsegv;
return -EFAULT;
if (_NSIG_WORDS > 1) {
err |= __copy_to_user(frame->extramask, &set->sig[1],
......@@ -408,16 +403,16 @@ static int setup_frame(int sig, struct k_sigaction *ka,
/* Give up earlier as i386, in case */
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) {
if (ksig->ka.sa.sa_flags & SA_RESTORER) {
/*
* On SH5 all edited pointers are subject to NEFF
*/
DEREF_REG_PR = neff_sign_extend((unsigned long)
ka->sa.sa_restorer | 0x1);
ksig->ka->sa.sa_restorer | 0x1);
} else {
/*
* Different approach on SH5.
......@@ -435,7 +430,7 @@ static int setup_frame(int sig, struct k_sigaction *ka,
if (__copy_to_user(frame->retcode,
(void *)((unsigned long)sa_default_restorer & (~1)), 16) != 0)
goto give_sigsegv;
return -EFAULT;
/* Cohere the trampoline with the I-cache. */
flush_cache_sigtramp(DEREF_REG_PR-1);
......@@ -460,7 +455,7 @@ static int setup_frame(int sig, struct k_sigaction *ka,
regs->regs[REG_ARG2] = (unsigned long long)(unsigned long)(signed long)&frame->sc;
regs->regs[REG_ARG3] = (unsigned long long)(unsigned long)(signed long)&frame->sc;
regs->pc = neff_sign_extend((unsigned long)ka->sa.sa_handler);
regs->pc = neff_sign_extend((unsigned long)ksig->ka.sa.sa_handler);
set_fs(USER_DS);
......@@ -471,23 +466,19 @@ static int setup_frame(int sig, struct k_sigaction *ka,
DEREF_REG_PR >> 32, DEREF_REG_PR & 0xffffffff);
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 *kig, sigset_t *set,
struct pt_regs *regs)
{
struct rt_sigframe __user *frame;
int err = 0;
int err = 0, sig = ksig->sig;
int signal;
frame = get_sigframe(ka, regs->regs[REG_SP], sizeof(*frame));
frame = get_sigframe(&ksig->ka, regs->regs[REG_SP], sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
goto give_sigsegv;
return -EFAULT;
signal = current_thread_info()->exec_domain
&& current_thread_info()->exec_domain->signal_invmap
......@@ -497,11 +488,11 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
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);
/* Give up earlier as i386, in case */
if (err)
goto give_sigsegv;
return -EFAULT;
/* Create the ucontext. */
err |= __put_user(0, &frame->uc.uc_flags);
......@@ -513,16 +504,16 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
/* Give up earlier as i386, in case */
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) {
if (ksig->ka.sa.sa_flags & SA_RESTORER) {
/*
* On SH5 all edited pointers are subject to NEFF
*/
DEREF_REG_PR = neff_sign_extend((unsigned long)
ka->sa.sa_restorer | 0x1);
ksig->ka.sa.sa_restorer | 0x1);
} else {
/*
* Different approach on SH5.
......@@ -540,7 +531,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
if (__copy_to_user(frame->retcode,
(void *)((unsigned long)sa_default_rt_restorer & (~1)), 16) != 0)
goto give_sigsegv;
return -EFAULT;
/* Cohere the trampoline with the I-cache. */
flush_icache_range(DEREF_REG_PR-1, DEREF_REG_PR-1+15);
......@@ -554,7 +545,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
regs->regs[REG_ARG1] = signal; /* Arg for signal handler */
regs->regs[REG_ARG2] = (unsigned long long)(unsigned long)(signed long)&frame->info;
regs->regs[REG_ARG3] = (unsigned long long)(unsigned long)(signed long)&frame->uc.uc_mcontext;
regs->pc = neff_sign_extend((unsigned long)ka->sa.sa_handler);
regs->pc = neff_sign_extend((unsigned long)ksig->ka.sa.sa_handler);
set_fs(USER_DS);
......@@ -564,33 +555,24 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
DEREF_REG_PR >> 32, DEREF_REG_PR & 0xffffffff);
return 0;
give_sigsegv:
force_sigsegv(sig, current);
return -EFAULT;
}
/*
* OK, we're invoking a handler
*/
static void
handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
struct pt_regs * regs)
handle_signal(struct ksignal *ksig, struct pt_regs *regs)
{
sigset_t *oldset = sigmask_to_save();
int ret;
/* 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);
if (ret)
return;
ret = setup_frame(ksig, oldset, regs);
signal_delivered(sig, info, ka, regs,
test_thread_flag(TIF_SINGLESTEP));
signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
}
asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags)
......
......@@ -267,8 +267,7 @@ static inline int is_compat_task(void)
return current_thread_info()->status & TS_COMPAT;
}
extern int compat_setup_rt_frame(int sig, struct k_sigaction *ka,
siginfo_t *info, sigset_t *set,
extern int compat_setup_rt_frame(struct ksignal *ksig, sigset_t *set,
struct pt_regs *regs);
/* Compat syscalls. */
......
......@@ -190,18 +190,18 @@ static inline void __user *compat_get_sigframe(struct k_sigaction *ka,
return (void __user *) sp;
}
int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
sigset_t *set, struct pt_regs *regs)
int compat_setup_rt_frame(struct ksignal *ksig, sigset_t *set,
struct pt_regs *regs)
{
unsigned long restorer;
struct compat_rt_sigframe __user *frame;
int err = 0;
int err = 0, sig = ksig->sig;
int usig;
frame = compat_get_sigframe(ka, regs, sizeof(*frame));
frame = compat_get_sigframe(&ksig->ka, regs, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
goto give_sigsegv;
goto err;
usig = current_thread_info()->exec_domain
&& current_thread_info()->exec_domain->signal_invmap
......@@ -210,12 +210,12 @@ int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
: sig;
/* Always write at least the signal number for the stack backtracer. */
if (ka->sa.sa_flags & SA_SIGINFO) {
if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
/* At sigreturn time, restore the callee-save registers too. */
err |= copy_siginfo_to_user32(&frame->info, info);
err |= copy_siginfo_to_user32(&frame->info, &ksig->info);
regs->flags |= PT_FLAGS_RESTORE_REGS;
} else {
err |= __put_user(info->si_signo, &frame->info.si_signo);
err |= __put_user(ksig->info.si_signo, &frame->info.si_signo);
}
/* Create the ucontext. */
......@@ -226,11 +226,11 @@ int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
err |= setup_sigcontext(&frame->uc.uc_mcontext, regs);
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
if (err)
goto give_sigsegv;
goto err;
restorer = VDSO_SYM(&__vdso_rt_sigreturn);
if (ka->sa.sa_flags & SA_RESTORER)
restorer = ptr_to_compat_reg(ka->sa.sa_restorer);
if (ksig->ka.sa.sa_flags & SA_RESTORER)
restorer = ptr_to_compat_reg(ksig->ka.sa.sa_restorer);
/*
* Set up registers for signal handler.
......@@ -239,7 +239,7 @@ int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
* We always pass siginfo and mcontext, regardless of SA_SIGINFO,
* since some things rely on this (e.g. glibc's debug/segfault.c).
*/
regs->pc = ptr_to_compat_reg(ka->sa.sa_handler);
regs->pc = ptr_to_compat_reg(ksig->ka.sa.sa_handler);
regs->ex1 = PL_ICS_EX1(USER_PL, 1); /* set crit sec in handler */
regs->sp = ptr_to_compat_reg(frame);
regs->lr = restorer;
......@@ -249,7 +249,8 @@ int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
regs->flags |= PT_FLAGS_CALLER_SAVES;
return 0;
give_sigsegv:
signal_fault("bad setup frame", regs, frame, sig);
err:
trace_unhandled_signal("bad sigreturn frame", regs,
(unsigned long)frame, SIGSEGV);
return -EFAULT;
}
......@@ -153,18 +153,18 @@ static inline void __user *get_sigframe(struct k_sigaction *ka,
return (void __user *) sp;
}
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)
{
unsigned long restorer;
struct rt_sigframe __user *frame;
int err = 0;
int err = 0, sig = ksig->sig;
int usig;
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;
goto err;
usig = current_thread_info()->exec_domain
&& current_thread_info()->exec_domain->signal_invmap
......@@ -173,12 +173,12 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
: sig;
/* Always write at least the signal number for the stack backtracer. */
if (ka->sa.sa_flags & SA_SIGINFO) {
if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
/* At sigreturn time, restore the callee-save registers too. */
err |= copy_siginfo_to_user(&frame->info, info);
err |= copy_siginfo_to_user(&frame->info, &ksig->info);
regs->flags |= PT_FLAGS_RESTORE_REGS;
} else {
err |= __put_user(info->si_signo, &frame->info.si_signo);
err |= __put_user(ksig->info.si_signo, &frame->info.si_signo);
}
/* Create the ucontext. */
......@@ -189,11 +189,11 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
err |= setup_sigcontext(&frame->uc.uc_mcontext, regs);
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
if (err)
goto give_sigsegv;
goto err;
restorer = VDSO_SYM(&__vdso_rt_sigreturn);
if (ka->sa.sa_flags & SA_RESTORER)
restorer = (unsigned long) ka->sa.sa_restorer;
if (ksig->ka.sa.sa_flags & SA_RESTORER)
restorer = (unsigned long) ksig->ka.sa.sa_restorer;
/*
* Set up registers for signal handler.
......@@ -202,7 +202,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
* We always pass siginfo and mcontext, regardless of SA_SIGINFO,
* since some things rely on this (e.g. glibc's debug/segfault.c).
*/
regs->pc = (unsigned long) ka->sa.sa_handler;
regs->pc = (unsigned long) ksig->ka.sa.sa_handler;
regs->ex1 = PL_ICS_EX1(USER_PL, 1); /* set crit sec in handler */
regs->sp = (unsigned long) frame;
regs->lr = restorer;
......@@ -212,8 +212,9 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
regs->flags |= PT_FLAGS_CALLER_SAVES;
return 0;
give_sigsegv:
signal_fault("bad setup frame", regs, frame, sig);
err:
trace_unhandled_signal("bad sigreturn frame", regs,
(unsigned long)frame, SIGSEGV);
return -EFAULT;
}
......@@ -221,9 +222,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
* OK, we're invoking a handler
*/
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;
......@@ -238,7 +237,7 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
break;
case -ERESTARTSYS:
if (!(ka->sa.sa_flags & SA_RESTART)) {
if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
regs->regs[0] = -EINTR;
break;
}
......@@ -254,14 +253,12 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
/* Set up the stack frame */
#ifdef CONFIG_COMPAT
if (is_compat_task())
ret = compat_setup_rt_frame(sig, ka, info, oldset, regs);
ret = compat_setup_rt_frame(ksig, oldset, regs);
else
#endif
ret = setup_rt_frame(sig, ka, info, oldset, regs);
if (ret)
return;
signal_delivered(sig, info, ka, regs,
test_thread_flag(TIF_SINGLESTEP));
ret = setup_rt_frame(ksig, oldset, regs);
signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
}
/*
......@@ -271,9 +268,7 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
*/
void do_signal(struct pt_regs *regs)
{
siginfo_t info;
int signr;
struct k_sigaction ka;
struct ksignal ksig;
/*
* i386 will check if we're coming from kernel mode and bail out
......@@ -282,10 +277,9 @@ void do_signal(struct pt_regs *regs)
* helpful, we can reinstate the check on "!user_mode(regs)".
*/
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);
goto done;
}
......
......@@ -6,14 +6,10 @@
#ifndef __FRAME_KERN_H_
#define __FRAME_KERN_H_
extern int setup_signal_stack_sc(unsigned long stack_top, int sig,
struct k_sigaction *ka,
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);
extern int setup_signal_stack_sc(unsigned long stack_top, struct ksignal *ksig,
struct pt_regs *regs, sigset_t *mask);
extern int setup_signal_stack_si(unsigned long stack_top, struct ksignal *ksig,
struct pt_regs *regs, sigset_t *mask);
#endif
......@@ -18,8 +18,7 @@ EXPORT_SYMBOL(unblock_signals);
/*
* OK, we're invoking a handler
*/
static void handle_signal(struct pt_regs *regs, unsigned long signr,
struct k_sigaction *ka, struct siginfo *info)
static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
{
sigset_t *oldset = sigmask_to_save();
int singlestep = 0;
......@@ -39,7 +38,7 @@ static void handle_signal(struct pt_regs *regs, unsigned long signr,
break;
case -ERESTARTSYS:
if (!(ka->sa.sa_flags & SA_RESTART)) {
if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
PT_REGS_SYSCALL_RET(regs) = -EINTR;
break;
}
......@@ -52,32 +51,28 @@ static void handle_signal(struct pt_regs *regs, unsigned long signr,
}
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;
#ifdef CONFIG_ARCH_HAS_SC_SIGNALS
if (!(ka->sa.sa_flags & SA_SIGINFO))
err = setup_signal_stack_sc(sp, signr, ka, regs, oldset);
if (!(ksig->ka.sa.sa_flags & SA_SIGINFO))
err = setup_signal_stack_sc(sp, ksig, regs, oldset);
else
#endif
err = setup_signal_stack_si(sp, signr, ka, regs, info, oldset);
err = setup_signal_stack_si(sp, ksig, regs, oldset);
if (err)
force_sigsegv(signr, current);
else
signal_delivered(signr, info, ka, regs, singlestep);
signal_setup_done(err, ksig, singlestep);
}
static int kern_do_signal(struct pt_regs *regs)
{
struct k_sigaction ka_copy;
struct siginfo info;
int sig, handled_sig = 0;
struct ksignal ksig;
int handled_sig = 0;
while ((sig = get_signal_to_deliver(&info, &ka_copy, regs, NULL)) > 0) {
while (get_signal(&ksig)) {
handled_sig = 1;
/* Whee! Actually deliver the signal. */
handle_signal(regs, sig, &ka_copy, &info);
handle_signal(&ksig, regs);
}
/* Did we come from a system call? */
......
......@@ -238,10 +238,10 @@ static int setup_return(struct pt_regs *regs, struct k_sigaction *ka,
return 0;
}
static int setup_frame(int usig, 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 = get_sigframe(ka, regs, sizeof(*frame));
struct sigframe __user *frame = get_sigframe(&ksig->ka, regs, sizeof(*frame));
int err = 0;
if (!frame)
......@@ -254,29 +254,29 @@ static int setup_frame(int usig, struct k_sigaction *ka,
err |= setup_sigframe(frame, regs, set);
if (err == 0)
err |= setup_return(regs, ka, frame->retcode, frame, usig);
err |= setup_return(regs, &ksig->ka, frame->retcode, frame, usig);
return err;
}
static int setup_rt_frame(int usig, 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 =
get_sigframe(ka, regs, sizeof(*frame));
get_sigframe(&ksig->ka, regs, sizeof(*frame));
int err = 0;
if (!frame)
return 1;
err |= copy_siginfo_to_user(&frame->info, info);
err |= copy_siginfo_to_user(&frame->info, &ksig->info);
err |= __put_user(0, &frame->sig.uc.uc_flags);
err |= __put_user(NULL, &frame->sig.uc.uc_link);
err |= __save_altstack(&frame->sig.uc.uc_stack, regs->UCreg_sp);
err |= setup_sigframe(&frame->sig, regs, set);
if (err == 0)
err |= setup_return(regs, ka, frame->sig.retcode, frame, usig);
err |= setup_return(regs, &ksig->ka, frame->sig.retcode, frame, usig);
if (err == 0) {
/*
......@@ -299,13 +299,13 @@ static inline void setup_syscall_restart(struct pt_regs *regs)
/*
* OK, we're invoking a handler
*/
static void handle_signal(unsigned long sig, struct k_sigaction *ka,
siginfo_t *info, struct pt_regs *regs, int syscall)
static void handle_signal(struct ksignal *ksig, struct pt_regs *regs,
int syscall)
{
struct thread_info *thread = current_thread_info();
struct task_struct *tsk = current;
sigset_t *oldset = sigmask_to_save();
int usig = sig;
int usig = ksig->sig;
int ret;
/*
......@@ -318,7 +318,7 @@ static void handle_signal(unsigned long sig, struct k_sigaction *ka,
regs->UCreg_00 = -EINTR;
break;
case -ERESTARTSYS:
if (!(ka->sa.sa_flags & SA_RESTART)) {
if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
regs->UCreg_00 = -EINTR;
break;
}
......@@ -338,22 +338,17 @@ static void handle_signal(unsigned long sig, struct k_sigaction *ka,
/*
* Set up the stack frame
*/
if (ka->sa.sa_flags & SA_SIGINFO)
ret = setup_rt_frame(usig, ka, info, oldset, regs);
if (ksig->ka.sa.sa_flags & SA_SIGINFO)
ret = setup_rt_frame(ksig, oldset, regs);
else
ret = setup_frame(usig, ka, oldset, regs);
ret = setup_frame(ksig, oldset, regs);
/*
* Check that the resulting registers are actually sane.
*/
ret |= !valid_user_regs(regs);
if (ret != 0) {
force_sigsegv(sig, tsk);
return;
}
signal_delivered(sig, info, ka, regs, 0);
signal_setup_done(ret, ksig, 0);
}
/*
......@@ -367,9 +362,7 @@ static void handle_signal(unsigned long sig, struct k_sigaction *ka,
*/
static void do_signal(struct pt_regs *regs, int syscall)
{
struct k_sigaction ka;
siginfo_t info;
int signr;
struct ksignal ksig;
/*
* We want the common case to go fast, which
......@@ -380,9 +373,8 @@ static void do_signal(struct pt_regs *regs, int syscall)
if (!user_mode(regs))
return;
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) {
handle_signal(signr, &ka, &info, regs, syscall);
if (get_signsl(&ksig)) {
handle_signal(&ksig, regs, syscall);
return;
}
......
......@@ -370,13 +370,12 @@ struct rt_sigframe
char retcode[8];
};
int setup_signal_stack_sc(unsigned long stack_top, int sig,
struct k_sigaction *ka, struct pt_regs *regs,
sigset_t *mask)
int setup_signal_stack_sc(unsigned long stack_top, struct ksignal *ksig,
struct pt_regs *regs, sigset_t *mask)
{
struct sigframe __user *frame;
void __user *restorer;
int err = 0;
int err = 0, sig = ksig->sig;
/* This is the same calculation as i386 - ((sp + 4) & 15) == 0 */
stack_top = ((stack_top + 4) & -16UL) - 4;
......@@ -385,8 +384,8 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig,
return 1;
restorer = frame->retcode;
if (ka->sa.sa_flags & SA_RESTORER)
restorer = ka->sa.sa_restorer;
if (ksig->ka.sa.sa_flags & SA_RESTORER)
restorer = ksig->ka.sa.sa_restorer;
err |= __put_user(restorer, &frame->pretcode);
err |= __put_user(sig, &frame->sig);
......@@ -410,20 +409,19 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig,
return err;
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_DX(regs) = (unsigned long) 0;
PT_REGS_CX(regs) = (unsigned long) 0;
return 0;
}
int setup_signal_stack_si(unsigned long stack_top, int sig,
struct k_sigaction *ka, struct pt_regs *regs,
siginfo_t *info, sigset_t *mask)
int setup_signal_stack_si(unsigned long stack_top, struct ksignal *ksig,
struct pt_regs *regs, sigset_t *mask)
{
struct rt_sigframe __user *frame;
void __user *restorer;
int err = 0;
int err = 0, sig = ksig->sig;
stack_top &= -8UL;
frame = (struct rt_sigframe __user *) stack_top - 1;
......@@ -431,14 +429,14 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
return 1;
restorer = frame->retcode;
if (ka->sa.sa_flags & SA_RESTORER)
restorer = ka->sa.sa_restorer;
if (ksig->ka.sa.sa_flags & SA_RESTORER)
restorer = ksig->ka.sa.sa_restorer;
err |= __put_user(restorer, &frame->pretcode);
err |= __put_user(sig, &frame->sig);
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);
err |= copy_ucontext_to_user(&frame->uc, &frame->fpstate, mask,
PT_REGS_SP(regs));
......@@ -457,7 +455,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
return err;
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_DX(regs) = (unsigned long) &frame->info;
PT_REGS_CX(regs) = (unsigned long) &frame->uc;
......@@ -502,12 +500,11 @@ struct rt_sigframe
struct _fpstate fpstate;
};
int setup_signal_stack_si(unsigned long stack_top, int sig,
struct k_sigaction *ka, struct pt_regs * regs,
siginfo_t *info, sigset_t *set)
int setup_signal_stack_si(unsigned long stack_top, struct ksignal *ksig,
struct pt_regs *regs, sigset_t *set)
{
struct rt_sigframe __user *frame;
int err = 0;
int err = 0, sig = ksig->sig;
frame = (struct rt_sigframe __user *)
round_down(stack_top - sizeof(struct rt_sigframe), 16);
......@@ -517,8 +514,8 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
goto out;
if (ka->sa.sa_flags & SA_SIGINFO) {
err |= copy_siginfo_to_user(&frame->info, info);
if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
err |= copy_siginfo_to_user(&frame->info, &ksig->info);
if (err)
goto out;
}
......@@ -543,8 +540,8 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
* already in userspace.
*/
/* x86-64 should always use SA_RESTORER. */
if (ka->sa.sa_flags & SA_RESTORER)
err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
if (ksig->ka.sa.sa_flags & SA_RESTORER)
err |= __put_user(ksig->ka.sa.sa_restorer, &frame->pretcode);
else
/* could use a vstub here */
return err;
......@@ -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_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:
return err;
}
......
......@@ -331,17 +331,17 @@ gen_return_code(unsigned char *codemem)
}
static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
sigset_t *set, struct pt_regs *regs)
static int setup_frame(struct ksignal *ksig, sigset_t *set,
struct pt_regs *regs)
{
struct rt_sigframe *frame;
int err = 0;
int err = 0, sig = ksig->sig;
int signal;
unsigned long sp, ra, tp;
sp = regs->areg[1];
if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && sas_ss_flags(sp) == 0) {
if ((ksig->ka.sa.sa_flags & SA_ONSTACK) != 0 && sas_ss_flags(sp) == 0) {
sp = current->sas_ss_sp + current->sas_ss_size;
}
......@@ -351,7 +351,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
panic ("Double exception sys_sigreturn\n");
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) {
goto give_sigsegv;
return -EFAULT;
}
signal = current_thread_info()->exec_domain
......@@ -360,8 +360,8 @@ static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
? current_thread_info()->exec_domain->signal_invmap[sig]
: sig;
if (ka->sa.sa_flags & SA_SIGINFO) {
err |= copy_siginfo_to_user(&frame->info, info);
if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
err |= copy_siginfo_to_user(&frame->info, &ksig->info);
}
/* Create the user context. */
......@@ -372,8 +372,8 @@ static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
err |= setup_sigcontext(frame, regs);
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
if (ka->sa.sa_flags & SA_RESTORER) {
ra = (unsigned long)ka->sa.sa_restorer;
if (ksig->ka.sa.sa_flags & SA_RESTORER) {
ra = (unsigned long)ksig->ka.sa.sa_restorer;
} else {
/* Create sys_rt_sigreturn syscall in stack frame */
......@@ -381,7 +381,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
err |= gen_return_code(frame->retcode);
if (err) {
goto give_sigsegv;
return -EFAULT;
}
ra = (unsigned long) frame->retcode;
}
......@@ -393,7 +393,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
/* Set up registers for signal handler; preserve the threadptr */
tp = regs->threadptr;
start_thread(regs, (unsigned long) ka->sa.sa_handler,
start_thread(regs, (unsigned long) ksig->ka.sa.sa_handler,
(unsigned long) frame);
/* Set up a stack frame for a call4
......@@ -416,10 +416,6 @@ static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
#endif
return 0;
give_sigsegv:
force_sigsegv(sig, current);
return -EFAULT;
}
/*
......@@ -433,15 +429,11 @@ static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
*/
static void do_signal(struct pt_regs *regs)
{
siginfo_t info;
int signr;
struct k_sigaction ka;
struct ksignal ksig;
task_pt_regs(current)->icountlevel = 0;
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) {
if (get_signal(&ksig)) {
int ret;
/* Are we from a system call? */
......@@ -457,7 +449,7 @@ static void do_signal(struct pt_regs *regs)
break;
case -ERESTARTSYS:
if (!(ka.sa.sa_flags & SA_RESTART)) {
if (!(ksig.ka.sa.sa_flags & SA_RESTART)) {
regs->areg[2] = -EINTR;
break;
}
......@@ -476,11 +468,8 @@ static void do_signal(struct pt_regs *regs)
/* Whee! Actually deliver the signal. */
/* Set up the stack frame */
ret = setup_frame(signr, &ka, &info, sigmask_to_save(), regs);
if (ret)
return;
signal_delivered(signr, &info, &ka, regs, 0);
ret = setup_frame(&ksig, sigmask_to_save(), regs);
signal_setup_done(ret, &ksig, 0);
if (current->ptrace & PT_SINGLESTEP)
task_pt_regs(current)->icountlevel = 1;
......
......@@ -2360,8 +2360,10 @@ static inline int on_sig_stack(unsigned long sp)
static inline int sas_ss_flags(unsigned long sp)
{
return (current->sas_ss_size == 0 ? SS_DISABLE
: on_sig_stack(sp) ? SS_ONSTACK : 0);
if (!current->sas_ss_size)
return SS_DISABLE;
return on_sig_stack(sp) ? SS_ONSTACK : 0;
}
static inline unsigned long sigsp(unsigned long sp, struct ksignal *ksig)
......
......@@ -280,9 +280,8 @@ struct ksignal {
int sig;
};
extern int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, struct pt_regs *regs, void *cookie);
extern int get_signal(struct ksignal *ksig);
extern void signal_setup_done(int failed, struct ksignal *ksig, int stepping);
extern void signal_delivered(int sig, siginfo_t *info, struct k_sigaction *ka, struct pt_regs *regs, int stepping);
extern void exit_signals(struct task_struct *tsk);
extern void kernel_sigaction(int, __sighandler_t);
......@@ -301,18 +300,6 @@ static inline void disallow_signal(int sig)
kernel_sigaction(sig, SIG_IGN);
}
/*
* Eventually that'll replace get_signal_to_deliver(); macro for now,
* to avoid nastiness with include order.
*/
#define get_signal(ksig) \
({ \
struct ksignal *p = (ksig); \
p->sig = get_signal_to_deliver(&p->info, &p->ka, \
signal_pt_regs(), NULL);\
p->sig > 0; \
})
extern struct kmem_cache *sighand_cachep;
int unhandled_signal(struct task_struct *tsk, int sig);
......
......@@ -133,10 +133,6 @@ static inline void tracehook_report_syscall_exit(struct pt_regs *regs, int step)
/**
* tracehook_signal_handler - signal handler setup is complete
* @sig: number of signal being delivered
* @info: siginfo_t of signal being delivered
* @ka: sigaction setting that chose the handler
* @regs: user register state
* @stepping: nonzero if debugger single-step or block-step in use
*
* Called by the arch code after a signal handler has been set up.
......@@ -146,9 +142,7 @@ static inline void tracehook_report_syscall_exit(struct pt_regs *regs, int step)
* Called without locks, shortly before returning to user mode
* (or handling more signals).
*/
static inline void tracehook_signal_handler(int sig, siginfo_t *info,
const struct k_sigaction *ka,
struct pt_regs *regs, int stepping)
static inline void tracehook_signal_handler(int stepping)
{
if (stepping)
ptrace_notify(SIGTRAP);
......
......@@ -2170,8 +2170,7 @@ static int ptrace_signal(int signr, siginfo_t *info)
return signr;
}
int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka,
struct pt_regs *regs, void *cookie)
int get_signal(struct ksignal *ksig)
{
struct sighand_struct *sighand = current->sighand;
struct signal_struct *signal = current->signal;
......@@ -2241,13 +2240,13 @@ int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka,
goto relock;
}
signr = dequeue_signal(current, &current->blocked, info);
signr = dequeue_signal(current, &current->blocked, &ksig->info);
if (!signr)
break; /* will return 0 */
if (unlikely(current->ptrace) && signr != SIGKILL) {
signr = ptrace_signal(signr, info);
signr = ptrace_signal(signr, &ksig->info);
if (!signr)
continue;
}
......@@ -2255,13 +2254,13 @@ int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka,
ka = &sighand->action[signr-1];
/* Trace actually delivered signals. */
trace_signal_deliver(signr, info, ka);
trace_signal_deliver(signr, &ksig->info, ka);
if (ka->sa.sa_handler == SIG_IGN) /* Do nothing. */
continue;
if (ka->sa.sa_handler != SIG_DFL) {
/* Run the handler. */
*return_ka = *ka;
ksig->ka = *ka;
if (ka->sa.sa_flags & SA_ONESHOT)
ka->sa.sa_handler = SIG_DFL;
......@@ -2311,7 +2310,7 @@ int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka,
spin_lock_irq(&sighand->siglock);
}
if (likely(do_signal_stop(info->si_signo))) {
if (likely(do_signal_stop(ksig->info.si_signo))) {
/* It released the siglock. */
goto relock;
}
......@@ -2332,7 +2331,7 @@ int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka,
if (sig_kernel_coredump(signr)) {
if (print_fatal_signals)
print_fatal_signal(info->si_signo);
print_fatal_signal(ksig->info.si_signo);
proc_coredump_connector(current);
/*
* If it was able to dump core, this kills all
......@@ -2342,34 +2341,32 @@ int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka,
* first and our do_group_exit call below will use
* that value and ignore the one we pass it.
*/
do_coredump(info);
do_coredump(&ksig->info);
}
/*
* Death signals, no core dump.
*/
do_group_exit(info->si_signo);
do_group_exit(ksig->info.si_signo);
/* NOTREACHED */
}
spin_unlock_irq(&sighand->siglock);
return signr;
ksig->sig = signr;
return ksig->sig > 0;
}
/**
* signal_delivered -
* @sig: number of signal being delivered
* @info: siginfo_t of signal being delivered
* @ka: sigaction setting that chose the handler
* @regs: user register state
* @ksig: kernel signal struct
* @stepping: nonzero if debugger single-step or block-step in use
*
* This function should be called when a signal has successfully been
* delivered. It updates the blocked signals accordingly (@ka->sa.sa_mask
* delivered. It updates the blocked signals accordingly (@ksig->ka.sa.sa_mask
* is always blocked, and the signal itself is blocked unless %SA_NODEFER
* is set in @ka->sa.sa_flags. Tracing is notified.
* is set in @ksig->ka.sa.sa_flags. Tracing is notified.
*/
void signal_delivered(int sig, siginfo_t *info, struct k_sigaction *ka,
struct pt_regs *regs, int stepping)
static void signal_delivered(struct ksignal *ksig, int stepping)
{
sigset_t blocked;
......@@ -2379,11 +2376,11 @@ void signal_delivered(int sig, siginfo_t *info, struct k_sigaction *ka,
simply clear the restore sigmask flag. */
clear_restore_sigmask();
sigorsets(&blocked, &current->blocked, &ka->sa.sa_mask);
if (!(ka->sa.sa_flags & SA_NODEFER))
sigaddset(&blocked, sig);
sigorsets(&blocked, &current->blocked, &ksig->ka.sa.sa_mask);
if (!(ksig->ka.sa.sa_flags & SA_NODEFER))
sigaddset(&blocked, ksig->sig);
set_current_blocked(&blocked);
tracehook_signal_handler(sig, info, ka, regs, stepping);
tracehook_signal_handler(stepping);
}
void signal_setup_done(int failed, struct ksignal *ksig, int stepping)
......@@ -2391,8 +2388,7 @@ void signal_setup_done(int failed, struct ksignal *ksig, int stepping)
if (failed)
force_sigsegv(ksig->sig, current);
else
signal_delivered(ksig->sig, &ksig->info, &ksig->ka,
signal_pt_regs(), stepping);
signal_delivered(ksig, stepping);
}
/*
......
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