aboutsummaryrefslogtreecommitdiffstats
path: root/arch/tile/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/tile/kernel/signal.c')
-rw-r--r--arch/tile/kernel/signal.c20
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
55int restore_sigcontext(struct pt_regs *regs, 54int 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. */
81SYSCALL_DEFINE1(rt_sigreturn, struct pt_regs *, regs) 82SYSCALL_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(&current->sighand->siglock); 97 spin_unlock_irq(&current->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
107badframe: 107badframe:
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, &current->saved_sigmask, NULL); 359 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
360 } 360 }
361
362done:
363 /* Avoid double syscall restart if there are nested signals. */
364 regs->faultnum = INT_SWINT_1_SIGRETURN;
361} 365}