Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <lethal@linux-sh.org>

+37 -6
+2 -2
arch/sh64/kernel/entry.S
··· 947 947 ! FIXME:!!! 948 948 ! no handling of TIF_SYSCALL_TRACE yet!! 949 949 950 - movi (1 << TIF_NEED_RESCHED), r8 950 + movi _TIF_NEED_RESCHED, r8 951 951 and r8, r7, r8 952 952 pta work_resched, tr0 953 953 bne r8, ZERO, tr0 954 954 955 955 pta restore_all, tr1 956 956 957 - movi (1 << TIF_SIGPENDING), r8 957 + movi (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), r8 958 958 and r8, r7, r8 959 959 pta work_notifysig, tr0 960 960 bne r8, ZERO, tr0
+29 -4
arch/sh64/kernel/signal.c
··· 698 698 if (try_to_freeze()) 699 699 goto no_signal; 700 700 701 - if (!oldset) 701 + if (test_thread_flag(TIF_RESTORE_SIGMASK)) 702 + oldset = &current->saved_sigmask; 703 + else if (!oldset) 702 704 oldset = &current->blocked; 703 705 704 706 signr = get_signal_to_deliver(&info, &ka, regs, 0); ··· 708 706 if (signr > 0) { 709 707 /* Whee! Actually deliver the signal. */ 710 708 handle_signal(signr, &info, &ka, oldset, regs); 709 + 710 + /* 711 + * If a signal was successfully delivered, the saved sigmask 712 + * is in its frame, and we can clear the TIF_RESTORE_SIGMASK 713 + * flag. 714 + */ 715 + if (test_thread_flag(TIF_RESTORE_SIGMASK)) 716 + clear_thread_flag(TIF_RESTORE_SIGMASK); 717 + 711 718 return 1; 712 719 } 713 720 ··· 724 713 /* Did we come from a system call? */ 725 714 if (regs->syscall_nr >= 0) { 726 715 /* Restart the system call - no handlers present */ 727 - if (regs->regs[REG_RET] == -ERESTARTNOHAND || 728 - regs->regs[REG_RET] == -ERESTARTSYS || 729 - regs->regs[REG_RET] == -ERESTARTNOINTR) { 716 + switch (regs->regs[REG_RET]) { 717 + case -ERESTARTNOHAND: 718 + case -ERESTARTSYS: 719 + case -ERESTARTNOINTR: 730 720 /* Decode Syscall # */ 731 721 regs->regs[REG_RET] = regs->syscall_nr; 732 722 regs->pc -= 4; 723 + break; 724 + 725 + case -ERESTART_RESTARTBLOCK: 726 + regs->regs[REG_RET] = __NR_restart_syscall; 727 + regs->pc -= 4; 728 + break; 733 729 } 734 730 } 731 + 732 + /* No signal to deliver -- put the saved sigmask back */ 733 + if (test_thread_flag(TIF_RESTORE_SIGMASK)) { 734 + clear_thread_flag(TIF_RESTORE_SIGMASK); 735 + sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL); 736 + } 737 + 735 738 return 0; 736 739 }
+6
include/asm-sh64/thread_info.h
··· 78 78 #define TIF_SIGPENDING 2 /* signal pending */ 79 79 #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ 80 80 #define TIF_MEMDIE 4 81 + #define TIF_RESTORE_SIGMASK 5 /* Restore signal mask in do_signal */ 81 82 83 + #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) 84 + #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) 85 + #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) 86 + #define _TIF_MEMDIE (1 << TIF_MEMDIE) 87 + #define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) 82 88 83 89 #endif /* __KERNEL__ */ 84 90