From f27201da5c8f118cfe266f51447bdd108d5f081d Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Wed, 18 Jan 2006 17:44:01 -0800 Subject: [PATCH] TIF_RESTORE_SIGMASK support for arch/powerpc Implement the TIF_RESTORE_SIGMASK flag in the new arch/powerpc kernel, for both 32-bit and 64-bit system call paths. Signed-off-by: David Woodhouse Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/powerpc/kernel/signal_64.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'arch/powerpc/kernel/signal_64.c') diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index a4a6812e815..b3193116e68 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -520,11 +520,15 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs) if (test_thread_flag(TIF_32BIT)) return do_signal32(oldset, regs); - if (!oldset) + if (test_thread_flag(TIF_RESTORE_SIGMASK)) + oldset = ¤t->saved_sigmask; + else if (!oldset) oldset = ¤t->blocked; signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { + int ret; + /* Whee! Actually deliver the signal. */ if (TRAP(regs) == 0x0C00) syscall_restart(regs, &ka); @@ -537,7 +541,14 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs) if (current->thread.dabr) set_dabr(current->thread.dabr); - return handle_signal(signr, &ka, &info, oldset, regs); + ret = handle_signal(signr, &ka, &info, oldset, regs); + + /* If a signal was successfully delivered, the saved sigmask is in + its frame, and we can clear the TIF_RESTORE_SIGMASK flag */ + if (ret && test_thread_flag(TIF_RESTORE_SIGMASK)) + clear_thread_flag(TIF_RESTORE_SIGMASK); + + return ret; } if (TRAP(regs) == 0x0C00) { /* System Call! */ @@ -553,6 +564,11 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs) 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); + sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); + } return 0; } -- cgit v1.2.3