diff options
Diffstat (limited to 'kernel/debug')
-rw-r--r-- | kernel/debug/debug_core.c | 52 | ||||
-rw-r--r-- | kernel/debug/kdb/kdb_bp.c | 37 | ||||
-rw-r--r-- | kernel/debug/kdb/kdb_debugger.c | 4 | ||||
-rw-r--r-- | kernel/debug/kdb/kdb_main.c | 269 | ||||
-rw-r--r-- | kernel/debug/kdb/kdb_private.h | 3 |
5 files changed, 227 insertions, 138 deletions
diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c index 1adf62b39b96..07ce18ca71e0 100644 --- a/kernel/debug/debug_core.c +++ b/kernel/debug/debug_core.c | |||
@@ -27,6 +27,9 @@ | |||
27 | * version 2. This program is licensed "as is" without any warranty of any | 27 | * version 2. This program is licensed "as is" without any warranty of any |
28 | * kind, whether express or implied. | 28 | * kind, whether express or implied. |
29 | */ | 29 | */ |
30 | |||
31 | #define pr_fmt(fmt) "KGDB: " fmt | ||
32 | |||
30 | #include <linux/pid_namespace.h> | 33 | #include <linux/pid_namespace.h> |
31 | #include <linux/clocksource.h> | 34 | #include <linux/clocksource.h> |
32 | #include <linux/serial_core.h> | 35 | #include <linux/serial_core.h> |
@@ -196,8 +199,8 @@ int __weak kgdb_validate_break_address(unsigned long addr) | |||
196 | return err; | 199 | return err; |
197 | err = kgdb_arch_remove_breakpoint(&tmp); | 200 | err = kgdb_arch_remove_breakpoint(&tmp); |
198 | if (err) | 201 | if (err) |
199 | printk(KERN_ERR "KGDB: Critical breakpoint error, kernel " | 202 | pr_err("Critical breakpoint error, kernel memory destroyed at: %lx\n", |
200 | "memory destroyed at: %lx", addr); | 203 | addr); |
201 | return err; | 204 | return err; |
202 | } | 205 | } |
203 | 206 | ||
@@ -256,8 +259,8 @@ int dbg_activate_sw_breakpoints(void) | |||
256 | error = kgdb_arch_set_breakpoint(&kgdb_break[i]); | 259 | error = kgdb_arch_set_breakpoint(&kgdb_break[i]); |
257 | if (error) { | 260 | if (error) { |
258 | ret = error; | 261 | ret = error; |
259 | printk(KERN_INFO "KGDB: BP install failed: %lx", | 262 | pr_info("BP install failed: %lx\n", |
260 | kgdb_break[i].bpt_addr); | 263 | kgdb_break[i].bpt_addr); |
261 | continue; | 264 | continue; |
262 | } | 265 | } |
263 | 266 | ||
@@ -319,8 +322,8 @@ int dbg_deactivate_sw_breakpoints(void) | |||
319 | continue; | 322 | continue; |
320 | error = kgdb_arch_remove_breakpoint(&kgdb_break[i]); | 323 | error = kgdb_arch_remove_breakpoint(&kgdb_break[i]); |
321 | if (error) { | 324 | if (error) { |
322 | printk(KERN_INFO "KGDB: BP remove failed: %lx\n", | 325 | pr_info("BP remove failed: %lx\n", |
323 | kgdb_break[i].bpt_addr); | 326 | kgdb_break[i].bpt_addr); |
324 | ret = error; | 327 | ret = error; |
325 | } | 328 | } |
326 | 329 | ||
@@ -367,7 +370,7 @@ int dbg_remove_all_break(void) | |||
367 | goto setundefined; | 370 | goto setundefined; |
368 | error = kgdb_arch_remove_breakpoint(&kgdb_break[i]); | 371 | error = kgdb_arch_remove_breakpoint(&kgdb_break[i]); |
369 | if (error) | 372 | if (error) |
370 | printk(KERN_ERR "KGDB: breakpoint remove failed: %lx\n", | 373 | pr_err("breakpoint remove failed: %lx\n", |
371 | kgdb_break[i].bpt_addr); | 374 | kgdb_break[i].bpt_addr); |
372 | setundefined: | 375 | setundefined: |
373 | kgdb_break[i].state = BP_UNDEFINED; | 376 | kgdb_break[i].state = BP_UNDEFINED; |
@@ -400,9 +403,9 @@ static int kgdb_io_ready(int print_wait) | |||
400 | if (print_wait) { | 403 | if (print_wait) { |
401 | #ifdef CONFIG_KGDB_KDB | 404 | #ifdef CONFIG_KGDB_KDB |
402 | if (!dbg_kdb_mode) | 405 | if (!dbg_kdb_mode) |
403 | printk(KERN_CRIT "KGDB: waiting... or $3#33 for KDB\n"); | 406 | pr_crit("waiting... or $3#33 for KDB\n"); |
404 | #else | 407 | #else |
405 | printk(KERN_CRIT "KGDB: Waiting for remote debugger\n"); | 408 | pr_crit("Waiting for remote debugger\n"); |
406 | #endif | 409 | #endif |
407 | } | 410 | } |
408 | return 1; | 411 | return 1; |
@@ -430,8 +433,7 @@ static int kgdb_reenter_check(struct kgdb_state *ks) | |||
430 | exception_level = 0; | 433 | exception_level = 0; |
431 | kgdb_skipexception(ks->ex_vector, ks->linux_regs); | 434 | kgdb_skipexception(ks->ex_vector, ks->linux_regs); |
432 | dbg_activate_sw_breakpoints(); | 435 | dbg_activate_sw_breakpoints(); |
433 | printk(KERN_CRIT "KGDB: re-enter error: breakpoint removed %lx\n", | 436 | pr_crit("re-enter error: breakpoint removed %lx\n", addr); |
434 | addr); | ||
435 | WARN_ON_ONCE(1); | 437 | WARN_ON_ONCE(1); |
436 | 438 | ||
437 | return 1; | 439 | return 1; |
@@ -444,7 +446,7 @@ static int kgdb_reenter_check(struct kgdb_state *ks) | |||
444 | panic("Recursive entry to debugger"); | 446 | panic("Recursive entry to debugger"); |
445 | } | 447 | } |
446 | 448 | ||
447 | printk(KERN_CRIT "KGDB: re-enter exception: ALL breakpoints killed\n"); | 449 | pr_crit("re-enter exception: ALL breakpoints killed\n"); |
448 | #ifdef CONFIG_KGDB_KDB | 450 | #ifdef CONFIG_KGDB_KDB |
449 | /* Allow kdb to debug itself one level */ | 451 | /* Allow kdb to debug itself one level */ |
450 | return 0; | 452 | return 0; |
@@ -471,6 +473,7 @@ static int kgdb_cpu_enter(struct kgdb_state *ks, struct pt_regs *regs, | |||
471 | int cpu; | 473 | int cpu; |
472 | int trace_on = 0; | 474 | int trace_on = 0; |
473 | int online_cpus = num_online_cpus(); | 475 | int online_cpus = num_online_cpus(); |
476 | u64 time_left; | ||
474 | 477 | ||
475 | kgdb_info[ks->cpu].enter_kgdb++; | 478 | kgdb_info[ks->cpu].enter_kgdb++; |
476 | kgdb_info[ks->cpu].exception_state |= exception_state; | 479 | kgdb_info[ks->cpu].exception_state |= exception_state; |
@@ -595,9 +598,13 @@ return_normal: | |||
595 | /* | 598 | /* |
596 | * Wait for the other CPUs to be notified and be waiting for us: | 599 | * Wait for the other CPUs to be notified and be waiting for us: |
597 | */ | 600 | */ |
598 | while (kgdb_do_roundup && (atomic_read(&masters_in_kgdb) + | 601 | time_left = loops_per_jiffy * HZ; |
599 | atomic_read(&slaves_in_kgdb)) != online_cpus) | 602 | while (kgdb_do_roundup && --time_left && |
603 | (atomic_read(&masters_in_kgdb) + atomic_read(&slaves_in_kgdb)) != | ||
604 | online_cpus) | ||
600 | cpu_relax(); | 605 | cpu_relax(); |
606 | if (!time_left) | ||
607 | pr_crit("KGDB: Timed out waiting for secondary CPUs.\n"); | ||
601 | 608 | ||
602 | /* | 609 | /* |
603 | * At this point the primary processor is completely | 610 | * At this point the primary processor is completely |
@@ -795,15 +802,15 @@ static struct console kgdbcons = { | |||
795 | static void sysrq_handle_dbg(int key) | 802 | static void sysrq_handle_dbg(int key) |
796 | { | 803 | { |
797 | if (!dbg_io_ops) { | 804 | if (!dbg_io_ops) { |
798 | printk(KERN_CRIT "ERROR: No KGDB I/O module available\n"); | 805 | pr_crit("ERROR: No KGDB I/O module available\n"); |
799 | return; | 806 | return; |
800 | } | 807 | } |
801 | if (!kgdb_connected) { | 808 | if (!kgdb_connected) { |
802 | #ifdef CONFIG_KGDB_KDB | 809 | #ifdef CONFIG_KGDB_KDB |
803 | if (!dbg_kdb_mode) | 810 | if (!dbg_kdb_mode) |
804 | printk(KERN_CRIT "KGDB or $3#33 for KDB\n"); | 811 | pr_crit("KGDB or $3#33 for KDB\n"); |
805 | #else | 812 | #else |
806 | printk(KERN_CRIT "Entering KGDB\n"); | 813 | pr_crit("Entering KGDB\n"); |
807 | #endif | 814 | #endif |
808 | } | 815 | } |
809 | 816 | ||
@@ -945,7 +952,7 @@ static void kgdb_initial_breakpoint(void) | |||
945 | { | 952 | { |
946 | kgdb_break_asap = 0; | 953 | kgdb_break_asap = 0; |
947 | 954 | ||
948 | printk(KERN_CRIT "kgdb: Waiting for connection from remote gdb...\n"); | 955 | pr_crit("Waiting for connection from remote gdb...\n"); |
949 | kgdb_breakpoint(); | 956 | kgdb_breakpoint(); |
950 | } | 957 | } |
951 | 958 | ||
@@ -964,8 +971,7 @@ int kgdb_register_io_module(struct kgdb_io *new_dbg_io_ops) | |||
964 | if (dbg_io_ops) { | 971 | if (dbg_io_ops) { |
965 | spin_unlock(&kgdb_registration_lock); | 972 | spin_unlock(&kgdb_registration_lock); |
966 | 973 | ||
967 | printk(KERN_ERR "kgdb: Another I/O driver is already " | 974 | pr_err("Another I/O driver is already registered with KGDB\n"); |
968 | "registered with KGDB.\n"); | ||
969 | return -EBUSY; | 975 | return -EBUSY; |
970 | } | 976 | } |
971 | 977 | ||
@@ -981,8 +987,7 @@ int kgdb_register_io_module(struct kgdb_io *new_dbg_io_ops) | |||
981 | 987 | ||
982 | spin_unlock(&kgdb_registration_lock); | 988 | spin_unlock(&kgdb_registration_lock); |
983 | 989 | ||
984 | printk(KERN_INFO "kgdb: Registered I/O driver %s.\n", | 990 | pr_info("Registered I/O driver %s\n", new_dbg_io_ops->name); |
985 | new_dbg_io_ops->name); | ||
986 | 991 | ||
987 | /* Arm KGDB now. */ | 992 | /* Arm KGDB now. */ |
988 | kgdb_register_callbacks(); | 993 | kgdb_register_callbacks(); |
@@ -1017,8 +1022,7 @@ void kgdb_unregister_io_module(struct kgdb_io *old_dbg_io_ops) | |||
1017 | 1022 | ||
1018 | spin_unlock(&kgdb_registration_lock); | 1023 | spin_unlock(&kgdb_registration_lock); |
1019 | 1024 | ||
1020 | printk(KERN_INFO | 1025 | pr_info("Unregistered I/O driver %s, debugger disabled\n", |
1021 | "kgdb: Unregistered I/O driver %s, debugger disabled.\n", | ||
1022 | old_dbg_io_ops->name); | 1026 | old_dbg_io_ops->name); |
1023 | } | 1027 | } |
1024 | EXPORT_SYMBOL_GPL(kgdb_unregister_io_module); | 1028 | EXPORT_SYMBOL_GPL(kgdb_unregister_io_module); |
diff --git a/kernel/debug/kdb/kdb_bp.c b/kernel/debug/kdb/kdb_bp.c index b20d544f20c2..e1dbf4a2c69e 100644 --- a/kernel/debug/kdb/kdb_bp.c +++ b/kernel/debug/kdb/kdb_bp.c | |||
@@ -531,22 +531,29 @@ void __init kdb_initbptab(void) | |||
531 | for (i = 0, bp = kdb_breakpoints; i < KDB_MAXBPT; i++, bp++) | 531 | for (i = 0, bp = kdb_breakpoints; i < KDB_MAXBPT; i++, bp++) |
532 | bp->bp_free = 1; | 532 | bp->bp_free = 1; |
533 | 533 | ||
534 | kdb_register_repeat("bp", kdb_bp, "[<vaddr>]", | 534 | kdb_register_flags("bp", kdb_bp, "[<vaddr>]", |
535 | "Set/Display breakpoints", 0, KDB_REPEAT_NO_ARGS); | 535 | "Set/Display breakpoints", 0, |
536 | kdb_register_repeat("bl", kdb_bp, "[<vaddr>]", | 536 | KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS); |
537 | "Display breakpoints", 0, KDB_REPEAT_NO_ARGS); | 537 | kdb_register_flags("bl", kdb_bp, "[<vaddr>]", |
538 | "Display breakpoints", 0, | ||
539 | KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS); | ||
538 | if (arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT) | 540 | if (arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT) |
539 | kdb_register_repeat("bph", kdb_bp, "[<vaddr>]", | 541 | kdb_register_flags("bph", kdb_bp, "[<vaddr>]", |
540 | "[datar [length]|dataw [length]] Set hw brk", 0, KDB_REPEAT_NO_ARGS); | 542 | "[datar [length]|dataw [length]] Set hw brk", 0, |
541 | kdb_register_repeat("bc", kdb_bc, "<bpnum>", | 543 | KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS); |
542 | "Clear Breakpoint", 0, KDB_REPEAT_NONE); | 544 | kdb_register_flags("bc", kdb_bc, "<bpnum>", |
543 | kdb_register_repeat("be", kdb_bc, "<bpnum>", | 545 | "Clear Breakpoint", 0, |
544 | "Enable Breakpoint", 0, KDB_REPEAT_NONE); | 546 | KDB_ENABLE_FLOW_CTRL); |
545 | kdb_register_repeat("bd", kdb_bc, "<bpnum>", | 547 | kdb_register_flags("be", kdb_bc, "<bpnum>", |
546 | "Disable Breakpoint", 0, KDB_REPEAT_NONE); | 548 | "Enable Breakpoint", 0, |
547 | 549 | KDB_ENABLE_FLOW_CTRL); | |
548 | kdb_register_repeat("ss", kdb_ss, "", | 550 | kdb_register_flags("bd", kdb_bc, "<bpnum>", |
549 | "Single Step", 1, KDB_REPEAT_NO_ARGS); | 551 | "Disable Breakpoint", 0, |
552 | KDB_ENABLE_FLOW_CTRL); | ||
553 | |||
554 | kdb_register_flags("ss", kdb_ss, "", | ||
555 | "Single Step", 1, | ||
556 | KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS); | ||
550 | /* | 557 | /* |
551 | * Architecture dependent initialization. | 558 | * Architecture dependent initialization. |
552 | */ | 559 | */ |
diff --git a/kernel/debug/kdb/kdb_debugger.c b/kernel/debug/kdb/kdb_debugger.c index 8859ca34dcfe..15e1a7af5dd0 100644 --- a/kernel/debug/kdb/kdb_debugger.c +++ b/kernel/debug/kdb/kdb_debugger.c | |||
@@ -129,6 +129,10 @@ int kdb_stub(struct kgdb_state *ks) | |||
129 | ks->pass_exception = 1; | 129 | ks->pass_exception = 1; |
130 | KDB_FLAG_SET(CATASTROPHIC); | 130 | KDB_FLAG_SET(CATASTROPHIC); |
131 | } | 131 | } |
132 | /* set CATASTROPHIC if the system contains unresponsive processors */ | ||
133 | for_each_online_cpu(i) | ||
134 | if (!kgdb_info[i].enter_kgdb) | ||
135 | KDB_FLAG_SET(CATASTROPHIC); | ||
132 | if (KDB_STATE(SSBPT) && reason == KDB_REASON_SSTEP) { | 136 | if (KDB_STATE(SSBPT) && reason == KDB_REASON_SSTEP) { |
133 | KDB_STATE_CLEAR(SSBPT); | 137 | KDB_STATE_CLEAR(SSBPT); |
134 | KDB_STATE_CLEAR(DOING_SS); | 138 | KDB_STATE_CLEAR(DOING_SS); |
diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c index 379650b984f8..7b40c5f07dce 100644 --- a/kernel/debug/kdb/kdb_main.c +++ b/kernel/debug/kdb/kdb_main.c | |||
@@ -12,6 +12,7 @@ | |||
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/ctype.h> | 14 | #include <linux/ctype.h> |
15 | #include <linux/types.h> | ||
15 | #include <linux/string.h> | 16 | #include <linux/string.h> |
16 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
17 | #include <linux/kmsg_dump.h> | 18 | #include <linux/kmsg_dump.h> |
@@ -23,6 +24,7 @@ | |||
23 | #include <linux/vmalloc.h> | 24 | #include <linux/vmalloc.h> |
24 | #include <linux/atomic.h> | 25 | #include <linux/atomic.h> |
25 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/moduleparam.h> | ||
26 | #include <linux/mm.h> | 28 | #include <linux/mm.h> |
27 | #include <linux/init.h> | 29 | #include <linux/init.h> |
28 | #include <linux/kallsyms.h> | 30 | #include <linux/kallsyms.h> |
@@ -42,6 +44,12 @@ | |||
42 | #include <linux/slab.h> | 44 | #include <linux/slab.h> |
43 | #include "kdb_private.h" | 45 | #include "kdb_private.h" |
44 | 46 | ||
47 | #undef MODULE_PARAM_PREFIX | ||
48 | #define MODULE_PARAM_PREFIX "kdb." | ||
49 | |||
50 | static int kdb_cmd_enabled = CONFIG_KDB_DEFAULT_ENABLE; | ||
51 | module_param_named(cmd_enable, kdb_cmd_enabled, int, 0600); | ||
52 | |||
45 | #define GREP_LEN 256 | 53 | #define GREP_LEN 256 |
46 | char kdb_grep_string[GREP_LEN]; | 54 | char kdb_grep_string[GREP_LEN]; |
47 | int kdb_grepping_flag; | 55 | int kdb_grepping_flag; |
@@ -121,6 +129,7 @@ static kdbmsg_t kdbmsgs[] = { | |||
121 | KDBMSG(BADLENGTH, "Invalid length field"), | 129 | KDBMSG(BADLENGTH, "Invalid length field"), |
122 | KDBMSG(NOBP, "No Breakpoint exists"), | 130 | KDBMSG(NOBP, "No Breakpoint exists"), |
123 | KDBMSG(BADADDR, "Invalid address"), | 131 | KDBMSG(BADADDR, "Invalid address"), |
132 | KDBMSG(NOPERM, "Permission denied"), | ||
124 | }; | 133 | }; |
125 | #undef KDBMSG | 134 | #undef KDBMSG |
126 | 135 | ||
@@ -188,6 +197,26 @@ struct task_struct *kdb_curr_task(int cpu) | |||
188 | } | 197 | } |
189 | 198 | ||
190 | /* | 199 | /* |
200 | * Check whether the flags of the current command and the permissions | ||
201 | * of the kdb console has allow a command to be run. | ||
202 | */ | ||
203 | static inline bool kdb_check_flags(kdb_cmdflags_t flags, int permissions, | ||
204 | bool no_args) | ||
205 | { | ||
206 | /* permissions comes from userspace so needs massaging slightly */ | ||
207 | permissions &= KDB_ENABLE_MASK; | ||
208 | permissions |= KDB_ENABLE_ALWAYS_SAFE; | ||
209 | |||
210 | /* some commands change group when launched with no arguments */ | ||
211 | if (no_args) | ||
212 | permissions |= permissions << KDB_ENABLE_NO_ARGS_SHIFT; | ||
213 | |||
214 | flags |= KDB_ENABLE_ALL; | ||
215 | |||
216 | return permissions & flags; | ||
217 | } | ||
218 | |||
219 | /* | ||
191 | * kdbgetenv - This function will return the character string value of | 220 | * kdbgetenv - This function will return the character string value of |
192 | * an environment variable. | 221 | * an environment variable. |
193 | * Parameters: | 222 | * Parameters: |
@@ -476,6 +505,15 @@ int kdbgetaddrarg(int argc, const char **argv, int *nextarg, | |||
476 | kdb_symtab_t symtab; | 505 | kdb_symtab_t symtab; |
477 | 506 | ||
478 | /* | 507 | /* |
508 | * If the enable flags prohibit both arbitrary memory access | ||
509 | * and flow control then there are no reasonable grounds to | ||
510 | * provide symbol lookup. | ||
511 | */ | ||
512 | if (!kdb_check_flags(KDB_ENABLE_MEM_READ | KDB_ENABLE_FLOW_CTRL, | ||
513 | kdb_cmd_enabled, false)) | ||
514 | return KDB_NOPERM; | ||
515 | |||
516 | /* | ||
479 | * Process arguments which follow the following syntax: | 517 | * Process arguments which follow the following syntax: |
480 | * | 518 | * |
481 | * symbol | numeric-address [+/- numeric-offset] | 519 | * symbol | numeric-address [+/- numeric-offset] |
@@ -641,8 +679,13 @@ static int kdb_defcmd2(const char *cmdstr, const char *argv0) | |||
641 | if (!s->count) | 679 | if (!s->count) |
642 | s->usable = 0; | 680 | s->usable = 0; |
643 | if (s->usable) | 681 | if (s->usable) |
644 | kdb_register(s->name, kdb_exec_defcmd, | 682 | /* macros are always safe because when executed each |
645 | s->usage, s->help, 0); | 683 | * internal command re-enters kdb_parse() and is |
684 | * safety checked individually. | ||
685 | */ | ||
686 | kdb_register_flags(s->name, kdb_exec_defcmd, s->usage, | ||
687 | s->help, 0, | ||
688 | KDB_ENABLE_ALWAYS_SAFE); | ||
646 | return 0; | 689 | return 0; |
647 | } | 690 | } |
648 | if (!s->usable) | 691 | if (!s->usable) |
@@ -1003,25 +1046,22 @@ int kdb_parse(const char *cmdstr) | |||
1003 | 1046 | ||
1004 | if (i < kdb_max_commands) { | 1047 | if (i < kdb_max_commands) { |
1005 | int result; | 1048 | int result; |
1049 | |||
1050 | if (!kdb_check_flags(tp->cmd_flags, kdb_cmd_enabled, argc <= 1)) | ||
1051 | return KDB_NOPERM; | ||
1052 | |||
1006 | KDB_STATE_SET(CMD); | 1053 | KDB_STATE_SET(CMD); |
1007 | result = (*tp->cmd_func)(argc-1, (const char **)argv); | 1054 | result = (*tp->cmd_func)(argc-1, (const char **)argv); |
1008 | if (result && ignore_errors && result > KDB_CMD_GO) | 1055 | if (result && ignore_errors && result > KDB_CMD_GO) |
1009 | result = 0; | 1056 | result = 0; |
1010 | KDB_STATE_CLEAR(CMD); | 1057 | KDB_STATE_CLEAR(CMD); |
1011 | switch (tp->cmd_repeat) { | 1058 | |
1012 | case KDB_REPEAT_NONE: | 1059 | if (tp->cmd_flags & KDB_REPEAT_WITH_ARGS) |
1013 | argc = 0; | 1060 | return result; |
1014 | if (argv[0]) | 1061 | |
1015 | *(argv[0]) = '\0'; | 1062 | argc = tp->cmd_flags & KDB_REPEAT_NO_ARGS ? 1 : 0; |
1016 | break; | 1063 | if (argv[argc]) |
1017 | case KDB_REPEAT_NO_ARGS: | 1064 | *(argv[argc]) = '\0'; |
1018 | argc = 1; | ||
1019 | if (argv[1]) | ||
1020 | *(argv[1]) = '\0'; | ||
1021 | break; | ||
1022 | case KDB_REPEAT_WITH_ARGS: | ||
1023 | break; | ||
1024 | } | ||
1025 | return result; | 1065 | return result; |
1026 | } | 1066 | } |
1027 | 1067 | ||
@@ -1921,10 +1961,14 @@ static int kdb_rm(int argc, const char **argv) | |||
1921 | */ | 1961 | */ |
1922 | static int kdb_sr(int argc, const char **argv) | 1962 | static int kdb_sr(int argc, const char **argv) |
1923 | { | 1963 | { |
1964 | bool check_mask = | ||
1965 | !kdb_check_flags(KDB_ENABLE_ALL, kdb_cmd_enabled, false); | ||
1966 | |||
1924 | if (argc != 1) | 1967 | if (argc != 1) |
1925 | return KDB_ARGCOUNT; | 1968 | return KDB_ARGCOUNT; |
1969 | |||
1926 | kdb_trap_printk++; | 1970 | kdb_trap_printk++; |
1927 | __handle_sysrq(*argv[1], false); | 1971 | __handle_sysrq(*argv[1], check_mask); |
1928 | kdb_trap_printk--; | 1972 | kdb_trap_printk--; |
1929 | 1973 | ||
1930 | return 0; | 1974 | return 0; |
@@ -1979,7 +2023,7 @@ static int kdb_lsmod(int argc, const char **argv) | |||
1979 | kdb_printf("%-20s%8u 0x%p ", mod->name, | 2023 | kdb_printf("%-20s%8u 0x%p ", mod->name, |
1980 | mod->core_size, (void *)mod); | 2024 | mod->core_size, (void *)mod); |
1981 | #ifdef CONFIG_MODULE_UNLOAD | 2025 | #ifdef CONFIG_MODULE_UNLOAD |
1982 | kdb_printf("%4ld ", module_refcount(mod)); | 2026 | kdb_printf("%4d ", module_refcount(mod)); |
1983 | #endif | 2027 | #endif |
1984 | if (mod->state == MODULE_STATE_GOING) | 2028 | if (mod->state == MODULE_STATE_GOING) |
1985 | kdb_printf(" (Unloading)"); | 2029 | kdb_printf(" (Unloading)"); |
@@ -2157,6 +2201,8 @@ static void kdb_cpu_status(void) | |||
2157 | for (start_cpu = -1, i = 0; i < NR_CPUS; i++) { | 2201 | for (start_cpu = -1, i = 0; i < NR_CPUS; i++) { |
2158 | if (!cpu_online(i)) { | 2202 | if (!cpu_online(i)) { |
2159 | state = 'F'; /* cpu is offline */ | 2203 | state = 'F'; /* cpu is offline */ |
2204 | } else if (!kgdb_info[i].enter_kgdb) { | ||
2205 | state = 'D'; /* cpu is online but unresponsive */ | ||
2160 | } else { | 2206 | } else { |
2161 | state = ' '; /* cpu is responding to kdb */ | 2207 | state = ' '; /* cpu is responding to kdb */ |
2162 | if (kdb_task_state_char(KDB_TSK(i)) == 'I') | 2208 | if (kdb_task_state_char(KDB_TSK(i)) == 'I') |
@@ -2210,7 +2256,7 @@ static int kdb_cpu(int argc, const char **argv) | |||
2210 | /* | 2256 | /* |
2211 | * Validate cpunum | 2257 | * Validate cpunum |
2212 | */ | 2258 | */ |
2213 | if ((cpunum > NR_CPUS) || !cpu_online(cpunum)) | 2259 | if ((cpunum > NR_CPUS) || !kgdb_info[cpunum].enter_kgdb) |
2214 | return KDB_BADCPUNUM; | 2260 | return KDB_BADCPUNUM; |
2215 | 2261 | ||
2216 | dbg_switch_cpu = cpunum; | 2262 | dbg_switch_cpu = cpunum; |
@@ -2375,6 +2421,8 @@ static int kdb_help(int argc, const char **argv) | |||
2375 | return 0; | 2421 | return 0; |
2376 | if (!kt->cmd_name) | 2422 | if (!kt->cmd_name) |
2377 | continue; | 2423 | continue; |
2424 | if (!kdb_check_flags(kt->cmd_flags, kdb_cmd_enabled, true)) | ||
2425 | continue; | ||
2378 | if (strlen(kt->cmd_usage) > 20) | 2426 | if (strlen(kt->cmd_usage) > 20) |
2379 | space = "\n "; | 2427 | space = "\n "; |
2380 | kdb_printf("%-15.15s %-20s%s%s\n", kt->cmd_name, | 2428 | kdb_printf("%-15.15s %-20s%s%s\n", kt->cmd_name, |
@@ -2629,7 +2677,7 @@ static int kdb_grep_help(int argc, const char **argv) | |||
2629 | } | 2677 | } |
2630 | 2678 | ||
2631 | /* | 2679 | /* |
2632 | * kdb_register_repeat - This function is used to register a kernel | 2680 | * kdb_register_flags - This function is used to register a kernel |
2633 | * debugger command. | 2681 | * debugger command. |
2634 | * Inputs: | 2682 | * Inputs: |
2635 | * cmd Command name | 2683 | * cmd Command name |
@@ -2641,12 +2689,12 @@ static int kdb_grep_help(int argc, const char **argv) | |||
2641 | * zero for success, one if a duplicate command. | 2689 | * zero for success, one if a duplicate command. |
2642 | */ | 2690 | */ |
2643 | #define kdb_command_extend 50 /* arbitrary */ | 2691 | #define kdb_command_extend 50 /* arbitrary */ |
2644 | int kdb_register_repeat(char *cmd, | 2692 | int kdb_register_flags(char *cmd, |
2645 | kdb_func_t func, | 2693 | kdb_func_t func, |
2646 | char *usage, | 2694 | char *usage, |
2647 | char *help, | 2695 | char *help, |
2648 | short minlen, | 2696 | short minlen, |
2649 | kdb_repeat_t repeat) | 2697 | kdb_cmdflags_t flags) |
2650 | { | 2698 | { |
2651 | int i; | 2699 | int i; |
2652 | kdbtab_t *kp; | 2700 | kdbtab_t *kp; |
@@ -2694,19 +2742,18 @@ int kdb_register_repeat(char *cmd, | |||
2694 | kp->cmd_func = func; | 2742 | kp->cmd_func = func; |
2695 | kp->cmd_usage = usage; | 2743 | kp->cmd_usage = usage; |
2696 | kp->cmd_help = help; | 2744 | kp->cmd_help = help; |
2697 | kp->cmd_flags = 0; | ||
2698 | kp->cmd_minlen = minlen; | 2745 | kp->cmd_minlen = minlen; |
2699 | kp->cmd_repeat = repeat; | 2746 | kp->cmd_flags = flags; |
2700 | 2747 | ||
2701 | return 0; | 2748 | return 0; |
2702 | } | 2749 | } |
2703 | EXPORT_SYMBOL_GPL(kdb_register_repeat); | 2750 | EXPORT_SYMBOL_GPL(kdb_register_flags); |
2704 | 2751 | ||
2705 | 2752 | ||
2706 | /* | 2753 | /* |
2707 | * kdb_register - Compatibility register function for commands that do | 2754 | * kdb_register - Compatibility register function for commands that do |
2708 | * not need to specify a repeat state. Equivalent to | 2755 | * not need to specify a repeat state. Equivalent to |
2709 | * kdb_register_repeat with KDB_REPEAT_NONE. | 2756 | * kdb_register_flags with flags set to 0. |
2710 | * Inputs: | 2757 | * Inputs: |
2711 | * cmd Command name | 2758 | * cmd Command name |
2712 | * func Function to execute the command | 2759 | * func Function to execute the command |
@@ -2721,8 +2768,7 @@ int kdb_register(char *cmd, | |||
2721 | char *help, | 2768 | char *help, |
2722 | short minlen) | 2769 | short minlen) |
2723 | { | 2770 | { |
2724 | return kdb_register_repeat(cmd, func, usage, help, minlen, | 2771 | return kdb_register_flags(cmd, func, usage, help, minlen, 0); |
2725 | KDB_REPEAT_NONE); | ||
2726 | } | 2772 | } |
2727 | EXPORT_SYMBOL_GPL(kdb_register); | 2773 | EXPORT_SYMBOL_GPL(kdb_register); |
2728 | 2774 | ||
@@ -2764,80 +2810,109 @@ static void __init kdb_inittab(void) | |||
2764 | for_each_kdbcmd(kp, i) | 2810 | for_each_kdbcmd(kp, i) |
2765 | kp->cmd_name = NULL; | 2811 | kp->cmd_name = NULL; |
2766 | 2812 | ||
2767 | kdb_register_repeat("md", kdb_md, "<vaddr>", | 2813 | kdb_register_flags("md", kdb_md, "<vaddr>", |
2768 | "Display Memory Contents, also mdWcN, e.g. md8c1", 1, | 2814 | "Display Memory Contents, also mdWcN, e.g. md8c1", 1, |
2769 | KDB_REPEAT_NO_ARGS); | 2815 | KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS); |
2770 | kdb_register_repeat("mdr", kdb_md, "<vaddr> <bytes>", | 2816 | kdb_register_flags("mdr", kdb_md, "<vaddr> <bytes>", |
2771 | "Display Raw Memory", 0, KDB_REPEAT_NO_ARGS); | 2817 | "Display Raw Memory", 0, |
2772 | kdb_register_repeat("mdp", kdb_md, "<paddr> <bytes>", | 2818 | KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS); |
2773 | "Display Physical Memory", 0, KDB_REPEAT_NO_ARGS); | 2819 | kdb_register_flags("mdp", kdb_md, "<paddr> <bytes>", |
2774 | kdb_register_repeat("mds", kdb_md, "<vaddr>", | 2820 | "Display Physical Memory", 0, |
2775 | "Display Memory Symbolically", 0, KDB_REPEAT_NO_ARGS); | 2821 | KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS); |
2776 | kdb_register_repeat("mm", kdb_mm, "<vaddr> <contents>", | 2822 | kdb_register_flags("mds", kdb_md, "<vaddr>", |
2777 | "Modify Memory Contents", 0, KDB_REPEAT_NO_ARGS); | 2823 | "Display Memory Symbolically", 0, |
2778 | kdb_register_repeat("go", kdb_go, "[<vaddr>]", | 2824 | KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS); |
2779 | "Continue Execution", 1, KDB_REPEAT_NONE); | 2825 | kdb_register_flags("mm", kdb_mm, "<vaddr> <contents>", |
2780 | kdb_register_repeat("rd", kdb_rd, "", | 2826 | "Modify Memory Contents", 0, |
2781 | "Display Registers", 0, KDB_REPEAT_NONE); | 2827 | KDB_ENABLE_MEM_WRITE | KDB_REPEAT_NO_ARGS); |
2782 | kdb_register_repeat("rm", kdb_rm, "<reg> <contents>", | 2828 | kdb_register_flags("go", kdb_go, "[<vaddr>]", |
2783 | "Modify Registers", 0, KDB_REPEAT_NONE); | 2829 | "Continue Execution", 1, |
2784 | kdb_register_repeat("ef", kdb_ef, "<vaddr>", | 2830 | KDB_ENABLE_REG_WRITE | KDB_ENABLE_ALWAYS_SAFE_NO_ARGS); |
2785 | "Display exception frame", 0, KDB_REPEAT_NONE); | 2831 | kdb_register_flags("rd", kdb_rd, "", |
2786 | kdb_register_repeat("bt", kdb_bt, "[<vaddr>]", | 2832 | "Display Registers", 0, |
2787 | "Stack traceback", 1, KDB_REPEAT_NONE); | 2833 | KDB_ENABLE_REG_READ); |
2788 | kdb_register_repeat("btp", kdb_bt, "<pid>", | 2834 | kdb_register_flags("rm", kdb_rm, "<reg> <contents>", |
2789 | "Display stack for process <pid>", 0, KDB_REPEAT_NONE); | 2835 | "Modify Registers", 0, |
2790 | kdb_register_repeat("bta", kdb_bt, "[D|R|S|T|C|Z|E|U|I|M|A]", | 2836 | KDB_ENABLE_REG_WRITE); |
2791 | "Backtrace all processes matching state flag", 0, KDB_REPEAT_NONE); | 2837 | kdb_register_flags("ef", kdb_ef, "<vaddr>", |
2792 | kdb_register_repeat("btc", kdb_bt, "", | 2838 | "Display exception frame", 0, |
2793 | "Backtrace current process on each cpu", 0, KDB_REPEAT_NONE); | 2839 | KDB_ENABLE_MEM_READ); |
2794 | kdb_register_repeat("btt", kdb_bt, "<vaddr>", | 2840 | kdb_register_flags("bt", kdb_bt, "[<vaddr>]", |
2841 | "Stack traceback", 1, | ||
2842 | KDB_ENABLE_MEM_READ | KDB_ENABLE_INSPECT_NO_ARGS); | ||
2843 | kdb_register_flags("btp", kdb_bt, "<pid>", | ||
2844 | "Display stack for process <pid>", 0, | ||
2845 | KDB_ENABLE_INSPECT); | ||
2846 | kdb_register_flags("bta", kdb_bt, "[D|R|S|T|C|Z|E|U|I|M|A]", | ||
2847 | "Backtrace all processes matching state flag", 0, | ||
2848 | KDB_ENABLE_INSPECT); | ||
2849 | kdb_register_flags("btc", kdb_bt, "", | ||
2850 | "Backtrace current process on each cpu", 0, | ||
2851 | KDB_ENABLE_INSPECT); | ||
2852 | kdb_register_flags("btt", kdb_bt, "<vaddr>", | ||
2795 | "Backtrace process given its struct task address", 0, | 2853 | "Backtrace process given its struct task address", 0, |
2796 | KDB_REPEAT_NONE); | 2854 | KDB_ENABLE_MEM_READ | KDB_ENABLE_INSPECT_NO_ARGS); |
2797 | kdb_register_repeat("env", kdb_env, "", | 2855 | kdb_register_flags("env", kdb_env, "", |
2798 | "Show environment variables", 0, KDB_REPEAT_NONE); | 2856 | "Show environment variables", 0, |
2799 | kdb_register_repeat("set", kdb_set, "", | 2857 | KDB_ENABLE_ALWAYS_SAFE); |
2800 | "Set environment variables", 0, KDB_REPEAT_NONE); | 2858 | kdb_register_flags("set", kdb_set, "", |
2801 | kdb_register_repeat("help", kdb_help, "", | 2859 | "Set environment variables", 0, |
2802 | "Display Help Message", 1, KDB_REPEAT_NONE); | 2860 | KDB_ENABLE_ALWAYS_SAFE); |
2803 | kdb_register_repeat("?", kdb_help, "", | 2861 | kdb_register_flags("help", kdb_help, "", |
2804 | "Display Help Message", 0, KDB_REPEAT_NONE); | 2862 | "Display Help Message", 1, |
2805 | kdb_register_repeat("cpu", kdb_cpu, "<cpunum>", | 2863 | KDB_ENABLE_ALWAYS_SAFE); |
2806 | "Switch to new cpu", 0, KDB_REPEAT_NONE); | 2864 | kdb_register_flags("?", kdb_help, "", |
2807 | kdb_register_repeat("kgdb", kdb_kgdb, "", | 2865 | "Display Help Message", 0, |
2808 | "Enter kgdb mode", 0, KDB_REPEAT_NONE); | 2866 | KDB_ENABLE_ALWAYS_SAFE); |
2809 | kdb_register_repeat("ps", kdb_ps, "[<flags>|A]", | 2867 | kdb_register_flags("cpu", kdb_cpu, "<cpunum>", |
2810 | "Display active task list", 0, KDB_REPEAT_NONE); | 2868 | "Switch to new cpu", 0, |
2811 | kdb_register_repeat("pid", kdb_pid, "<pidnum>", | 2869 | KDB_ENABLE_ALWAYS_SAFE_NO_ARGS); |
2812 | "Switch to another task", 0, KDB_REPEAT_NONE); | 2870 | kdb_register_flags("kgdb", kdb_kgdb, "", |
2813 | kdb_register_repeat("reboot", kdb_reboot, "", | 2871 | "Enter kgdb mode", 0, 0); |
2814 | "Reboot the machine immediately", 0, KDB_REPEAT_NONE); | 2872 | kdb_register_flags("ps", kdb_ps, "[<flags>|A]", |
2873 | "Display active task list", 0, | ||
2874 | KDB_ENABLE_INSPECT); | ||
2875 | kdb_register_flags("pid", kdb_pid, "<pidnum>", | ||
2876 | "Switch to another task", 0, | ||
2877 | KDB_ENABLE_INSPECT); | ||
2878 | kdb_register_flags("reboot", kdb_reboot, "", | ||
2879 | "Reboot the machine immediately", 0, | ||
2880 | KDB_ENABLE_REBOOT); | ||
2815 | #if defined(CONFIG_MODULES) | 2881 | #if defined(CONFIG_MODULES) |
2816 | kdb_register_repeat("lsmod", kdb_lsmod, "", | 2882 | kdb_register_flags("lsmod", kdb_lsmod, "", |
2817 | "List loaded kernel modules", 0, KDB_REPEAT_NONE); | 2883 | "List loaded kernel modules", 0, |
2884 | KDB_ENABLE_INSPECT); | ||
2818 | #endif | 2885 | #endif |
2819 | #if defined(CONFIG_MAGIC_SYSRQ) | 2886 | #if defined(CONFIG_MAGIC_SYSRQ) |
2820 | kdb_register_repeat("sr", kdb_sr, "<key>", | 2887 | kdb_register_flags("sr", kdb_sr, "<key>", |
2821 | "Magic SysRq key", 0, KDB_REPEAT_NONE); | 2888 | "Magic SysRq key", 0, |
2889 | KDB_ENABLE_ALWAYS_SAFE); | ||
2822 | #endif | 2890 | #endif |
2823 | #if defined(CONFIG_PRINTK) | 2891 | #if defined(CONFIG_PRINTK) |
2824 | kdb_register_repeat("dmesg", kdb_dmesg, "[lines]", | 2892 | kdb_register_flags("dmesg", kdb_dmesg, "[lines]", |
2825 | "Display syslog buffer", 0, KDB_REPEAT_NONE); | 2893 | "Display syslog buffer", 0, |
2894 | KDB_ENABLE_ALWAYS_SAFE); | ||
2826 | #endif | 2895 | #endif |
2827 | if (arch_kgdb_ops.enable_nmi) { | 2896 | if (arch_kgdb_ops.enable_nmi) { |
2828 | kdb_register_repeat("disable_nmi", kdb_disable_nmi, "", | 2897 | kdb_register_flags("disable_nmi", kdb_disable_nmi, "", |
2829 | "Disable NMI entry to KDB", 0, KDB_REPEAT_NONE); | 2898 | "Disable NMI entry to KDB", 0, |
2830 | } | 2899 | KDB_ENABLE_ALWAYS_SAFE); |
2831 | kdb_register_repeat("defcmd", kdb_defcmd, "name \"usage\" \"help\"", | 2900 | } |
2832 | "Define a set of commands, down to endefcmd", 0, KDB_REPEAT_NONE); | 2901 | kdb_register_flags("defcmd", kdb_defcmd, "name \"usage\" \"help\"", |
2833 | kdb_register_repeat("kill", kdb_kill, "<-signal> <pid>", | 2902 | "Define a set of commands, down to endefcmd", 0, |
2834 | "Send a signal to a process", 0, KDB_REPEAT_NONE); | 2903 | KDB_ENABLE_ALWAYS_SAFE); |
2835 | kdb_register_repeat("summary", kdb_summary, "", | 2904 | kdb_register_flags("kill", kdb_kill, "<-signal> <pid>", |
2836 | "Summarize the system", 4, KDB_REPEAT_NONE); | 2905 | "Send a signal to a process", 0, |
2837 | kdb_register_repeat("per_cpu", kdb_per_cpu, "<sym> [<bytes>] [<cpu>]", | 2906 | KDB_ENABLE_SIGNAL); |
2838 | "Display per_cpu variables", 3, KDB_REPEAT_NONE); | 2907 | kdb_register_flags("summary", kdb_summary, "", |
2839 | kdb_register_repeat("grephelp", kdb_grep_help, "", | 2908 | "Summarize the system", 4, |
2840 | "Display help on | grep", 0, KDB_REPEAT_NONE); | 2909 | KDB_ENABLE_ALWAYS_SAFE); |
2910 | kdb_register_flags("per_cpu", kdb_per_cpu, "<sym> [<bytes>] [<cpu>]", | ||
2911 | "Display per_cpu variables", 3, | ||
2912 | KDB_ENABLE_MEM_READ); | ||
2913 | kdb_register_flags("grephelp", kdb_grep_help, "", | ||
2914 | "Display help on | grep", 0, | ||
2915 | KDB_ENABLE_ALWAYS_SAFE); | ||
2841 | } | 2916 | } |
2842 | 2917 | ||
2843 | /* Execute any commands defined in kdb_cmds. */ | 2918 | /* Execute any commands defined in kdb_cmds. */ |
diff --git a/kernel/debug/kdb/kdb_private.h b/kernel/debug/kdb/kdb_private.h index 7afd3c8c41d5..eaacd1693954 100644 --- a/kernel/debug/kdb/kdb_private.h +++ b/kernel/debug/kdb/kdb_private.h | |||
@@ -172,10 +172,9 @@ typedef struct _kdbtab { | |||
172 | kdb_func_t cmd_func; /* Function to execute command */ | 172 | kdb_func_t cmd_func; /* Function to execute command */ |
173 | char *cmd_usage; /* Usage String for this command */ | 173 | char *cmd_usage; /* Usage String for this command */ |
174 | char *cmd_help; /* Help message for this command */ | 174 | char *cmd_help; /* Help message for this command */ |
175 | short cmd_flags; /* Parsing flags */ | ||
176 | short cmd_minlen; /* Minimum legal # command | 175 | short cmd_minlen; /* Minimum legal # command |
177 | * chars required */ | 176 | * chars required */ |
178 | kdb_repeat_t cmd_repeat; /* Does command auto repeat on enter? */ | 177 | kdb_cmdflags_t cmd_flags; /* Command behaviour flags */ |
179 | } kdbtab_t; | 178 | } kdbtab_t; |
180 | 179 | ||
181 | extern int kdb_bt(int, const char **); /* KDB display back trace */ | 180 | extern int kdb_bt(int, const char **); /* KDB display back trace */ |