aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/signal.c')
-rw-r--r--kernel/signal.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/kernel/signal.c b/kernel/signal.c
index dbd7fe073c55..825a3f24ad76 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -2735,3 +2735,43 @@ void __init signals_init(void)
2735{ 2735{
2736 sigqueue_cachep = KMEM_CACHE(sigqueue, SLAB_PANIC); 2736 sigqueue_cachep = KMEM_CACHE(sigqueue, SLAB_PANIC);
2737} 2737}
2738
2739#ifdef CONFIG_KGDB_KDB
2740#include <linux/kdb.h>
2741/*
2742 * kdb_send_sig_info - Allows kdb to send signals without exposing
2743 * signal internals. This function checks if the required locks are
2744 * available before calling the main signal code, to avoid kdb
2745 * deadlocks.
2746 */
2747void
2748kdb_send_sig_info(struct task_struct *t, struct siginfo *info)
2749{
2750 static struct task_struct *kdb_prev_t;
2751 int sig, new_t;
2752 if (!spin_trylock(&t->sighand->siglock)) {
2753 kdb_printf("Can't do kill command now.\n"
2754 "The sigmask lock is held somewhere else in "
2755 "kernel, try again later\n");
2756 return;
2757 }
2758 spin_unlock(&t->sighand->siglock);
2759 new_t = kdb_prev_t != t;
2760 kdb_prev_t = t;
2761 if (t->state != TASK_RUNNING && new_t) {
2762 kdb_printf("Process is not RUNNING, sending a signal from "
2763 "kdb risks deadlock\n"
2764 "on the run queue locks. "
2765 "The signal has _not_ been sent.\n"
2766 "Reissue the kill command if you want to risk "
2767 "the deadlock.\n");
2768 return;
2769 }
2770 sig = info->si_signo;
2771 if (send_sig_info(sig, info, t))
2772 kdb_printf("Fail to deliver Signal %d to process %d.\n",
2773 sig, t->pid);
2774 else
2775 kdb_printf("Signal %d is sent to process %d.\n", sig, t->pid);
2776}
2777#endif /* CONFIG_KGDB_KDB */