diff options
Diffstat (limited to 'arch/powerpc/kernel/signal_64.c')
-rw-r--r-- | arch/powerpc/kernel/signal_64.c | 86 |
1 files changed, 1 insertions, 85 deletions
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index 7e9c4b7e7e8..c17903cd384 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 | ||
337 | static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info, | 337 | int 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 | */ | ||
425 | static 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(¤t->sighand->siglock); | ||
435 | sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); | ||
436 | if (!(ka->sa.sa_flags & SA_NODEFER)) | ||
437 | sigaddset(¤t->blocked,sig); | ||
438 | recalc_sigpending(); | ||
439 | spin_unlock_irq(¤t->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 | */ | ||
450 | int 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 = ¤t->saved_sigmask; | ||
465 | else if (!oldset) | ||
466 | oldset = ¤t->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, ¤t->saved_sigmask, NULL); | ||
499 | } | ||
500 | |||
501 | return 0; | ||
502 | } | ||
503 | EXPORT_SYMBOL(do_signal); | ||