aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/signal_64.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2007-06-04 01:15:52 -0400
committerPaul Mackerras <paulus@samba.org>2007-06-14 08:29:58 -0400
commitf478f5430c8a599f46c41e8172a507a5772a6b69 (patch)
treece42723ed517a82a5e73b45cfe52a3bd338c1a4d /arch/powerpc/kernel/signal_64.c
parentdb277e9a67b9d81b9d6cd74edf0c3e1a0ef2aa4b (diff)
[POWERPC] Consolidate do_signal
do_signal has exactly the same behaviour on 32bit and 64bit and 32bit compat on 64bit for handling 32bit signals. Consolidate all these into one common function in signal.c. The only odd left over is the try_to_free in the 32bit version that no other architecture has in mainline (only in i386 for some odd SuSE release). We should probably get rid of it in a separate patch. Signed-off-by: Christoph Hellwig <hch@lst.de> 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.c86
1 files changed, 1 insertions, 85 deletions
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index 7e9c4b7e7e82..c17903cd384a 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -334,7 +334,7 @@ badframe:
334 return 0; 334 return 0;
335} 335}
336 336
337static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info, 337int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
338 sigset_t *set, struct pt_regs *regs) 338 sigset_t *set, struct pt_regs *regs)
339{ 339{
340 /* Handler is *really* a pointer to the function descriptor for 340 /* Handler is *really* a pointer to the function descriptor for
@@ -417,87 +417,3 @@ badframe:
417 force_sigsegv(signr, current); 417 force_sigsegv(signr, current);
418 return 0; 418 return 0;
419} 419}
420
421
422/*
423 * OK, we're invoking a handler
424 */
425static int handle_signal(unsigned long sig, struct k_sigaction *ka,
426 siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
427{
428 int ret;
429
430 /* Set up Signal Frame */
431 ret = setup_rt_frame(sig, ka, info, oldset, regs);
432
433 if (ret) {
434 spin_lock_irq(&current->sighand->siglock);
435 sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
436 if (!(ka->sa.sa_flags & SA_NODEFER))
437 sigaddset(&current->blocked,sig);
438 recalc_sigpending();
439 spin_unlock_irq(&current->sighand->siglock);
440 }
441
442 return ret;
443}
444
445/*
446 * Note that 'init' is a special process: it doesn't get signals it doesn't
447 * want to handle. Thus you cannot kill init even with a SIGKILL even by
448 * mistake.
449 */
450int do_signal(sigset_t *oldset, struct pt_regs *regs)
451{
452 siginfo_t info;
453 int signr;
454 struct k_sigaction ka;
455
456 /*
457 * If the current thread is 32 bit - invoke the
458 * 32 bit signal handling code
459 */
460 if (test_thread_flag(TIF_32BIT))
461 return do_signal32(oldset, regs);
462
463 if (test_thread_flag(TIF_RESTORE_SIGMASK))
464 oldset = &current->saved_sigmask;
465 else if (!oldset)
466 oldset = &current->blocked;
467
468 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
469
470 /* Is there any syscall restart business here ? */
471 check_syscall_restart(regs, &ka, signr > 0);
472
473 if (signr > 0) {
474 int ret;
475
476 /*
477 * Reenable the DABR before delivering the signal to
478 * user space. The DABR will have been cleared if it
479 * triggered inside the kernel.
480 */
481 if (current->thread.dabr)
482 set_dabr(current->thread.dabr);
483
484 /* Whee! Actually deliver the signal. */
485 ret = handle_signal(signr, &ka, &info, oldset, regs);
486
487 /* If a signal was successfully delivered, the saved sigmask is in
488 its frame, and we can clear the TIF_RESTORE_SIGMASK flag */
489 if (ret && test_thread_flag(TIF_RESTORE_SIGMASK))
490 clear_thread_flag(TIF_RESTORE_SIGMASK);
491
492 return ret;
493 }
494
495 /* No signal to deliver -- put the saved sigmask back */
496 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
497 clear_thread_flag(TIF_RESTORE_SIGMASK);
498 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
499 }
500
501 return 0;
502}
503EXPORT_SYMBOL(do_signal);