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

sh: __NR_restart_syscall support.

This implements support for __NR_restart_syscall.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>

+13 -7
+2
arch/sh/kernel/entry.S
··· 376 376 bt/s restore_all 377 377 mov r15, r4 378 378 mov #0, r5 379 + mov r12, r6 ! set arg2(save_r0) 379 380 mov.l 2f, r1 380 381 mova restore_all, r0 381 382 jmp @r1 ··· 535 534 mov.l @r9, r8 536 535 jsr @r8 ! jump to specific syscall handler 537 536 nop 537 + mov.l @(OFF_R0,r15), r12 ! save r0 538 538 mov.l r0, @(OFF_R0,r15) ! save the return value 539 539 ! 540 540 syscall_exit:
+10 -6
arch/sh/kernel/signal.c
··· 33 33 34 34 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 35 35 36 - asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset); 36 + asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset, 37 + unsigned int save_r0); 37 38 38 39 /* 39 40 * Atomically swap in the new signal mask, and wait for a signal. ··· 57 56 while (1) { 58 57 current->state = TASK_INTERRUPTIBLE; 59 58 schedule(); 60 - if (do_signal(&regs, &saveset)) 59 + if (do_signal(&regs, &saveset, regs.regs[0])) 61 60 return -EINTR; 62 61 } 63 62 } ··· 86 85 while (1) { 87 86 current->state = TASK_INTERRUPTIBLE; 88 87 schedule(); 89 - if (do_signal(&regs, &saveset)) 88 + if (do_signal(&regs, &saveset, regs.regs[0])) 90 89 return -EINTR; 91 90 } 92 91 } ··· 564 563 * the kernel can handle, and then we build all the user-level signal handling 565 564 * stack-frames in one go after that. 566 565 */ 567 - int do_signal(struct pt_regs *regs, sigset_t *oldset) 566 + int do_signal(struct pt_regs *regs, sigset_t *oldset, unsigned int save_r0) 568 567 { 569 568 siginfo_t info; 570 569 int signr; ··· 598 597 /* Restart the system call - no handlers present */ 599 598 if (regs->regs[0] == -ERESTARTNOHAND || 600 599 regs->regs[0] == -ERESTARTSYS || 601 - regs->regs[0] == -ERESTARTNOINTR || 602 - regs->regs[0] == -ERESTART_RESTARTBLOCK) { 600 + regs->regs[0] == -ERESTARTNOINTR) { 601 + regs->regs[0] = save_r0; 603 602 regs->pc -= 2; 603 + } else if (regs->regs[0] == -ERESTART_RESTARTBLOCK) { 604 + regs->pc -= 2; 605 + regs->regs[3] = __NR_restart_syscall; 604 606 } 605 607 } 606 608 return 0;
+1 -1
arch/sh/kernel/syscalls.S
··· 34 34 35 35 .data 36 36 ENTRY(sys_call_table) 37 - .long sys_ni_syscall /* 0 - old "setup()" system call*/ 37 + .long sys_restart_syscall /* 0 - old "setup()" system call*/ 38 38 .long sys_exit 39 39 .long sys_fork 40 40 .long sys_read