aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/signal.c')
-rw-r--r--kernel/signal.c63
1 files changed, 59 insertions, 4 deletions
diff --git a/kernel/signal.c b/kernel/signal.c
index e1d7ad8e6ab1..99fa8ff06fd9 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -688,6 +688,48 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, kernel_siginfo_t *in
688} 688}
689EXPORT_SYMBOL_GPL(dequeue_signal); 689EXPORT_SYMBOL_GPL(dequeue_signal);
690 690
691static int dequeue_synchronous_signal(kernel_siginfo_t *info)
692{
693 struct task_struct *tsk = current;
694 struct sigpending *pending = &tsk->pending;
695 struct sigqueue *q, *sync = NULL;
696
697 /*
698 * Might a synchronous signal be in the queue?
699 */
700 if (!((pending->signal.sig[0] & ~tsk->blocked.sig[0]) & SYNCHRONOUS_MASK))
701 return 0;
702
703 /*
704 * Return the first synchronous signal in the queue.
705 */
706 list_for_each_entry(q, &pending->list, list) {
707 /* Synchronous signals have a postive si_code */
708 if ((q->info.si_code > SI_USER) &&
709 (sigmask(q->info.si_signo) & SYNCHRONOUS_MASK)) {
710 sync = q;
711 goto next;
712 }
713 }
714 return 0;
715next:
716 /*
717 * Check if there is another siginfo for the same signal.
718 */
719 list_for_each_entry_continue(q, &pending->list, list) {
720 if (q->info.si_signo == sync->info.si_signo)
721 goto still_pending;
722 }
723
724 sigdelset(&pending->signal, sync->info.si_signo);
725 recalc_sigpending();
726still_pending:
727 list_del_init(&sync->list);
728 copy_siginfo(info, &sync->info);
729 __sigqueue_free(sync);
730 return info->si_signo;
731}
732
691/* 733/*
692 * Tell a process that it has a new active signal.. 734 * Tell a process that it has a new active signal..
693 * 735 *
@@ -1057,10 +1099,9 @@ static int __send_signal(int sig, struct kernel_siginfo *info, struct task_struc
1057 1099
1058 result = TRACE_SIGNAL_DELIVERED; 1100 result = TRACE_SIGNAL_DELIVERED;
1059 /* 1101 /*
1060 * Skip useless siginfo allocation for SIGKILL SIGSTOP, 1102 * Skip useless siginfo allocation for SIGKILL and kernel threads.
1061 * and kernel threads.
1062 */ 1103 */
1063 if (sig_kernel_only(sig) || (t->flags & PF_KTHREAD)) 1104 if ((sig == SIGKILL) || (t->flags & PF_KTHREAD))
1064 goto out_set; 1105 goto out_set;
1065 1106
1066 /* 1107 /*
@@ -2394,6 +2435,11 @@ relock:
2394 goto relock; 2435 goto relock;
2395 } 2436 }
2396 2437
2438 /* Has this task already been marked for death? */
2439 ksig->info.si_signo = signr = SIGKILL;
2440 if (signal_group_exit(signal))
2441 goto fatal;
2442
2397 for (;;) { 2443 for (;;) {
2398 struct k_sigaction *ka; 2444 struct k_sigaction *ka;
2399 2445
@@ -2407,7 +2453,15 @@ relock:
2407 goto relock; 2453 goto relock;
2408 } 2454 }
2409 2455
2410 signr = dequeue_signal(current, &current->blocked, &ksig->info); 2456 /*
2457 * Signals generated by the execution of an instruction
2458 * need to be delivered before any other pending signals
2459 * so that the instruction pointer in the signal stack
2460 * frame points to the faulting instruction.
2461 */
2462 signr = dequeue_synchronous_signal(&ksig->info);
2463 if (!signr)
2464 signr = dequeue_signal(current, &current->blocked, &ksig->info);
2411 2465
2412 if (!signr) 2466 if (!signr)
2413 break; /* will return 0 */ 2467 break; /* will return 0 */
@@ -2489,6 +2543,7 @@ relock:
2489 continue; 2543 continue;
2490 } 2544 }
2491 2545
2546 fatal:
2492 spin_unlock_irq(&sighand->siglock); 2547 spin_unlock_irq(&sighand->siglock);
2493 2548
2494 /* 2549 /*