[POWERPC] Merge creation of signal frame
The code for creating signal frames was still duplicated and split
in strange ways between 32 and 64 bits, including the SA_ONSTACK
handling being in do_signal on 32 bits but inside handle_rt_signal
on 64 bits etc...
This moves the 64 bits get_sigframe() to the generic signal.c,
cleans it a bit, moves the access_ok() call done by all callers to
it as well, and adapts/cleanups the 3 different signal handling cases
to use that common function.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index a9c148a..dee2750 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -11,6 +11,7 @@
#include <linux/ptrace.h>
#include <linux/signal.h>
+#include <asm/uaccess.h>
#include <asm/unistd.h>
#include "signal.h"
@@ -28,6 +29,32 @@
}
#endif
+/*
+ * Allocate space for the signal frame
+ */
+void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
+ size_t frame_size)
+{
+ unsigned long oldsp, newsp;
+
+ /* Default to using normal stack */
+ oldsp = regs->gpr[1];
+
+ /* 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 */
+ newsp = (oldsp - frame_size) & ~0xFUL;
+
+ /* Check access */
+ if (!access_ok(VERIFY_WRITE, (void __user *)newsp, oldsp - newsp))
+ return NULL;
+
+ return (void __user *)newsp;
+}
+
/*
* Restore the user process's signal mask
@@ -130,20 +157,12 @@
#endif
if (is32) {
- unsigned int newsp;
-
- if ((ka.sa.sa_flags & SA_ONSTACK) &&
- current->sas_ss_size && !on_sig_stack(regs->gpr[1]))
- newsp = current->sas_ss_sp + current->sas_ss_size;
- else
- newsp = regs->gpr[1];
-
if (ka.sa.sa_flags & SA_SIGINFO)
ret = handle_rt_signal32(signr, &ka, &info, oldset,
- regs, newsp);
+ regs);
else
ret = handle_signal32(signr, &ka, &info, oldset,
- regs, newsp);
+ regs);
#ifdef CONFIG_PPC64
} else {
ret = handle_rt_signal64(signr, &ka, &info, oldset, regs);