aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/signal_64.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_64.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_64.c')
-rw-r--r--arch/powerpc/kernel/signal_64.c24
1 files changed, 2 insertions, 22 deletions
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index c17903cd384a..5004a979ebc0 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -196,25 +196,6 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig,
196} 196}
197 197
198/* 198/*
199 * Allocate space for the signal frame
200 */
201static inline void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
202 size_t frame_size)
203{
204 unsigned long newsp;
205
206 /* Default to using normal stack */
207 newsp = regs->gpr[1];
208
209 if ((ka->sa.sa_flags & SA_ONSTACK) && current->sas_ss_size) {
210 if (! on_sig_stack(regs->gpr[1]))
211 newsp = (current->sas_ss_sp + current->sas_ss_size);
212 }
213
214 return (void __user *)((newsp - frame_size) & -16ul);
215}
216
217/*
218 * Setup the trampoline code on the stack 199 * Setup the trampoline code on the stack
219 */ 200 */
220static long setup_trampoline(unsigned int syscall, unsigned int __user *tramp) 201static long setup_trampoline(unsigned int syscall, unsigned int __user *tramp)
@@ -348,8 +329,7 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
348 long err = 0; 329 long err = 0;
349 330
350 frame = get_sigframe(ka, regs, sizeof(*frame)); 331 frame = get_sigframe(ka, regs, sizeof(*frame));
351 332 if (unlikely(frame == NULL))
352 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
353 goto badframe; 333 goto badframe;
354 334
355 err |= __put_user(&frame->info, &frame->pinfo); 335 err |= __put_user(&frame->info, &frame->pinfo);
@@ -386,7 +366,7 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
386 funct_desc_ptr = (func_descr_t __user *) ka->sa.sa_handler; 366 funct_desc_ptr = (func_descr_t __user *) ka->sa.sa_handler;
387 367
388 /* Allocate a dummy caller frame for the signal handler. */ 368 /* Allocate a dummy caller frame for the signal handler. */
389 newsp = (unsigned long)frame - __SIGNAL_FRAMESIZE; 369 newsp = ((unsigned long)frame) - __SIGNAL_FRAMESIZE;
390 err |= put_user(regs->gpr[1], (unsigned long __user *)newsp); 370 err |= put_user(regs->gpr[1], (unsigned long __user *)newsp);
391 371
392 /* Set up "regs" so we "return" to the signal handler. */ 372 /* Set up "regs" so we "return" to the signal handler. */