diff options
author | Paul Mundt <lethal@linux-sh.org> | 2008-12-10 05:46:18 -0500 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2008-12-22 04:44:04 -0500 |
commit | 94e2fb3d3e1f4cb6bad2b13c572c4c99ad734a37 (patch) | |
tree | 7bfd32774ea72cbf0da11ed074dd449a31dbed0b /arch/sh/kernel/signal_64.c | |
parent | 6ac034375fe8b4341137657adf5e6ff0dcb5a99f (diff) |
sh: Provide asm/syscall.h for SH-5.
This provides the asm/syscall.h implementation for sh64 parts.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/kernel/signal_64.c')
-rw-r--r-- | arch/sh/kernel/signal_64.c | 63 |
1 files changed, 33 insertions, 30 deletions
diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c index 08828ddd97ff..b22fdfaaa191 100644 --- a/arch/sh/kernel/signal_64.c +++ b/arch/sh/kernel/signal_64.c | |||
@@ -47,6 +47,34 @@ static int | |||
47 | handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, | 47 | handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, |
48 | sigset_t *oldset, struct pt_regs * regs); | 48 | sigset_t *oldset, struct pt_regs * regs); |
49 | 49 | ||
50 | static inline void | ||
51 | handle_syscall_restart(struct pt_regs *regs, struct sigaction *sa) | ||
52 | { | ||
53 | /* If we're not from a syscall, bail out */ | ||
54 | if (regs->syscall_nr < 0) | ||
55 | return; | ||
56 | |||
57 | /* check for system call restart.. */ | ||
58 | switch (regs->regs[REG_RET]) { | ||
59 | case -ERESTART_RESTARTBLOCK: | ||
60 | case -ERESTARTNOHAND: | ||
61 | no_system_call_restart: | ||
62 | regs->regs[REG_RET] = -EINTR; | ||
63 | regs->sr |= 1; | ||
64 | break; | ||
65 | |||
66 | case -ERESTARTSYS: | ||
67 | if (!(sa->sa_flags & SA_RESTART)) | ||
68 | goto no_system_call_restart; | ||
69 | /* fallthrough */ | ||
70 | case -ERESTARTNOINTR: | ||
71 | /* Decode syscall # */ | ||
72 | regs->regs[REG_RET] = regs->syscall_nr; | ||
73 | regs->pc -= 4; | ||
74 | break; | ||
75 | } | ||
76 | } | ||
77 | |||
50 | /* | 78 | /* |
51 | * Note that 'init' is a special process: it doesn't get signals it doesn't | 79 | * Note that 'init' is a special process: it doesn't get signals it doesn't |
52 | * want to handle. Thus you cannot kill init even with a SIGKILL even by | 80 | * want to handle. Thus you cannot kill init even with a SIGKILL even by |
@@ -81,6 +109,9 @@ static int do_signal(struct pt_regs *regs, sigset_t *oldset) | |||
81 | 109 | ||
82 | signr = get_signal_to_deliver(&info, &ka, regs, 0); | 110 | signr = get_signal_to_deliver(&info, &ka, regs, 0); |
83 | if (signr > 0) { | 111 | if (signr > 0) { |
112 | if (regs->sr & 1) | ||
113 | handle_syscall_restart(regs, &ka.sa); | ||
114 | |||
84 | /* Whee! Actually deliver the signal. */ | 115 | /* Whee! Actually deliver the signal. */ |
85 | if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { | 116 | if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { |
86 | /* | 117 | /* |
@@ -128,7 +159,6 @@ no_signal: | |||
128 | /* | 159 | /* |
129 | * Atomically swap in the new signal mask, and wait for a signal. | 160 | * Atomically swap in the new signal mask, and wait for a signal. |
130 | */ | 161 | */ |
131 | |||
132 | asmlinkage int | 162 | asmlinkage int |
133 | sys_sigsuspend(old_sigset_t mask, | 163 | sys_sigsuspend(old_sigset_t mask, |
134 | unsigned long r3, unsigned long r4, unsigned long r5, | 164 | unsigned long r3, unsigned long r4, unsigned long r5, |
@@ -234,20 +264,16 @@ sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, | |||
234 | return do_sigaltstack(uss, uoss, REF_REG_SP); | 264 | return do_sigaltstack(uss, uoss, REF_REG_SP); |
235 | } | 265 | } |
236 | 266 | ||
237 | |||
238 | /* | 267 | /* |
239 | * Do a signal return; undo the signal stack. | 268 | * Do a signal return; undo the signal stack. |
240 | */ | 269 | */ |
241 | 270 | struct sigframe { | |
242 | struct sigframe | ||
243 | { | ||
244 | struct sigcontext sc; | 271 | struct sigcontext sc; |
245 | unsigned long extramask[_NSIG_WORDS-1]; | 272 | unsigned long extramask[_NSIG_WORDS-1]; |
246 | long long retcode[2]; | 273 | long long retcode[2]; |
247 | }; | 274 | }; |
248 | 275 | ||
249 | struct rt_sigframe | 276 | struct rt_sigframe { |
250 | { | ||
251 | struct siginfo __user *pinfo; | 277 | struct siginfo __user *pinfo; |
252 | void *puc; | 278 | void *puc; |
253 | struct siginfo info; | 279 | struct siginfo info; |
@@ -449,7 +475,6 @@ badframe: | |||
449 | /* | 475 | /* |
450 | * Set up a signal frame. | 476 | * Set up a signal frame. |
451 | */ | 477 | */ |
452 | |||
453 | static int | 478 | static int |
454 | setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, | 479 | setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, |
455 | unsigned long mask) | 480 | unsigned long mask) |
@@ -714,34 +739,12 @@ give_sigsegv: | |||
714 | /* | 739 | /* |
715 | * OK, we're invoking a handler | 740 | * OK, we're invoking a handler |
716 | */ | 741 | */ |
717 | |||
718 | static int | 742 | static int |
719 | handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, | 743 | handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, |
720 | sigset_t *oldset, struct pt_regs * regs) | 744 | sigset_t *oldset, struct pt_regs * regs) |
721 | { | 745 | { |
722 | int ret; | 746 | int ret; |
723 | 747 | ||
724 | /* Are we from a system call? */ | ||
725 | if (regs->syscall_nr >= 0) { | ||
726 | /* If so, check system call restarting.. */ | ||
727 | switch (regs->regs[REG_RET]) { | ||
728 | case -ERESTART_RESTARTBLOCK: | ||
729 | case -ERESTARTNOHAND: | ||
730 | no_system_call_restart: | ||
731 | regs->regs[REG_RET] = -EINTR; | ||
732 | break; | ||
733 | |||
734 | case -ERESTARTSYS: | ||
735 | if (!(ka->sa.sa_flags & SA_RESTART)) | ||
736 | goto no_system_call_restart; | ||
737 | /* fallthrough */ | ||
738 | case -ERESTARTNOINTR: | ||
739 | /* Decode syscall # */ | ||
740 | regs->regs[REG_RET] = regs->syscall_nr; | ||
741 | regs->pc -= 4; | ||
742 | } | ||
743 | } | ||
744 | |||
745 | /* Set up the stack frame */ | 748 | /* Set up the stack frame */ |
746 | if (ka->sa.sa_flags & SA_SIGINFO) | 749 | if (ka->sa.sa_flags & SA_SIGINFO) |
747 | ret = setup_rt_frame(sig, ka, info, oldset, regs); | 750 | ret = setup_rt_frame(sig, ka, info, oldset, regs); |