! 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
 
        if (try_to_freeze())
                goto no_signal;
 
-       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, 0);
        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;
        }
 
        /* 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, ¤t->saved_sigmask, NULL);
+       }
+
        return 0;
 }
 
 #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__ */