forked from luck/tmp_suning_uos_patched
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:
parent
e96636ccfa
commit
0b8929354c
@ -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:
|
||||||
|
@ -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(®s, &saveset))
|
if (do_signal(®s, &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(®s, &saveset))
|
if (do_signal(®s, &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;
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user