Skip to content

Commit

Permalink
sh64: ppoll/pselect6() and restartable syscalls.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Paul Mundt committed May 14, 2007
1 parent 599c26d commit c18fe9a
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 6 deletions.
4 changes: 2 additions & 2 deletions arch/sh64/kernel/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
33 changes: 29 additions & 4 deletions arch/sh64/kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -698,28 +698,53 @@ 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);

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;
}

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;
}
6 changes: 6 additions & 0 deletions include/asm-sh64/thread_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -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__ */

Expand Down

0 comments on commit c18fe9a

Please sign in to comment.