Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=c18fe9a0467afaec7de05ec76cd994ae7c866760
Commit:     c18fe9a0467afaec7de05ec76cd994ae7c866760
Parent:     599c26d32950c33bdd2a5ac6939bfe15ecf057e0
Author:     Paul Mundt <[EMAIL PROTECTED]>
AuthorDate: Mon May 14 09:12:39 2007 +0900
Committer:  Paul Mundt <[EMAIL PROTECTED]>
CommitDate: Mon May 14 09:12:39 2007 +0900

    sh64: ppoll/pselect6() and restartable syscalls.
    
    This patch was hanging around for some time while we were waiting
    for the compiler situation to improve.. now that all is well again,
    finally merge it.
    
    Signed-off-by: Paul Mundt <[EMAIL PROTECTED]>
---
 arch/sh64/kernel/entry.S       |    4 ++--
 arch/sh64/kernel/signal.c      |   33 +++++++++++++++++++++++++++++----
 include/asm-sh64/thread_info.h |    6 ++++++
 3 files changed, 37 insertions(+), 6 deletions(-)

diff --git a/arch/sh64/kernel/entry.S b/arch/sh64/kernel/entry.S
index 40d4534..7013fcb 100644
--- a/arch/sh64/kernel/entry.S
+++ b/arch/sh64/kernel/entry.S
@@ -947,14 +947,14 @@ ret_with_reschedule:
        ! FIXME:!!!
        ! no handling of TIF_SYSCALL_TRACE yet!!
 
-       movi    (1 << TIF_NEED_RESCHED), r8
+       movi    _TIF_NEED_RESCHED, r8
        and     r8, r7, r8
        pta     work_resched, tr0
        bne     r8, ZERO, tr0
 
        pta     restore_all, tr1
 
-       movi    (1 << TIF_SIGPENDING), r8
+       movi    (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), r8
        and     r8, r7, r8
        pta     work_notifysig, tr0
        bne     r8, ZERO, tr0
diff --git a/arch/sh64/kernel/signal.c b/arch/sh64/kernel/signal.c
index b76bdfa..c8525ad 100644
--- a/arch/sh64/kernel/signal.c
+++ b/arch/sh64/kernel/signal.c
@@ -698,7 +698,9 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
        if (try_to_freeze())
                goto no_signal;
 
-       if (!oldset)
+       if (test_thread_flag(TIF_RESTORE_SIGMASK))
+               oldset = &current->saved_sigmask;
+       else if (!oldset)
                oldset = &current->blocked;
 
        signr = get_signal_to_deliver(&info, &ka, regs, 0);
@@ -706,6 +708,15 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
        if (signr > 0) {
                /* Whee!  Actually deliver the signal.  */
                handle_signal(signr, &info, &ka, 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 (test_thread_flag(TIF_RESTORE_SIGMASK))
+                       clear_thread_flag(TIF_RESTORE_SIGMASK);
+
                return 1;
        }
 
@@ -713,13 +724,27 @@ no_signal:
        /* Did we come from a system call? */
        if (regs->syscall_nr >= 0) {
                /* Restart the system call - no handlers present */
-               if (regs->regs[REG_RET] == -ERESTARTNOHAND ||
-                   regs->regs[REG_RET] == -ERESTARTSYS ||
-                   regs->regs[REG_RET] == -ERESTARTNOINTR) {
+               switch (regs->regs[REG_RET]) {
+               case -ERESTARTNOHAND:
+               case -ERESTARTSYS:
+               case -ERESTARTNOINTR:
                        /* Decode Syscall # */
                        regs->regs[REG_RET] = regs->syscall_nr;
                        regs->pc -= 4;
+                       break;
+
+               case -ERESTART_RESTARTBLOCK:
+                       regs->regs[REG_RET] = __NR_restart_syscall;
+                       regs->pc -= 4;
+                       break;
                }
        }
+
+       /* 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, &current->saved_sigmask, NULL);
+       }
+
        return 0;
 }
diff --git a/include/asm-sh64/thread_info.h b/include/asm-sh64/thread_info.h
index 1f825cb..f6d5117 100644
--- a/include/asm-sh64/thread_info.h
+++ b/include/asm-sh64/thread_info.h
@@ -78,7 +78,13 @@ static inline struct thread_info *current_thread_info(void)
 #define TIF_SIGPENDING         2       /* signal pending */
 #define TIF_NEED_RESCHED       3       /* rescheduling necessary */
 #define TIF_MEMDIE             4
+#define TIF_RESTORE_SIGMASK    5       /* Restore signal mask in do_signal */
 
+#define _TIF_SYSCALL_TRACE     (1 << TIF_SYSCALL_TRACE)
+#define _TIF_SIGPENDING                (1 << TIF_SIGPENDING)
+#define _TIF_NEED_RESCHED      (1 << TIF_NEED_RESCHED)
+#define _TIF_MEMDIE            (1 << TIF_MEMDIE)
+#define _TIF_RESTORE_SIGMASK   (1 << TIF_RESTORE_SIGMASK)
 
 #endif /* __KERNEL__ */
 
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to