diff options
author | Paul Mundt <lethal@linux-sh.org> | 2009-01-28 21:21:38 -0500 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2009-01-28 21:56:03 -0500 |
commit | 03f07876df2565321871a2dbf33c5c737df185df (patch) | |
tree | c0c5d6d9a83e53acfc2052d99ff4e26f360af018 | |
parent | 0f6dee232f84c11ec195721571763ccae1b82639 (diff) |
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>
-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, | |||
21 | */ | 21 | */ |
22 | } | 22 | } |
23 | 23 | ||
24 | static inline bool syscall_has_error(struct pt_regs *regs) | ||
25 | { | ||
26 | return (regs->sr & 0x1) ? true : false; | ||
27 | } | ||
28 | static inline void syscall_set_error(struct pt_regs *regs) | ||
29 | { | ||
30 | regs->sr |= 0x1; | ||
31 | } | ||
32 | static inline void syscall_clear_error(struct pt_regs *regs) | ||
33 | { | ||
34 | regs->sr &= ~0x1; | ||
35 | } | ||
36 | |||
37 | static inline long syscall_get_error(struct task_struct *task, | 24 | static inline long syscall_get_error(struct task_struct *task, |
38 | struct pt_regs *regs) | 25 | struct pt_regs *regs) |
39 | { | 26 | { |
40 | return syscall_has_error(regs) ? regs->regs[0] : 0; | 27 | return IS_ERR_VALUE(regs->regs[0]) ? regs->regs[0] : 0; |
41 | } | 28 | } |
42 | 29 | ||
43 | static inline long syscall_get_return_value(struct task_struct *task, | 30 | 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, | |||
50 | struct pt_regs *regs, | 37 | struct pt_regs *regs, |
51 | int error, long val) | 38 | int error, long val) |
52 | { | 39 | { |
53 | if (error) { | 40 | if (error) |
54 | syscall_set_error(regs); | ||
55 | regs->regs[0] = -error; | 41 | regs->regs[0] = -error; |
56 | } else { | 42 | else |
57 | syscall_clear_error(regs); | ||
58 | regs->regs[0] = val; | 43 | regs->regs[0] = val; |
59 | } | ||
60 | } | 44 | } |
61 | 45 | ||
62 | static inline void syscall_get_arguments(struct task_struct *task, | 46 | 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, | |||
21 | */ | 21 | */ |
22 | } | 22 | } |
23 | 23 | ||
24 | static inline bool syscall_has_error(struct pt_regs *regs) | ||
25 | { | ||
26 | return (regs->sr & 0x1) ? true : false; | ||
27 | } | ||
28 | static inline void syscall_set_error(struct pt_regs *regs) | ||
29 | { | ||
30 | regs->sr |= 0x1; | ||
31 | } | ||
32 | static inline void syscall_clear_error(struct pt_regs *regs) | ||
33 | { | ||
34 | regs->sr &= ~0x1; | ||
35 | } | ||
36 | |||
37 | static inline long syscall_get_error(struct task_struct *task, | 24 | static inline long syscall_get_error(struct task_struct *task, |
38 | struct pt_regs *regs) | 25 | struct pt_regs *regs) |
39 | { | 26 | { |
40 | return syscall_has_error(regs) ? regs->regs[9] : 0; | 27 | return IS_ERR_VALUE(regs->regs[9]) ? regs->regs[9] : 0; |
41 | } | 28 | } |
42 | 29 | ||
43 | static inline long syscall_get_return_value(struct task_struct *task, | 30 | 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, | |||
50 | struct pt_regs *regs, | 37 | struct pt_regs *regs, |
51 | int error, long val) | 38 | int error, long val) |
52 | { | 39 | { |
53 | if (error) { | 40 | if (error) |
54 | syscall_set_error(regs); | ||
55 | regs->regs[9] = -error; | 41 | regs->regs[9] = -error; |
56 | } else { | 42 | else |
57 | syscall_clear_error(regs); | ||
58 | regs->regs[9] = val; | 43 | regs->regs[9] = val; |
59 | } | ||
60 | } | 44 | } |
61 | 45 | ||
62 | static inline void syscall_get_arguments(struct task_struct *task, | 46 | 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, | |||
510 | case -ERESTARTNOHAND: | 510 | case -ERESTARTNOHAND: |
511 | no_system_call_restart: | 511 | no_system_call_restart: |
512 | regs->regs[0] = -EINTR; | 512 | regs->regs[0] = -EINTR; |
513 | regs->sr |= 1; | ||
514 | break; | 513 | break; |
515 | 514 | ||
516 | case -ERESTARTSYS: | 515 | case -ERESTARTSYS: |
@@ -589,8 +588,7 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0) | |||
589 | 588 | ||
590 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); | 589 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); |
591 | if (signr > 0) { | 590 | if (signr > 0) { |
592 | if (regs->sr & 1) | 591 | handle_syscall_restart(save_r0, regs, &ka.sa); |
593 | handle_syscall_restart(save_r0, regs, &ka.sa); | ||
594 | 592 | ||
595 | /* Whee! Actually deliver the signal. */ | 593 | /* Whee! Actually deliver the signal. */ |
596 | if (handle_signal(signr, &ka, &info, oldset, | 594 | 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) | |||
60 | case -ERESTARTNOHAND: | 60 | case -ERESTARTNOHAND: |
61 | no_system_call_restart: | 61 | no_system_call_restart: |
62 | regs->regs[REG_RET] = -EINTR; | 62 | regs->regs[REG_RET] = -EINTR; |
63 | regs->sr |= 1; | ||
64 | break; | 63 | break; |
65 | 64 | ||
66 | case -ERESTARTSYS: | 65 | case -ERESTARTSYS: |
@@ -109,8 +108,7 @@ static int do_signal(struct pt_regs *regs, sigset_t *oldset) | |||
109 | 108 | ||
110 | signr = get_signal_to_deliver(&info, &ka, regs, 0); | 109 | signr = get_signal_to_deliver(&info, &ka, regs, 0); |
111 | if (signr > 0) { | 110 | if (signr > 0) { |
112 | if (regs->sr & 1) | 111 | handle_syscall_restart(regs, &ka.sa); |
113 | handle_syscall_restart(regs, &ka.sa); | ||
114 | 112 | ||
115 | /* Whee! Actually deliver the signal. */ | 113 | /* Whee! Actually deliver the signal. */ |
116 | if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { | 114 | if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { |