diff options
Diffstat (limited to 'arch/tile/kernel/signal.c')
-rw-r--r-- | arch/tile/kernel/signal.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/arch/tile/kernel/signal.c b/arch/tile/kernel/signal.c index fb28e85ae3ae..1260321155f1 100644 --- a/arch/tile/kernel/signal.c +++ b/arch/tile/kernel/signal.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/sched.h> | 16 | #include <linux/sched.h> |
17 | #include <linux/mm.h> | 17 | #include <linux/mm.h> |
18 | #include <linux/smp.h> | 18 | #include <linux/smp.h> |
19 | #include <linux/smp_lock.h> | ||
20 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
21 | #include <linux/signal.h> | 20 | #include <linux/signal.h> |
22 | #include <linux/errno.h> | 21 | #include <linux/errno.h> |
@@ -53,7 +52,7 @@ SYSCALL_DEFINE3(sigaltstack, const stack_t __user *, uss, | |||
53 | */ | 52 | */ |
54 | 53 | ||
55 | int restore_sigcontext(struct pt_regs *regs, | 54 | int restore_sigcontext(struct pt_regs *regs, |
56 | struct sigcontext __user *sc, long *pr0) | 55 | struct sigcontext __user *sc) |
57 | { | 56 | { |
58 | int err = 0; | 57 | int err = 0; |
59 | int i; | 58 | int i; |
@@ -71,19 +70,20 @@ int restore_sigcontext(struct pt_regs *regs, | |||
71 | for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i) | 70 | for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i) |
72 | err |= __get_user(regs->regs[i], &sc->gregs[i]); | 71 | err |= __get_user(regs->regs[i], &sc->gregs[i]); |
73 | 72 | ||
73 | /* Ensure that the PL is always set to USER_PL. */ | ||
74 | regs->ex1 = PL_ICS_EX1(USER_PL, EX1_ICS(regs->ex1)); | ||
75 | |||
74 | regs->faultnum = INT_SWINT_1_SIGRETURN; | 76 | regs->faultnum = INT_SWINT_1_SIGRETURN; |
75 | 77 | ||
76 | err |= __get_user(*pr0, &sc->gregs[0]); | ||
77 | return err; | 78 | return err; |
78 | } | 79 | } |
79 | 80 | ||
80 | /* sigreturn() returns long since it restores r0 in the interrupted code. */ | 81 | /* The assembly shim for this function arranges to ignore the return value. */ |
81 | SYSCALL_DEFINE1(rt_sigreturn, struct pt_regs *, regs) | 82 | SYSCALL_DEFINE1(rt_sigreturn, struct pt_regs *, regs) |
82 | { | 83 | { |
83 | struct rt_sigframe __user *frame = | 84 | struct rt_sigframe __user *frame = |
84 | (struct rt_sigframe __user *)(regs->sp); | 85 | (struct rt_sigframe __user *)(regs->sp); |
85 | sigset_t set; | 86 | sigset_t set; |
86 | long r0; | ||
87 | 87 | ||
88 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) | 88 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) |
89 | goto badframe; | 89 | goto badframe; |
@@ -96,13 +96,13 @@ SYSCALL_DEFINE1(rt_sigreturn, struct pt_regs *, regs) | |||
96 | recalc_sigpending(); | 96 | recalc_sigpending(); |
97 | spin_unlock_irq(¤t->sighand->siglock); | 97 | spin_unlock_irq(¤t->sighand->siglock); |
98 | 98 | ||
99 | if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0)) | 99 | if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) |
100 | goto badframe; | 100 | goto badframe; |
101 | 101 | ||
102 | if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->sp) == -EFAULT) | 102 | if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->sp) == -EFAULT) |
103 | goto badframe; | 103 | goto badframe; |
104 | 104 | ||
105 | return r0; | 105 | return 0; |
106 | 106 | ||
107 | badframe: | 107 | badframe: |
108 | force_sig(SIGSEGV, current); | 108 | force_sig(SIGSEGV, current); |
@@ -330,7 +330,7 @@ void do_signal(struct pt_regs *regs) | |||
330 | current_thread_info()->status &= ~TS_RESTORE_SIGMASK; | 330 | current_thread_info()->status &= ~TS_RESTORE_SIGMASK; |
331 | } | 331 | } |
332 | 332 | ||
333 | return; | 333 | goto done; |
334 | } | 334 | } |
335 | 335 | ||
336 | /* Did we come from a system call? */ | 336 | /* Did we come from a system call? */ |
@@ -358,4 +358,8 @@ void do_signal(struct pt_regs *regs) | |||
358 | current_thread_info()->status &= ~TS_RESTORE_SIGMASK; | 358 | current_thread_info()->status &= ~TS_RESTORE_SIGMASK; |
359 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); | 359 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); |
360 | } | 360 | } |
361 | |||
362 | done: | ||
363 | /* Avoid double syscall restart if there are nested signals. */ | ||
364 | regs->faultnum = INT_SWINT_1_SIGRETURN; | ||
361 | } | 365 | } |