diff options
Diffstat (limited to 'arch/sparc/kernel/signal_64.c')
-rw-r--r-- | arch/sparc/kernel/signal_64.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c index 35923e8abd82..cd91d010e6d3 100644 --- a/arch/sparc/kernel/signal_64.c +++ b/arch/sparc/kernel/signal_64.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/tty.h> | 23 | #include <linux/tty.h> |
24 | #include <linux/binfmts.h> | 24 | #include <linux/binfmts.h> |
25 | #include <linux/bitops.h> | 25 | #include <linux/bitops.h> |
26 | #include <linux/context_tracking.h> | ||
26 | 27 | ||
27 | #include <asm/uaccess.h> | 28 | #include <asm/uaccess.h> |
28 | #include <asm/ptrace.h> | 29 | #include <asm/ptrace.h> |
@@ -43,6 +44,7 @@ asmlinkage void sparc64_set_context(struct pt_regs *regs) | |||
43 | { | 44 | { |
44 | struct ucontext __user *ucp = (struct ucontext __user *) | 45 | struct ucontext __user *ucp = (struct ucontext __user *) |
45 | regs->u_regs[UREG_I0]; | 46 | regs->u_regs[UREG_I0]; |
47 | enum ctx_state prev_state = exception_enter(); | ||
46 | mc_gregset_t __user *grp; | 48 | mc_gregset_t __user *grp; |
47 | unsigned long pc, npc, tstate; | 49 | unsigned long pc, npc, tstate; |
48 | unsigned long fp, i7; | 50 | unsigned long fp, i7; |
@@ -129,16 +131,19 @@ asmlinkage void sparc64_set_context(struct pt_regs *regs) | |||
129 | } | 131 | } |
130 | if (err) | 132 | if (err) |
131 | goto do_sigsegv; | 133 | goto do_sigsegv; |
132 | 134 | out: | |
135 | exception_exit(prev_state); | ||
133 | return; | 136 | return; |
134 | do_sigsegv: | 137 | do_sigsegv: |
135 | force_sig(SIGSEGV, current); | 138 | force_sig(SIGSEGV, current); |
139 | goto out; | ||
136 | } | 140 | } |
137 | 141 | ||
138 | asmlinkage void sparc64_get_context(struct pt_regs *regs) | 142 | asmlinkage void sparc64_get_context(struct pt_regs *regs) |
139 | { | 143 | { |
140 | struct ucontext __user *ucp = (struct ucontext __user *) | 144 | struct ucontext __user *ucp = (struct ucontext __user *) |
141 | regs->u_regs[UREG_I0]; | 145 | regs->u_regs[UREG_I0]; |
146 | enum ctx_state prev_state = exception_enter(); | ||
142 | mc_gregset_t __user *grp; | 147 | mc_gregset_t __user *grp; |
143 | mcontext_t __user *mcp; | 148 | mcontext_t __user *mcp; |
144 | unsigned long fp, i7; | 149 | unsigned long fp, i7; |
@@ -220,10 +225,12 @@ asmlinkage void sparc64_get_context(struct pt_regs *regs) | |||
220 | } | 225 | } |
221 | if (err) | 226 | if (err) |
222 | goto do_sigsegv; | 227 | goto do_sigsegv; |
223 | 228 | out: | |
229 | exception_exit(prev_state); | ||
224 | return; | 230 | return; |
225 | do_sigsegv: | 231 | do_sigsegv: |
226 | force_sig(SIGSEGV, current); | 232 | force_sig(SIGSEGV, current); |
233 | goto out; | ||
227 | } | 234 | } |
228 | 235 | ||
229 | struct rt_signal_frame { | 236 | struct rt_signal_frame { |
@@ -528,11 +535,13 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) | |||
528 | 535 | ||
529 | void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long thread_info_flags) | 536 | void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long thread_info_flags) |
530 | { | 537 | { |
538 | user_exit(); | ||
531 | if (thread_info_flags & _TIF_SIGPENDING) | 539 | if (thread_info_flags & _TIF_SIGPENDING) |
532 | do_signal(regs, orig_i0); | 540 | do_signal(regs, orig_i0); |
533 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { | 541 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { |
534 | clear_thread_flag(TIF_NOTIFY_RESUME); | 542 | clear_thread_flag(TIF_NOTIFY_RESUME); |
535 | tracehook_notify_resume(regs); | 543 | tracehook_notify_resume(regs); |
536 | } | 544 | } |
545 | user_enter(); | ||
537 | } | 546 | } |
538 | 547 | ||