sh: __NR_restart_syscall support.

This implements support for __NR_restart_syscall.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>
This commit is contained in:
Paul Mundt 2006-09-27 17:22:49 +09:00
parent e96636ccfa
commit 0b8929354c
3 changed files with 13 additions and 7 deletions

View File

@ -376,6 +376,7 @@ work_notifysig:
bt/s restore_all bt/s restore_all
mov r15, r4 mov r15, r4
mov #0, r5 mov #0, r5
mov r12, r6 ! set arg2(save_r0)
mov.l 2f, r1 mov.l 2f, r1
mova restore_all, r0 mova restore_all, r0
jmp @r1 jmp @r1
@ -534,6 +535,7 @@ syscall_call:
mov.l @r9, r8 mov.l @r9, r8
jsr @r8 ! jump to specific syscall handler jsr @r8 ! jump to specific syscall handler
nop nop
mov.l @(OFF_R0,r15), r12 ! save r0
mov.l r0, @(OFF_R0,r15) ! save the return value mov.l r0, @(OFF_R0,r15) ! save the return value
! !
syscall_exit: syscall_exit:

View File

@ -33,7 +33,8 @@
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset); asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset,
unsigned int save_r0);
/* /*
* Atomically swap in the new signal mask, and wait for a signal. * Atomically swap in the new signal mask, and wait for a signal.
@ -56,7 +57,7 @@ sys_sigsuspend(old_sigset_t mask,
while (1) { while (1) {
current->state = TASK_INTERRUPTIBLE; current->state = TASK_INTERRUPTIBLE;
schedule(); schedule();
if (do_signal(&regs, &saveset)) if (do_signal(&regs, &saveset, regs.regs[0]))
return -EINTR; return -EINTR;
} }
} }
@ -85,7 +86,7 @@ sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize,
while (1) { while (1) {
current->state = TASK_INTERRUPTIBLE; current->state = TASK_INTERRUPTIBLE;
schedule(); schedule();
if (do_signal(&regs, &saveset)) if (do_signal(&regs, &saveset, regs.regs[0]))
return -EINTR; return -EINTR;
} }
} }
@ -563,7 +564,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
* the kernel can handle, and then we build all the user-level signal handling * the kernel can handle, and then we build all the user-level signal handling
* stack-frames in one go after that. * stack-frames in one go after that.
*/ */
int do_signal(struct pt_regs *regs, sigset_t *oldset) int do_signal(struct pt_regs *regs, sigset_t *oldset, unsigned int save_r0)
{ {
siginfo_t info; siginfo_t info;
int signr; int signr;
@ -597,9 +598,12 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
/* Restart the system call - no handlers present */ /* Restart the system call - no handlers present */
if (regs->regs[0] == -ERESTARTNOHAND || if (regs->regs[0] == -ERESTARTNOHAND ||
regs->regs[0] == -ERESTARTSYS || regs->regs[0] == -ERESTARTSYS ||
regs->regs[0] == -ERESTARTNOINTR || regs->regs[0] == -ERESTARTNOINTR) {
regs->regs[0] == -ERESTART_RESTARTBLOCK) { regs->regs[0] = save_r0;
regs->pc -= 2; regs->pc -= 2;
} else if (regs->regs[0] == -ERESTART_RESTARTBLOCK) {
regs->pc -= 2;
regs->regs[3] = __NR_restart_syscall;
} }
} }
return 0; return 0;

View File

@ -34,7 +34,7 @@
.data .data
ENTRY(sys_call_table) ENTRY(sys_call_table)
.long sys_ni_syscall /* 0 - old "setup()" system call*/ .long sys_restart_syscall /* 0 - old "setup()" system call*/
.long sys_exit .long sys_exit
.long sys_fork .long sys_fork
.long sys_read .long sys_read