aboutsummaryrefslogtreecommitdiffstats
path: root/arch/frv
diff options
context:
space:
mode:
Diffstat (limited to 'arch/frv')
-rw-r--r--arch/frv/kernel/entry.S2
-rw-r--r--arch/frv/kernel/signal.c73
2 files changed, 46 insertions, 29 deletions
diff --git a/arch/frv/kernel/entry.S b/arch/frv/kernel/entry.S
index ad10ea595459..5f6548388b74 100644
--- a/arch/frv/kernel/entry.S
+++ b/arch/frv/kernel/entry.S
@@ -1076,7 +1076,7 @@ __entry_work_notifysig:
1076 LEDS 0x6410 1076 LEDS 0x6410
1077 ori.p gr4,#0,gr8 1077 ori.p gr4,#0,gr8
1078 call do_notify_resume 1078 call do_notify_resume
1079 bra __entry_return_direct 1079 bra __entry_resume_userspace
1080 1080
1081 # perform syscall entry tracing 1081 # perform syscall entry tracing
1082__syscall_trace_entry: 1082__syscall_trace_entry:
diff --git a/arch/frv/kernel/signal.c b/arch/frv/kernel/signal.c
index d4ccc0728dfe..89a1cf5c076a 100644
--- a/arch/frv/kernel/signal.c
+++ b/arch/frv/kernel/signal.c
@@ -297,7 +297,8 @@ static inline void __user *get_sigframe(struct k_sigaction *ka,
297/* 297/*
298 * 298 *
299 */ 299 */
300static void setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, struct pt_regs * regs) 300static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
301 struct pt_regs *regs)
301{ 302{
302 struct sigframe __user *frame; 303 struct sigframe __user *frame;
303 int rsig; 304 int rsig;
@@ -362,26 +363,30 @@ static void setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, struct p
362 363
363 set_fs(USER_DS); 364 set_fs(USER_DS);
364 365
366 /* the tracer may want to single-step inside the handler */
367 if (test_thread_flag(TIF_SINGLESTEP))
368 ptrace_notify(SIGTRAP);
369
365#if DEBUG_SIG 370#if DEBUG_SIG
366 printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n", 371 printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
367 sig, current->comm, current->pid, frame, regs->pc, frame->pretcode); 372 sig, current->comm, current->pid, frame, regs->pc,
373 frame->pretcode);
368#endif 374#endif
369 375
370 return; 376 return 1;
371 377
372give_sigsegv: 378give_sigsegv:
373 if (sig == SIGSEGV)
374 ka->sa.sa_handler = SIG_DFL;
375
376 force_sig(SIGSEGV, current); 379 force_sig(SIGSEGV, current);
380 return 0;
381
377} /* end setup_frame() */ 382} /* end setup_frame() */
378 383
379/*****************************************************************************/ 384/*****************************************************************************/
380/* 385/*
381 * 386 *
382 */ 387 */
383static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 388static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
384 sigset_t *set, struct pt_regs * regs) 389 sigset_t *set, struct pt_regs * regs)
385{ 390{
386 struct rt_sigframe __user *frame; 391 struct rt_sigframe __user *frame;
387 int rsig; 392 int rsig;
@@ -457,17 +462,21 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
457 462
458 set_fs(USER_DS); 463 set_fs(USER_DS);
459 464
465 /* the tracer may want to single-step inside the handler */
466 if (test_thread_flag(TIF_SINGLESTEP))
467 ptrace_notify(SIGTRAP);
468
460#if DEBUG_SIG 469#if DEBUG_SIG
461 printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n", 470 printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
462 sig, current->comm, current->pid, frame, regs->pc, frame->pretcode); 471 sig, current->comm, current->pid, frame, regs->pc,
472 frame->pretcode);
463#endif 473#endif
464 474
465 return; 475 return 1;
466 476
467give_sigsegv: 477give_sigsegv:
468 if (sig == SIGSEGV)
469 ka->sa.sa_handler = SIG_DFL;
470 force_sig(SIGSEGV, current); 478 force_sig(SIGSEGV, current);
479 return 0;
471 480
472} /* end setup_rt_frame() */ 481} /* end setup_rt_frame() */
473 482
@@ -475,10 +484,12 @@ give_sigsegv:
475/* 484/*
476 * OK, we're invoking a handler 485 * OK, we're invoking a handler
477 */ 486 */
478static void handle_signal(unsigned long sig, siginfo_t *info, 487static int handle_signal(unsigned long sig, siginfo_t *info,
479 struct k_sigaction *ka, sigset_t *oldset, 488 struct k_sigaction *ka, sigset_t *oldset,
480 struct pt_regs *regs) 489 struct pt_regs *regs)
481{ 490{
491 int ret;
492
482 /* Are we from a system call? */ 493 /* Are we from a system call? */
483 if (in_syscall(regs)) { 494 if (in_syscall(regs)) {
484 /* If so, check system call restarting.. */ 495 /* If so, check system call restarting.. */
@@ -493,6 +504,7 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
493 regs->gr8 = -EINTR; 504 regs->gr8 = -EINTR;
494 break; 505 break;
495 } 506 }
507
496 /* fallthrough */ 508 /* fallthrough */
497 case -ERESTARTNOINTR: 509 case -ERESTARTNOINTR:
498 regs->gr8 = regs->orig_gr8; 510 regs->gr8 = regs->orig_gr8;
@@ -502,16 +514,22 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
502 514
503 /* Set up the stack frame */ 515 /* Set up the stack frame */
504 if (ka->sa.sa_flags & SA_SIGINFO) 516 if (ka->sa.sa_flags & SA_SIGINFO)
505 setup_rt_frame(sig, ka, info, oldset, regs); 517 ret = setup_rt_frame(sig, ka, info, oldset, regs);
506 else 518 else
507 setup_frame(sig, ka, oldset, regs); 519 ret = setup_frame(sig, ka, oldset, regs);
520
521 if (ret) {
522 spin_lock_irq(&current->sighand->siglock);
523 sigorsets(&current->blocked, &current->blocked,
524 &ka->sa.sa_mask);
525 if (!(ka->sa.sa_flags & SA_NODEFER))
526 sigaddset(&current->blocked, sig);
527 recalc_sigpending();
528 spin_unlock_irq(&current->sighand->siglock);
529 }
530
531 return ret;
508 532
509 spin_lock_irq(&current->sighand->siglock);
510 sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
511 if (!(ka->sa.sa_flags & SA_NODEFER))
512 sigaddset(&current->blocked, sig);
513 recalc_sigpending();
514 spin_unlock_irq(&current->sighand->siglock);
515} /* end handle_signal() */ 533} /* end handle_signal() */
516 534
517/*****************************************************************************/ 535/*****************************************************************************/
@@ -542,12 +560,10 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
542 oldset = &current->blocked; 560 oldset = &current->blocked;
543 561
544 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 562 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
545 if (signr > 0) { 563 if (signr > 0)
546 handle_signal(signr, &info, &ka, oldset, regs); 564 return handle_signal(signr, &info, &ka, oldset, regs);
547 return 1;
548 }
549 565
550 no_signal: 566no_signal:
551 /* Did we come from a system call? */ 567 /* Did we come from a system call? */
552 if (regs->syscallno >= 0) { 568 if (regs->syscallno >= 0) {
553 /* Restart the system call - no handlers present */ 569 /* Restart the system call - no handlers present */
@@ -565,6 +581,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
565 } 581 }
566 582
567 return 0; 583 return 0;
584
568} /* end do_signal() */ 585} /* end do_signal() */
569 586
570/*****************************************************************************/ 587/*****************************************************************************/