diff options
Diffstat (limited to 'arch/powerpc/kernel/signal_64.c')
-rw-r--r-- | arch/powerpc/kernel/signal_64.c | 59 |
1 files changed, 7 insertions, 52 deletions
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index 1ce0ae3f6ff..5d2faf0fbf0 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -34,6 +34,8 @@ #include <asm/syscalls.h> #include <asm/vdso.h> +#include "signal.h" + #define DEBUG_SIG 0 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) @@ -463,41 +465,6 @@ static int handle_signal(unsigned long sig, struct k_sigaction *ka, return ret; } -static inline void syscall_restart(struct pt_regs *regs, struct k_sigaction *ka) -{ - switch ((int)regs->result) { - case -ERESTART_RESTARTBLOCK: - case -ERESTARTNOHAND: - /* ERESTARTNOHAND means that the syscall should only be - * restarted if there was no handler for the signal, and since - * we only get here if there is a handler, we dont restart. - */ - regs->result = -EINTR; - regs->gpr[3] = EINTR; - regs->ccr |= 0x10000000; - break; - case -ERESTARTSYS: - /* ERESTARTSYS means to restart the syscall if there is no - * handler or the handler was registered with SA_RESTART - */ - if (!(ka->sa.sa_flags & SA_RESTART)) { - regs->result = -EINTR; - regs->gpr[3] = EINTR; - regs->ccr |= 0x10000000; - break; - } - /* fallthrough */ - case -ERESTARTNOINTR: - /* ERESTARTNOINTR means that the syscall should be - * called again after the signal handler returns. - */ - regs->gpr[3] = regs->orig_gpr3; - regs->nip -= 4; - regs->result = 0; - break; - } -} - /* * Note that 'init' is a special process: it doesn't get signals it doesn't * want to handle. Thus you cannot kill init even with a SIGKILL even by @@ -522,13 +489,13 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs) oldset = ¤t->blocked; signr = get_signal_to_deliver(&info, &ka, regs, NULL); + + /* Is there any syscall restart business here ? */ + check_syscall_restart(regs, &ka, signr > 0); + if (signr > 0) { int ret; - /* Whee! Actually deliver the signal. */ - if (TRAP(regs) == 0x0C00) - syscall_restart(regs, &ka); - /* * Reenable the DABR before delivering the signal to * user space. The DABR will have been cleared if it @@ -537,6 +504,7 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs) if (current->thread.dabr) set_dabr(current->thread.dabr); + /* Whee! Actually deliver the signal. */ ret = handle_signal(signr, &ka, &info, oldset, regs); /* If a signal was successfully delivered, the saved sigmask is in @@ -547,19 +515,6 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs) return ret; } - if (TRAP(regs) == 0x0C00) { /* System Call! */ - if ((int)regs->result == -ERESTARTNOHAND || - (int)regs->result == -ERESTARTSYS || - (int)regs->result == -ERESTARTNOINTR) { - regs->gpr[3] = regs->orig_gpr3; - regs->nip -= 4; /* Back up & retry system call */ - regs->result = 0; - } else if ((int)regs->result == -ERESTART_RESTARTBLOCK) { - regs->gpr[0] = __NR_restart_syscall; - regs->nip -= 4; - regs->result = 0; - } - } /* No signal to deliver -- put the saved sigmask back */ if (test_thread_flag(TIF_RESTORE_SIGMASK)) { clear_thread_flag(TIF_RESTORE_SIGMASK); |