aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/signal.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2007-06-04 03:22:48 -0400
committerPaul Mackerras <paulus@samba.org>2007-06-14 08:29:58 -0400
commita3f61dc0a5335334958ec3b97d0b1946b4ae5375 (patch)
treee7b151d724dca73220d8346c2a0c2a3525c5c91c /arch/powerpc/kernel/signal.c
parent5f9f375a62d3fd3d7f0d5adc23039ade523e62ba (diff)
[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>
Diffstat (limited to 'arch/powerpc/kernel/signal.c')
-rw-r--r--arch/powerpc/kernel/signal.c39
1 files changed, 29 insertions, 10 deletions
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index a9c148a09361..dee275014e00 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -11,6 +11,7 @@
11 11
12#include <linux/ptrace.h> 12#include <linux/ptrace.h>
13#include <linux/signal.h> 13#include <linux/signal.h>
14#include <asm/uaccess.h>
14#include <asm/unistd.h> 15#include <asm/unistd.h>
15 16
16#include "signal.h" 17#include "signal.h"
@@ -28,6 +29,32 @@ static inline int is_32bit_task(void)
28} 29}
29#endif 30#endif
30 31
32/*
33 * Allocate space for the signal frame
34 */
35void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
36 size_t frame_size)
37{
38 unsigned long oldsp, newsp;
39
40 /* Default to using normal stack */
41 oldsp = regs->gpr[1];
42
43 /* Check for alt stack */
44 if ((ka->sa.sa_flags & SA_ONSTACK) &&
45 current->sas_ss_size && !on_sig_stack(oldsp))
46 oldsp = (current->sas_ss_sp + current->sas_ss_size);
47
48 /* Get aligned frame */
49 newsp = (oldsp - frame_size) & ~0xFUL;
50
51 /* Check access */
52 if (!access_ok(VERIFY_WRITE, (void __user *)newsp, oldsp - newsp))
53 return NULL;
54
55 return (void __user *)newsp;
56}
57
31 58
32/* 59/*
33 * Restore the user process's signal mask 60 * Restore the user process's signal mask
@@ -130,20 +157,12 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
130#endif 157#endif
131 158
132 if (is32) { 159 if (is32) {
133 unsigned int newsp;
134
135 if ((ka.sa.sa_flags & SA_ONSTACK) &&
136 current->sas_ss_size && !on_sig_stack(regs->gpr[1]))
137 newsp = current->sas_ss_sp + current->sas_ss_size;
138 else
139 newsp = regs->gpr[1];
140
141 if (ka.sa.sa_flags & SA_SIGINFO) 160 if (ka.sa.sa_flags & SA_SIGINFO)
142 ret = handle_rt_signal32(signr, &ka, &info, oldset, 161 ret = handle_rt_signal32(signr, &ka, &info, oldset,
143 regs, newsp); 162 regs);
144 else 163 else
145 ret = handle_signal32(signr, &ka, &info, oldset, 164 ret = handle_signal32(signr, &ka, &info, oldset,
146 regs, newsp); 165 regs);
147#ifdef CONFIG_PPC64 166#ifdef CONFIG_PPC64
148 } else { 167 } else {
149 ret = handle_rt_signal64(signr, &ka, &info, oldset, regs); 168 ret = handle_rt_signal64(signr, &ka, &info, oldset, regs);