diff options
-rw-r--r-- | arch/arm/include/asm/kmap_types.h | 1 | ||||
-rw-r--r-- | arch/powerpc/include/asm/kmap_types.h | 1 | ||||
-rw-r--r-- | include/asm-generic/kmap_types.h | 3 | ||||
-rw-r--r-- | init/main.c | 2 | ||||
-rw-r--r-- | kernel/kallsyms.c | 21 | ||||
-rw-r--r-- | kernel/module.c | 4 | ||||
-rw-r--r-- | kernel/printk.c | 16 | ||||
-rw-r--r-- | kernel/sched.c | 7 | ||||
-rw-r--r-- | kernel/signal.c | 40 |
9 files changed, 92 insertions, 3 deletions
diff --git a/arch/arm/include/asm/kmap_types.h b/arch/arm/include/asm/kmap_types.h index c4b2ea3fbe42..e51b1e81df05 100644 --- a/arch/arm/include/asm/kmap_types.h +++ b/arch/arm/include/asm/kmap_types.h | |||
@@ -20,6 +20,7 @@ enum km_type { | |||
20 | KM_SOFTIRQ1, | 20 | KM_SOFTIRQ1, |
21 | KM_L1_CACHE, | 21 | KM_L1_CACHE, |
22 | KM_L2_CACHE, | 22 | KM_L2_CACHE, |
23 | KM_KDB, | ||
23 | KM_TYPE_NR | 24 | KM_TYPE_NR |
24 | }; | 25 | }; |
25 | 26 | ||
diff --git a/arch/powerpc/include/asm/kmap_types.h b/arch/powerpc/include/asm/kmap_types.h index 916369575c97..bca8fdcd2542 100644 --- a/arch/powerpc/include/asm/kmap_types.h +++ b/arch/powerpc/include/asm/kmap_types.h | |||
@@ -26,6 +26,7 @@ enum km_type { | |||
26 | KM_SOFTIRQ1, | 26 | KM_SOFTIRQ1, |
27 | KM_PPC_SYNC_PAGE, | 27 | KM_PPC_SYNC_PAGE, |
28 | KM_PPC_SYNC_ICACHE, | 28 | KM_PPC_SYNC_ICACHE, |
29 | KM_KDB, | ||
29 | KM_TYPE_NR | 30 | KM_TYPE_NR |
30 | }; | 31 | }; |
31 | 32 | ||
diff --git a/include/asm-generic/kmap_types.h b/include/asm-generic/kmap_types.h index e5f234a08540..97e807c8c812 100644 --- a/include/asm-generic/kmap_types.h +++ b/include/asm-generic/kmap_types.h | |||
@@ -28,7 +28,8 @@ KMAP_D(15) KM_UML_USERCOPY, | |||
28 | KMAP_D(16) KM_IRQ_PTE, | 28 | KMAP_D(16) KM_IRQ_PTE, |
29 | KMAP_D(17) KM_NMI, | 29 | KMAP_D(17) KM_NMI, |
30 | KMAP_D(18) KM_NMI_PTE, | 30 | KMAP_D(18) KM_NMI_PTE, |
31 | KMAP_D(19) KM_TYPE_NR | 31 | KMAP_D(19) KM_KDB, |
32 | KMAP_D(20) KM_TYPE_NR | ||
32 | }; | 33 | }; |
33 | 34 | ||
34 | #undef KMAP_D | 35 | #undef KMAP_D |
diff --git a/init/main.c b/init/main.c index 5c8540271529..372771333d98 100644 --- a/init/main.c +++ b/init/main.c | |||
@@ -62,6 +62,7 @@ | |||
62 | #include <linux/sched.h> | 62 | #include <linux/sched.h> |
63 | #include <linux/signal.h> | 63 | #include <linux/signal.h> |
64 | #include <linux/idr.h> | 64 | #include <linux/idr.h> |
65 | #include <linux/kdb.h> | ||
65 | #include <linux/ftrace.h> | 66 | #include <linux/ftrace.h> |
66 | #include <linux/async.h> | 67 | #include <linux/async.h> |
67 | #include <linux/kmemcheck.h> | 68 | #include <linux/kmemcheck.h> |
@@ -675,6 +676,7 @@ asmlinkage void __init start_kernel(void) | |||
675 | buffer_init(); | 676 | buffer_init(); |
676 | key_init(); | 677 | key_init(); |
677 | security_init(); | 678 | security_init(); |
679 | kdb_init(KDB_INIT_FULL); | ||
678 | vfs_caches_init(totalram_pages); | 680 | vfs_caches_init(totalram_pages); |
679 | signals_init(); | 681 | signals_init(); |
680 | /* rootfs populating might need page-writeback */ | 682 | /* rootfs populating might need page-writeback */ |
diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c index 13aff293f4de..6f6d091b5757 100644 --- a/kernel/kallsyms.c +++ b/kernel/kallsyms.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/seq_file.h> | 17 | #include <linux/seq_file.h> |
18 | #include <linux/fs.h> | 18 | #include <linux/fs.h> |
19 | #include <linux/kdb.h> | ||
19 | #include <linux/err.h> | 20 | #include <linux/err.h> |
20 | #include <linux/proc_fs.h> | 21 | #include <linux/proc_fs.h> |
21 | #include <linux/sched.h> /* for cond_resched */ | 22 | #include <linux/sched.h> /* for cond_resched */ |
@@ -516,6 +517,26 @@ static int kallsyms_open(struct inode *inode, struct file *file) | |||
516 | return ret; | 517 | return ret; |
517 | } | 518 | } |
518 | 519 | ||
520 | #ifdef CONFIG_KGDB_KDB | ||
521 | const char *kdb_walk_kallsyms(loff_t *pos) | ||
522 | { | ||
523 | static struct kallsym_iter kdb_walk_kallsyms_iter; | ||
524 | if (*pos == 0) { | ||
525 | memset(&kdb_walk_kallsyms_iter, 0, | ||
526 | sizeof(kdb_walk_kallsyms_iter)); | ||
527 | reset_iter(&kdb_walk_kallsyms_iter, 0); | ||
528 | } | ||
529 | while (1) { | ||
530 | if (!update_iter(&kdb_walk_kallsyms_iter, *pos)) | ||
531 | return NULL; | ||
532 | ++*pos; | ||
533 | /* Some debugging symbols have no name. Ignore them. */ | ||
534 | if (kdb_walk_kallsyms_iter.name[0]) | ||
535 | return kdb_walk_kallsyms_iter.name; | ||
536 | } | ||
537 | } | ||
538 | #endif /* CONFIG_KGDB_KDB */ | ||
539 | |||
519 | static const struct file_operations kallsyms_operations = { | 540 | static const struct file_operations kallsyms_operations = { |
520 | .open = kallsyms_open, | 541 | .open = kallsyms_open, |
521 | .read = seq_read, | 542 | .read = seq_read, |
diff --git a/kernel/module.c b/kernel/module.c index e2564580f3f1..b751f1902476 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -77,6 +77,10 @@ | |||
77 | DEFINE_MUTEX(module_mutex); | 77 | DEFINE_MUTEX(module_mutex); |
78 | EXPORT_SYMBOL_GPL(module_mutex); | 78 | EXPORT_SYMBOL_GPL(module_mutex); |
79 | static LIST_HEAD(modules); | 79 | static LIST_HEAD(modules); |
80 | #ifdef CONFIG_KGDB_KDB | ||
81 | struct list_head *kdb_modules = &modules; /* kdb needs the list of modules */ | ||
82 | #endif /* CONFIG_KGDB_KDB */ | ||
83 | |||
80 | 84 | ||
81 | /* Block module loading/unloading? */ | 85 | /* Block module loading/unloading? */ |
82 | int modules_disabled = 0; | 86 | int modules_disabled = 0; |
diff --git a/kernel/printk.c b/kernel/printk.c index 75077ad0b537..9213b8b5bb4f 100644 --- a/kernel/printk.c +++ b/kernel/printk.c | |||
@@ -413,6 +413,22 @@ SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len) | |||
413 | return do_syslog(type, buf, len, SYSLOG_FROM_CALL); | 413 | return do_syslog(type, buf, len, SYSLOG_FROM_CALL); |
414 | } | 414 | } |
415 | 415 | ||
416 | #ifdef CONFIG_KGDB_KDB | ||
417 | /* kdb dmesg command needs access to the syslog buffer. do_syslog() | ||
418 | * uses locks so it cannot be used during debugging. Just tell kdb | ||
419 | * where the start and end of the physical and logical logs are. This | ||
420 | * is equivalent to do_syslog(3). | ||
421 | */ | ||
422 | void kdb_syslog_data(char *syslog_data[4]) | ||
423 | { | ||
424 | syslog_data[0] = log_buf; | ||
425 | syslog_data[1] = log_buf + log_buf_len; | ||
426 | syslog_data[2] = log_buf + log_end - | ||
427 | (logged_chars < log_buf_len ? logged_chars : log_buf_len); | ||
428 | syslog_data[3] = log_buf + log_end; | ||
429 | } | ||
430 | #endif /* CONFIG_KGDB_KDB */ | ||
431 | |||
416 | /* | 432 | /* |
417 | * Call the console drivers on a range of log_buf | 433 | * Call the console drivers on a range of log_buf |
418 | */ | 434 | */ |
diff --git a/kernel/sched.c b/kernel/sched.c index 1d93cd0ae4d3..a25c1324af54 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -7758,9 +7758,9 @@ void normalize_rt_tasks(void) | |||
7758 | 7758 | ||
7759 | #endif /* CONFIG_MAGIC_SYSRQ */ | 7759 | #endif /* CONFIG_MAGIC_SYSRQ */ |
7760 | 7760 | ||
7761 | #ifdef CONFIG_IA64 | 7761 | #if defined(CONFIG_IA64) || defined(CONFIG_KGDB_KDB) |
7762 | /* | 7762 | /* |
7763 | * These functions are only useful for the IA64 MCA handling. | 7763 | * These functions are only useful for the IA64 MCA handling, or kdb. |
7764 | * | 7764 | * |
7765 | * They can only be called when the whole system has been | 7765 | * They can only be called when the whole system has been |
7766 | * stopped - every CPU needs to be quiescent, and no scheduling | 7766 | * stopped - every CPU needs to be quiescent, and no scheduling |
@@ -7780,6 +7780,9 @@ struct task_struct *curr_task(int cpu) | |||
7780 | return cpu_curr(cpu); | 7780 | return cpu_curr(cpu); |
7781 | } | 7781 | } |
7782 | 7782 | ||
7783 | #endif /* defined(CONFIG_IA64) || defined(CONFIG_KGDB_KDB) */ | ||
7784 | |||
7785 | #ifdef CONFIG_IA64 | ||
7783 | /** | 7786 | /** |
7784 | * set_curr_task - set the current task for a given cpu. | 7787 | * set_curr_task - set the current task for a given cpu. |
7785 | * @cpu: the processor in question. | 7788 | * @cpu: the processor in question. |
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 | */ | ||
2747 | void | ||
2748 | kdb_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 */ | ||