aboutsummaryrefslogtreecommitdiffstats
path: root/arch/openrisc/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/openrisc/kernel/signal.c')
-rw-r--r--arch/openrisc/kernel/signal.c47
1 files changed, 20 insertions, 27 deletions
diff --git a/arch/openrisc/kernel/signal.c b/arch/openrisc/kernel/signal.c
index 95207ab0c99..e970743251a 100644
--- a/arch/openrisc/kernel/signal.c
+++ b/arch/openrisc/kernel/signal.c
@@ -102,10 +102,7 @@ asmlinkage long _sys_rt_sigreturn(struct pt_regs *regs)
102 goto badframe; 102 goto badframe;
103 103
104 sigdelsetmask(&set, ~_BLOCKABLE); 104 sigdelsetmask(&set, ~_BLOCKABLE);
105 spin_lock_irq(&current->sighand->siglock); 105 set_current_blocked(&set);
106 current->blocked = set;
107 recalc_sigpending();
108 spin_unlock_irq(&current->sighand->siglock);
109 106
110 if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) 107 if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
111 goto badframe; 108 goto badframe;
@@ -189,8 +186,8 @@ static inline void __user *get_sigframe(struct k_sigaction *ka,
189 * trampoline which performs the syscall sigreturn, or a provided 186 * trampoline which performs the syscall sigreturn, or a provided
190 * user-mode trampoline. 187 * user-mode trampoline.
191 */ 188 */
192static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 189static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
193 sigset_t *set, struct pt_regs *regs) 190 sigset_t *set, struct pt_regs *regs)
194{ 191{
195 struct rt_sigframe *frame; 192 struct rt_sigframe *frame;
196 unsigned long return_ip; 193 unsigned long return_ip;
@@ -247,31 +244,27 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
247 /* actually move the usp to reflect the stacked frame */ 244 /* actually move the usp to reflect the stacked frame */
248 regs->sp = (unsigned long)frame; 245 regs->sp = (unsigned long)frame;
249 246
250 return; 247 return 0;
251 248
252give_sigsegv: 249give_sigsegv:
253 if (sig == SIGSEGV) 250 force_sigsegv(sig, current);
254 ka->sa.sa_handler = SIG_DFL; 251 return -EFAULT;
255 force_sig(SIGSEGV, current);
256} 252}
257 253
258static inline void 254static inline int
259handle_signal(unsigned long sig, 255handle_signal(unsigned long sig,
260 siginfo_t *info, struct k_sigaction *ka, 256 siginfo_t *info, struct k_sigaction *ka,
261 sigset_t *oldset, struct pt_regs *regs) 257 sigset_t *oldset, struct pt_regs *regs)
262{ 258{
263 setup_rt_frame(sig, ka, info, oldset, regs); 259 int ret;
264 260
265 if (ka->sa.sa_flags & SA_ONESHOT) 261 ret = setup_rt_frame(sig, ka, info, oldset, regs);
266 ka->sa.sa_handler = SIG_DFL; 262 if (ret)
263 return ret;
267 264
268 spin_lock_irq(&current->sighand->siglock); 265 block_sigmask(ka, sig);
269 sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
270 if (!(ka->sa.sa_flags & SA_NODEFER))
271 sigaddset(&current->blocked, sig);
272 recalc_sigpending();
273 266
274 spin_unlock_irq(&current->sighand->siglock); 267 return 0;
275} 268}
276 269
277/* 270/*
@@ -312,7 +305,7 @@ void do_signal(struct pt_regs *regs)
312 * below mean that the syscall executed to completion and no 305 * below mean that the syscall executed to completion and no
313 * restart is necessary. 306 * restart is necessary.
314 */ 307 */
315 if (regs->syscallno) { 308 if (regs->orig_gpr11) {
316 int restart = 0; 309 int restart = 0;
317 310
318 switch (regs->gpr[11]) { 311 switch (regs->gpr[11]) {
@@ -360,13 +353,13 @@ void do_signal(struct pt_regs *regs)
360 oldset = &current->blocked; 353 oldset = &current->blocked;
361 354
362 /* Whee! Actually deliver the signal. */ 355 /* Whee! Actually deliver the signal. */
363 handle_signal(signr, &info, &ka, oldset, regs); 356 if (!handle_signal(signr, &info, &ka, oldset, regs)) {
364 /* a signal was successfully delivered; the saved 357 /* a signal was successfully delivered; the saved
365 * sigmask will have been stored in the signal frame, 358 * sigmask will have been stored in the signal frame,
366 * and will be restored by sigreturn, so we can simply 359 * and will be restored by sigreturn, so we can simply
367 * clear the TIF_RESTORE_SIGMASK flag */ 360 * clear the TIF_RESTORE_SIGMASK flag */
368 if (test_thread_flag(TIF_RESTORE_SIGMASK))
369 clear_thread_flag(TIF_RESTORE_SIGMASK); 361 clear_thread_flag(TIF_RESTORE_SIGMASK);
362 }
370 363
371 tracehook_signal_handler(signr, &info, &ka, regs, 364 tracehook_signal_handler(signr, &info, &ka, regs,
372 test_thread_flag(TIF_SINGLESTEP)); 365 test_thread_flag(TIF_SINGLESTEP));