Commit 6024955e authored by David S. Miller's avatar David S. Miller

[SPARC]: ADd ERESTART_RESTARTBLOCK signal return handling.

parent 3694fbeb
...@@ -1019,19 +1019,22 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, ...@@ -1019,19 +1019,22 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
struct sigaction *sa) struct sigaction *sa)
{ {
switch(regs->u_regs[UREG_I0]) { switch(regs->u_regs[UREG_I0]) {
case ERESTARTNOHAND: case ERESTART_RESTARTBLOCK:
no_system_call_restart: current_thread_info()->restart_block.fn = do_no_restart_syscall;
regs->u_regs[UREG_I0] = EINTR; /* fallthrough */
regs->psr |= PSR_C; case ERESTARTNOHAND:
break; no_system_call_restart:
case ERESTARTSYS: regs->u_regs[UREG_I0] = EINTR;
if(!(sa->sa_flags & SA_RESTART)) regs->psr |= PSR_C;
goto no_system_call_restart; break;
case ERESTARTSYS:
if(!(sa->sa_flags & SA_RESTART))
goto no_system_call_restart;
/* fallthrough */ /* fallthrough */
case ERESTARTNOINTR: case ERESTARTNOINTR:
regs->u_regs[UREG_I0] = orig_i0; regs->u_regs[UREG_I0] = orig_i0;
regs->pc -= 4; regs->pc -= 4;
regs->npc -= 4; regs->npc -= 4;
} }
} }
...@@ -1084,6 +1087,13 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, ...@@ -1084,6 +1087,13 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
regs->npc -= 4; regs->npc -= 4;
restart_syscall = 0; restart_syscall = 0;
} }
if (restart_syscall &&
regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
regs->u_regs[UREG_G1] = __NR_restart_syscall;
regs->pc -= 4;
regs->npc -= 4;
restart_syscall = 0;
}
current->exit_code = signr; current->exit_code = signr;
set_current_state(TASK_STOPPED); set_current_state(TASK_STOPPED);
...@@ -1184,6 +1194,12 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, ...@@ -1184,6 +1194,12 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
regs->pc -= 4; regs->pc -= 4;
regs->npc -= 4; regs->npc -= 4;
} }
if (restart_syscall &&
regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
regs->u_regs[UREG_G1] = __NR_restart_syscall;
regs->pc -= 4;
regs->npc -= 4;
}
return 0; return 0;
} }
......
...@@ -573,19 +573,22 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, ...@@ -573,19 +573,22 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
struct sigaction *sa) struct sigaction *sa)
{ {
switch (regs->u_regs[UREG_I0]) { switch (regs->u_regs[UREG_I0]) {
case ERESTARTNOHAND: case ERESTART_RESTARTBLOCK:
no_system_call_restart: current_thread_info()->restart_block.fn = do_no_restart_syscall;
regs->u_regs[UREG_I0] = EINTR; /* fallthrough */
regs->tstate |= (TSTATE_ICARRY|TSTATE_XCARRY); case ERESTARTNOHAND:
break; no_system_call_restart:
case ERESTARTSYS: regs->u_regs[UREG_I0] = EINTR;
if (!(sa->sa_flags & SA_RESTART)) regs->tstate |= (TSTATE_ICARRY|TSTATE_XCARRY);
goto no_system_call_restart; break;
case ERESTARTSYS:
if (!(sa->sa_flags & SA_RESTART))
goto no_system_call_restart;
/* fallthrough */ /* fallthrough */
case ERESTARTNOINTR: case ERESTARTNOINTR:
regs->u_regs[UREG_I0] = orig_i0; regs->u_regs[UREG_I0] = orig_i0;
regs->tpc -= 4; regs->tpc -= 4;
regs->tnpc -= 4; regs->tnpc -= 4;
} }
} }
...@@ -634,6 +637,13 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs, ...@@ -634,6 +637,13 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs,
regs->tnpc -= 4; regs->tnpc -= 4;
restart_syscall = 0; restart_syscall = 0;
} }
if (restart_syscall &&
regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
regs->u_regs[UREG_G1] = __NR_restart_syscall;
regs->tpc -= 4;
regs->tnpc -= 4;
restart_syscall = 0;
}
current->exit_code = signr; current->exit_code = signr;
set_current_state(TASK_STOPPED); set_current_state(TASK_STOPPED);
...@@ -727,6 +737,12 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs, ...@@ -727,6 +737,12 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs,
regs->tpc -= 4; regs->tpc -= 4;
regs->tnpc -= 4; regs->tnpc -= 4;
} }
if (restart_syscall &&
regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
regs->u_regs[UREG_G1] = __NR_restart_syscall;
regs->tpc -= 4;
regs->tnpc -= 4;
}
return 0; return 0;
} }
......
...@@ -1253,19 +1253,22 @@ static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs ...@@ -1253,19 +1253,22 @@ static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs
struct sigaction *sa) struct sigaction *sa)
{ {
switch (regs->u_regs[UREG_I0]) { switch (regs->u_regs[UREG_I0]) {
case ERESTARTNOHAND: case ERESTART_RESTARTBLOCK:
no_system_call_restart: current_thread_info()->restart_block.fn = do_no_restart_syscall;
regs->u_regs[UREG_I0] = EINTR; /* fallthrough */
regs->tstate |= TSTATE_ICARRY; case ERESTARTNOHAND:
break; no_system_call_restart:
case ERESTARTSYS: regs->u_regs[UREG_I0] = EINTR;
if (!(sa->sa_flags & SA_RESTART)) regs->tstate |= TSTATE_ICARRY;
goto no_system_call_restart; break;
case ERESTARTSYS:
if (!(sa->sa_flags & SA_RESTART))
goto no_system_call_restart;
/* fallthrough */ /* fallthrough */
case ERESTARTNOINTR: case ERESTARTNOINTR:
regs->u_regs[UREG_I0] = orig_i0; regs->u_regs[UREG_I0] = orig_i0;
regs->tpc -= 4; regs->tpc -= 4;
regs->tnpc -= 4; regs->tnpc -= 4;
} }
} }
...@@ -1306,6 +1309,13 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs, ...@@ -1306,6 +1309,13 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs,
regs->tnpc -= 4; regs->tnpc -= 4;
restart_syscall = 0; restart_syscall = 0;
} }
if (restart_syscall &&
regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
regs->u_regs[UREG_G1] = __NR_restart_syscall;
regs->tpc -= 4;
regs->tnpc -= 4;
restart_syscall = 0;
}
current->exit_code = signr; current->exit_code = signr;
set_current_state(TASK_STOPPED); set_current_state(TASK_STOPPED);
...@@ -1398,6 +1408,12 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs, ...@@ -1398,6 +1408,12 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs,
regs->tpc -= 4; regs->tpc -= 4;
regs->tnpc -= 4; regs->tnpc -= 4;
} }
if (restart_syscall &&
regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
regs->u_regs[UREG_G1] = __NR_restart_syscall;
regs->tpc -= 4;
regs->tnpc -= 4;
}
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment