diff options
author | Paul Mundt <lethal@linux-sh.org> | 2009-01-29 03:21:38 +0100 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2009-01-29 03:56:03 +0100 |
commit | 03f07876df2565321871a2dbf33c5c737df185df (patch) | |
tree | c0c5d6d9a83e53acfc2052d99ff4e26f360af018 /arch/sh | |
parent | sh: fcnvds fix with denormalized numbers on SH-4 FPU. (diff) | |
download | linux-03f07876df2565321871a2dbf33c5c737df185df.tar.xz linux-03f07876df2565321871a2dbf33c5c737df185df.zip |
sh: Fix up spurious syscall restarting.
The T-bit manipulation for syscall error checking had the side effect of
spuriously returning ERESTART* errno values over EINTR. So, we simplify
the error checking a bit and leave the T-bit alone.
Reported-by: Kaz Kojima <kkojima@rr.iij4u.or.jp>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh')
-rw-r--r-- | arch/sh/include/asm/syscall_32.h | 22 | ||||
-rw-r--r-- | arch/sh/include/asm/syscall_64.h | 22 | ||||
-rw-r--r-- | arch/sh/kernel/signal_32.c | 4 | ||||
-rw-r--r-- | arch/sh/kernel/signal_64.c | 4 |
4 files changed, 8 insertions, 44 deletions
diff --git a/arch/sh/include/asm/syscall_32.h b/arch/sh/include/asm/syscall_32.h index 05a868a71ef5..5bc34681d994 100644 --- a/arch/sh/include/asm/syscall_32.h +++ b/arch/sh/include/asm/syscall_32.h @@ -21,23 +21,10 @@ static inline void syscall_rollback(struct task_struct *task, */ } -static inline bool syscall_has_error(struct pt_regs *regs) -{ - return (regs->sr & 0x1) ? true : false; -} -static inline void syscall_set_error(struct pt_regs *regs) -{ - regs->sr |= 0x1; -} -static inline void syscall_clear_error(struct pt_regs *regs) -{ - regs->sr &= ~0x1; -} - static inline long syscall_get_error(struct task_struct *task, struct pt_regs *regs) { - return syscall_has_error(regs) ? regs->regs[0] : 0; + return IS_ERR_VALUE(regs->regs[0]) ? regs->regs[0] : 0; } static inline long syscall_get_return_value(struct task_struct *task, @@ -50,13 +37,10 @@ static inline void syscall_set_return_value(struct task_struct *task, struct pt_regs *regs, int error, long val) { - if (error) { - syscall_set_error(regs); + if (error) regs->regs[0] = -error; - } else { - syscall_clear_error(regs); + else regs->regs[0] = val; - } } static inline void syscall_get_arguments(struct task_struct *task, diff --git a/arch/sh/include/asm/syscall_64.h b/arch/sh/include/asm/syscall_64.h index e1143b9784d6..c3561ca72bee 100644 --- a/arch/sh/include/asm/syscall_64.h +++ b/arch/sh/include/asm/syscall_64.h @@ -21,23 +21,10 @@ static inline void syscall_rollback(struct task_struct *task, */ } -static inline bool syscall_has_error(struct pt_regs *regs) -{ - return (regs->sr & 0x1) ? true : false; -} -static inline void syscall_set_error(struct pt_regs *regs) -{ - regs->sr |= 0x1; -} -static inline void syscall_clear_error(struct pt_regs *regs) -{ - regs->sr &= ~0x1; -} - static inline long syscall_get_error(struct task_struct *task, struct pt_regs *regs) { - return syscall_has_error(regs) ? regs->regs[9] : 0; + return IS_ERR_VALUE(regs->regs[9]) ? regs->regs[9] : 0; } static inline long syscall_get_return_value(struct task_struct *task, @@ -50,13 +37,10 @@ static inline void syscall_set_return_value(struct task_struct *task, struct pt_regs *regs, int error, long val) { - if (error) { - syscall_set_error(regs); + if (error) regs->regs[9] = -error; - } else { - syscall_clear_error(regs); + else regs->regs[9] = val; - } } static inline void syscall_get_arguments(struct task_struct *task, diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c index 77c21bde376a..17784e19ae34 100644 --- a/arch/sh/kernel/signal_32.c +++ b/arch/sh/kernel/signal_32.c @@ -510,7 +510,6 @@ handle_syscall_restart(unsigned long save_r0, struct pt_regs *regs, case -ERESTARTNOHAND: no_system_call_restart: regs->regs[0] = -EINTR; - regs->sr |= 1; break; case -ERESTARTSYS: @@ -589,8 +588,7 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0) signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { - if (regs->sr & 1) - handle_syscall_restart(save_r0, regs, &ka.sa); + handle_syscall_restart(save_r0, regs, &ka.sa); /* Whee! Actually deliver the signal. */ if (handle_signal(signr, &ka, &info, oldset, diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c index b22fdfaaa191..0663a0ee6021 100644 --- a/arch/sh/kernel/signal_64.c +++ b/arch/sh/kernel/signal_64.c @@ -60,7 +60,6 @@ handle_syscall_restart(struct pt_regs *regs, struct sigaction *sa) case -ERESTARTNOHAND: no_system_call_restart: regs->regs[REG_RET] = -EINTR; - regs->sr |= 1; break; case -ERESTARTSYS: @@ -109,8 +108,7 @@ static int do_signal(struct pt_regs *regs, sigset_t *oldset) signr = get_signal_to_deliver(&info, &ka, regs, 0); if (signr > 0) { - if (regs->sr & 1) - handle_syscall_restart(regs, &ka.sa); + handle_syscall_restart(regs, &ka.sa); /* Whee! Actually deliver the signal. */ if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { |