MTMSRD(r10)
        lwz     r9,TI_FLAGS(r12)
        li      r8,-_LAST_ERRNO
-       andi.   r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL)
+       andi.   r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL|_TIF_RESTORE_SIGMASK)
        bne-    syscall_exit_work
        cmplw   0,r3,r8
        blt+    syscall_exit_cont
        lwz     r5,_MSR(r1)
        andi.   r5,r5,MSR_PR
        beq     ret_from_except
-       andi.   r0,r9,_TIF_SIGPENDING
+       andi.   r0,r9,_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK
        beq     ret_from_except
        b       do_user_signal
 8:
        /* Check current_thread_info()->flags */
        rlwinm  r9,r1,0,0,(31-THREAD_SHIFT)
        lwz     r9,TI_FLAGS(r9)
-       andi.   r0,r9,(_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL)
+       andi.   r0,r9,(_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL|_TIF_RESTORE_SIGMASK)
        bne     do_work
 
 restore_user:
        lwz     r9,TI_FLAGS(r9)
        andi.   r0,r9,_TIF_NEED_RESCHED
        bne-    do_resched
-       andi.   r0,r9,_TIF_SIGPENDING
+       andi.   r0,r9,_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK
        beq     restore_user
 do_user_signal:                        /* r10 contains MSR_KERNEL here */
        ori     r10,r10,MSR_EE
 
        mtmsrd  r10,1
        ld      r9,TI_FLAGS(r12)
        li      r11,-_LAST_ERRNO
-       andi.   r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL|_TIF_SAVE_NVGPRS|_TIF_NOERROR)
+       andi.   r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL|_TIF_SAVE_NVGPRS|_TIF_NOERROR|_TIF_RESTORE_SIGMASK)
        bne-    syscall_exit_work
        cmpld   r3,r11
        ld      r5,_CCR(r1)
 
 {
        siginfo_t info;
        struct k_sigaction ka;
-       unsigned int frame, newsp;
+       unsigned int newsp;
        int signr, ret;
 
 #ifdef CONFIG_PPC32
        }
 #endif
 
-       if (!oldset)
+       if (test_thread_flag(TIF_RESTORE_SIGMASK))
+               oldset = ¤t->saved_sigmask;
+       else if (!oldset)
                oldset = ¤t->blocked;
 
-       newsp = frame = 0;
-
        signr = get_signal_to_deliver(&info, &ka, regs, NULL);
 #ifdef CONFIG_PPC32
 no_signal:
                }
        }
 
-       if (signr == 0)
+       if (signr == 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;               /* no signals delivered */
+       }
 
        if ((ka.sa.sa_flags & SA_ONSTACK) && current->sas_ss_size
            && !on_sig_stack(regs->gpr[1]))
                        sigaddset(¤t->blocked, signr);
                recalc_sigpending();
                spin_unlock_irq(¤t->sighand->siglock);
+               /* 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 ret;
 
        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);
                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! */
                        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;
 }
 
 SYSCALL(inotify_rm_watch)
 SYSCALL(spu_run)
 SYSCALL(spu_create)
+COMPAT_SYS(pselect6)
+COMPAT_SYS(ppoll)
 
 #define TIF_RESTOREALL         12      /* Restore all regs (implies NOERROR) */
 #define TIF_SAVE_NVGPRS                13      /* Save r14-r31 in signal frame */
 #define TIF_NOERROR            14      /* Force successful syscall return */
+#define TIF_RESTORE_SIGMASK    15      /* Restore signal mask in do_signal */
 
 /* as above, but as bit values */
 #define _TIF_SYSCALL_TRACE     (1<<TIF_SYSCALL_TRACE)
 #define _TIF_RESTOREALL                (1<<TIF_RESTOREALL)
 #define _TIF_SAVE_NVGPRS       (1<<TIF_SAVE_NVGPRS)
 #define _TIF_NOERROR           (1<<TIF_NOERROR)
+#define _TIF_RESTORE_SIGMASK   (1<<TIF_RESTORE_SIGMASK)
 #define _TIF_SYSCALL_T_OR_A    (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP)
 
 #define _TIF_USER_WORK_MASK    (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING | \
-                                _TIF_NEED_RESCHED | _TIF_RESTOREALL)
+                                _TIF_NEED_RESCHED | _TIF_RESTOREALL | \
+                                _TIF_RESTORE_SIGMASK)
 #define _TIF_PERSYSCALL_MASK   (_TIF_RESTOREALL|_TIF_NOERROR|_TIF_SAVE_NVGPRS)
 
 #endif /* __KERNEL__ */
 
 #define __NR_inotify_rm_watch  277
 #define __NR_spu_run           278
 #define __NR_spu_create                279
+#define __NR_pselect6          280
+#define __NR_ppoll             281
 
-#define __NR_syscalls          280
+#define __NR_syscalls          282
 
 #ifdef __KERNEL__
 #define __NR__exit __NR_exit