diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /kernel/debug | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'kernel/debug')
-rw-r--r-- | kernel/debug/debug_core.c | 119 | ||||
-rw-r--r-- | kernel/debug/gdbstub.c | 22 | ||||
-rw-r--r-- | kernel/debug/kdb/kdb_bp.c | 7 | ||||
-rw-r--r-- | kernel/debug/kdb/kdb_bt.c | 3 | ||||
-rw-r--r-- | kernel/debug/kdb/kdb_debugger.c | 5 | ||||
-rw-r--r-- | kernel/debug/kdb/kdb_io.c | 48 | ||||
-rw-r--r-- | kernel/debug/kdb/kdb_keyboard.c | 95 | ||||
-rw-r--r-- | kernel/debug/kdb/kdb_main.c | 142 | ||||
-rw-r--r-- | kernel/debug/kdb/kdb_private.h | 8 | ||||
-rw-r--r-- | kernel/debug/kdb/kdb_support.c | 6 |
10 files changed, 157 insertions, 298 deletions
diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c index 9a61738cefc..0d7c08784ef 100644 --- a/kernel/debug/debug_core.c +++ b/kernel/debug/debug_core.c | |||
@@ -41,7 +41,6 @@ | |||
41 | #include <linux/delay.h> | 41 | #include <linux/delay.h> |
42 | #include <linux/sched.h> | 42 | #include <linux/sched.h> |
43 | #include <linux/sysrq.h> | 43 | #include <linux/sysrq.h> |
44 | #include <linux/reboot.h> | ||
45 | #include <linux/init.h> | 44 | #include <linux/init.h> |
46 | #include <linux/kgdb.h> | 45 | #include <linux/kgdb.h> |
47 | #include <linux/kdb.h> | 46 | #include <linux/kdb.h> |
@@ -53,6 +52,7 @@ | |||
53 | #include <asm/cacheflush.h> | 52 | #include <asm/cacheflush.h> |
54 | #include <asm/byteorder.h> | 53 | #include <asm/byteorder.h> |
55 | #include <linux/atomic.h> | 54 | #include <linux/atomic.h> |
55 | #include <asm/system.h> | ||
56 | 56 | ||
57 | #include "debug_core.h" | 57 | #include "debug_core.h" |
58 | 58 | ||
@@ -75,8 +75,6 @@ static int exception_level; | |||
75 | struct kgdb_io *dbg_io_ops; | 75 | struct kgdb_io *dbg_io_ops; |
76 | static DEFINE_SPINLOCK(kgdb_registration_lock); | 76 | static DEFINE_SPINLOCK(kgdb_registration_lock); |
77 | 77 | ||
78 | /* Action for the reboot notifiter, a global allow kdb to change it */ | ||
79 | static int kgdbreboot; | ||
80 | /* kgdb console driver is loaded */ | 78 | /* kgdb console driver is loaded */ |
81 | static int kgdb_con_registered; | 79 | static int kgdb_con_registered; |
82 | /* determine if kgdb console output should be used */ | 80 | /* determine if kgdb console output should be used */ |
@@ -98,7 +96,6 @@ static int __init opt_kgdb_con(char *str) | |||
98 | early_param("kgdbcon", opt_kgdb_con); | 96 | early_param("kgdbcon", opt_kgdb_con); |
99 | 97 | ||
100 | module_param(kgdb_use_con, int, 0644); | 98 | module_param(kgdb_use_con, int, 0644); |
101 | module_param(kgdbreboot, int, 0644); | ||
102 | 99 | ||
103 | /* | 100 | /* |
104 | * Holds information about breakpoints in a kernel. These breakpoints are | 101 | * Holds information about breakpoints in a kernel. These breakpoints are |
@@ -160,39 +157,37 @@ early_param("nokgdbroundup", opt_nokgdbroundup); | |||
160 | * Weak aliases for breakpoint management, | 157 | * Weak aliases for breakpoint management, |
161 | * can be overriden by architectures when needed: | 158 | * can be overriden by architectures when needed: |
162 | */ | 159 | */ |
163 | int __weak kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt) | 160 | int __weak kgdb_arch_set_breakpoint(unsigned long addr, char *saved_instr) |
164 | { | 161 | { |
165 | int err; | 162 | int err; |
166 | 163 | ||
167 | err = probe_kernel_read(bpt->saved_instr, (char *)bpt->bpt_addr, | 164 | err = probe_kernel_read(saved_instr, (char *)addr, BREAK_INSTR_SIZE); |
168 | BREAK_INSTR_SIZE); | ||
169 | if (err) | 165 | if (err) |
170 | return err; | 166 | return err; |
171 | err = probe_kernel_write((char *)bpt->bpt_addr, | 167 | |
172 | arch_kgdb_ops.gdb_bpt_instr, BREAK_INSTR_SIZE); | 168 | return probe_kernel_write((char *)addr, arch_kgdb_ops.gdb_bpt_instr, |
173 | return err; | 169 | BREAK_INSTR_SIZE); |
174 | } | 170 | } |
175 | 171 | ||
176 | int __weak kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt) | 172 | int __weak kgdb_arch_remove_breakpoint(unsigned long addr, char *bundle) |
177 | { | 173 | { |
178 | return probe_kernel_write((char *)bpt->bpt_addr, | 174 | return probe_kernel_write((char *)addr, |
179 | (char *)bpt->saved_instr, BREAK_INSTR_SIZE); | 175 | (char *)bundle, BREAK_INSTR_SIZE); |
180 | } | 176 | } |
181 | 177 | ||
182 | int __weak kgdb_validate_break_address(unsigned long addr) | 178 | int __weak kgdb_validate_break_address(unsigned long addr) |
183 | { | 179 | { |
184 | struct kgdb_bkpt tmp; | 180 | char tmp_variable[BREAK_INSTR_SIZE]; |
185 | int err; | 181 | int err; |
186 | /* Validate setting the breakpoint and then removing it. If the | 182 | /* Validate setting the breakpoint and then removing it. In the |
187 | * remove fails, the kernel needs to emit a bad message because we | 183 | * remove fails, the kernel needs to emit a bad message because we |
188 | * are deep trouble not being able to put things back the way we | 184 | * are deep trouble not being able to put things back the way we |
189 | * found them. | 185 | * found them. |
190 | */ | 186 | */ |
191 | tmp.bpt_addr = addr; | 187 | err = kgdb_arch_set_breakpoint(addr, tmp_variable); |
192 | err = kgdb_arch_set_breakpoint(&tmp); | ||
193 | if (err) | 188 | if (err) |
194 | return err; | 189 | return err; |
195 | err = kgdb_arch_remove_breakpoint(&tmp); | 190 | err = kgdb_arch_remove_breakpoint(addr, tmp_variable); |
196 | if (err) | 191 | if (err) |
197 | printk(KERN_ERR "KGDB: Critical breakpoint error, kernel " | 192 | printk(KERN_ERR "KGDB: Critical breakpoint error, kernel " |
198 | "memory destroyed at: %lx", addr); | 193 | "memory destroyed at: %lx", addr); |
@@ -236,6 +231,7 @@ static void kgdb_flush_swbreak_addr(unsigned long addr) | |||
236 | */ | 231 | */ |
237 | int dbg_activate_sw_breakpoints(void) | 232 | int dbg_activate_sw_breakpoints(void) |
238 | { | 233 | { |
234 | unsigned long addr; | ||
239 | int error; | 235 | int error; |
240 | int ret = 0; | 236 | int ret = 0; |
241 | int i; | 237 | int i; |
@@ -244,15 +240,16 @@ int dbg_activate_sw_breakpoints(void) | |||
244 | if (kgdb_break[i].state != BP_SET) | 240 | if (kgdb_break[i].state != BP_SET) |
245 | continue; | 241 | continue; |
246 | 242 | ||
247 | error = kgdb_arch_set_breakpoint(&kgdb_break[i]); | 243 | addr = kgdb_break[i].bpt_addr; |
244 | error = kgdb_arch_set_breakpoint(addr, | ||
245 | kgdb_break[i].saved_instr); | ||
248 | if (error) { | 246 | if (error) { |
249 | ret = error; | 247 | ret = error; |
250 | printk(KERN_INFO "KGDB: BP install failed: %lx", | 248 | printk(KERN_INFO "KGDB: BP install failed: %lx", addr); |
251 | kgdb_break[i].bpt_addr); | ||
252 | continue; | 249 | continue; |
253 | } | 250 | } |
254 | 251 | ||
255 | kgdb_flush_swbreak_addr(kgdb_break[i].bpt_addr); | 252 | kgdb_flush_swbreak_addr(addr); |
256 | kgdb_break[i].state = BP_ACTIVE; | 253 | kgdb_break[i].state = BP_ACTIVE; |
257 | } | 254 | } |
258 | return ret; | 255 | return ret; |
@@ -301,6 +298,7 @@ int dbg_set_sw_break(unsigned long addr) | |||
301 | 298 | ||
302 | int dbg_deactivate_sw_breakpoints(void) | 299 | int dbg_deactivate_sw_breakpoints(void) |
303 | { | 300 | { |
301 | unsigned long addr; | ||
304 | int error; | 302 | int error; |
305 | int ret = 0; | 303 | int ret = 0; |
306 | int i; | 304 | int i; |
@@ -308,14 +306,15 @@ int dbg_deactivate_sw_breakpoints(void) | |||
308 | for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) { | 306 | for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) { |
309 | if (kgdb_break[i].state != BP_ACTIVE) | 307 | if (kgdb_break[i].state != BP_ACTIVE) |
310 | continue; | 308 | continue; |
311 | error = kgdb_arch_remove_breakpoint(&kgdb_break[i]); | 309 | addr = kgdb_break[i].bpt_addr; |
310 | error = kgdb_arch_remove_breakpoint(addr, | ||
311 | kgdb_break[i].saved_instr); | ||
312 | if (error) { | 312 | if (error) { |
313 | printk(KERN_INFO "KGDB: BP remove failed: %lx\n", | 313 | printk(KERN_INFO "KGDB: BP remove failed: %lx\n", addr); |
314 | kgdb_break[i].bpt_addr); | ||
315 | ret = error; | 314 | ret = error; |
316 | } | 315 | } |
317 | 316 | ||
318 | kgdb_flush_swbreak_addr(kgdb_break[i].bpt_addr); | 317 | kgdb_flush_swbreak_addr(addr); |
319 | kgdb_break[i].state = BP_SET; | 318 | kgdb_break[i].state = BP_SET; |
320 | } | 319 | } |
321 | return ret; | 320 | return ret; |
@@ -349,6 +348,7 @@ int kgdb_isremovedbreak(unsigned long addr) | |||
349 | 348 | ||
350 | int dbg_remove_all_break(void) | 349 | int dbg_remove_all_break(void) |
351 | { | 350 | { |
351 | unsigned long addr; | ||
352 | int error; | 352 | int error; |
353 | int i; | 353 | int i; |
354 | 354 | ||
@@ -356,10 +356,12 @@ int dbg_remove_all_break(void) | |||
356 | for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) { | 356 | for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) { |
357 | if (kgdb_break[i].state != BP_ACTIVE) | 357 | if (kgdb_break[i].state != BP_ACTIVE) |
358 | goto setundefined; | 358 | goto setundefined; |
359 | error = kgdb_arch_remove_breakpoint(&kgdb_break[i]); | 359 | addr = kgdb_break[i].bpt_addr; |
360 | error = kgdb_arch_remove_breakpoint(addr, | ||
361 | kgdb_break[i].saved_instr); | ||
360 | if (error) | 362 | if (error) |
361 | printk(KERN_ERR "KGDB: breakpoint remove failed: %lx\n", | 363 | printk(KERN_ERR "KGDB: breakpoint remove failed: %lx\n", |
362 | kgdb_break[i].bpt_addr); | 364 | addr); |
363 | setundefined: | 365 | setundefined: |
364 | kgdb_break[i].state = BP_UNDEFINED; | 366 | kgdb_break[i].state = BP_UNDEFINED; |
365 | } | 367 | } |
@@ -672,10 +674,6 @@ kgdb_handle_exception(int evector, int signo, int ecode, struct pt_regs *regs) | |||
672 | { | 674 | { |
673 | struct kgdb_state kgdb_var; | 675 | struct kgdb_state kgdb_var; |
674 | struct kgdb_state *ks = &kgdb_var; | 676 | struct kgdb_state *ks = &kgdb_var; |
675 | int ret = 0; | ||
676 | |||
677 | if (arch_kgdb_ops.enable_nmi) | ||
678 | arch_kgdb_ops.enable_nmi(0); | ||
679 | 677 | ||
680 | ks->cpu = raw_smp_processor_id(); | 678 | ks->cpu = raw_smp_processor_id(); |
681 | ks->ex_vector = evector; | 679 | ks->ex_vector = evector; |
@@ -685,33 +683,13 @@ kgdb_handle_exception(int evector, int signo, int ecode, struct pt_regs *regs) | |||
685 | ks->linux_regs = regs; | 683 | ks->linux_regs = regs; |
686 | 684 | ||
687 | if (kgdb_reenter_check(ks)) | 685 | if (kgdb_reenter_check(ks)) |
688 | goto out; /* Ouch, double exception ! */ | 686 | return 0; /* Ouch, double exception ! */ |
689 | if (kgdb_info[ks->cpu].enter_kgdb != 0) | 687 | if (kgdb_info[ks->cpu].enter_kgdb != 0) |
690 | goto out; | 688 | return 0; |
691 | |||
692 | ret = kgdb_cpu_enter(ks, regs, DCPU_WANT_MASTER); | ||
693 | out: | ||
694 | if (arch_kgdb_ops.enable_nmi) | ||
695 | arch_kgdb_ops.enable_nmi(1); | ||
696 | return ret; | ||
697 | } | ||
698 | |||
699 | /* | ||
700 | * GDB places a breakpoint at this function to know dynamically | ||
701 | * loaded objects. It's not defined static so that only one instance with this | ||
702 | * name exists in the kernel. | ||
703 | */ | ||
704 | 689 | ||
705 | static int module_event(struct notifier_block *self, unsigned long val, | 690 | return kgdb_cpu_enter(ks, regs, DCPU_WANT_MASTER); |
706 | void *data) | ||
707 | { | ||
708 | return 0; | ||
709 | } | 691 | } |
710 | 692 | ||
711 | static struct notifier_block dbg_module_load_nb = { | ||
712 | .notifier_call = module_event, | ||
713 | }; | ||
714 | |||
715 | int kgdb_nmicallback(int cpu, void *regs) | 693 | int kgdb_nmicallback(int cpu, void *regs) |
716 | { | 694 | { |
717 | #ifdef CONFIG_SMP | 695 | #ifdef CONFIG_SMP |
@@ -806,33 +784,6 @@ void __init dbg_late_init(void) | |||
806 | kdb_init(KDB_INIT_FULL); | 784 | kdb_init(KDB_INIT_FULL); |
807 | } | 785 | } |
808 | 786 | ||
809 | static int | ||
810 | dbg_notify_reboot(struct notifier_block *this, unsigned long code, void *x) | ||
811 | { | ||
812 | /* | ||
813 | * Take the following action on reboot notify depending on value: | ||
814 | * 1 == Enter debugger | ||
815 | * 0 == [the default] detatch debug client | ||
816 | * -1 == Do nothing... and use this until the board resets | ||
817 | */ | ||
818 | switch (kgdbreboot) { | ||
819 | case 1: | ||
820 | kgdb_breakpoint(); | ||
821 | case -1: | ||
822 | goto done; | ||
823 | } | ||
824 | if (!dbg_kdb_mode) | ||
825 | gdbstub_exit(code); | ||
826 | done: | ||
827 | return NOTIFY_DONE; | ||
828 | } | ||
829 | |||
830 | static struct notifier_block dbg_reboot_notifier = { | ||
831 | .notifier_call = dbg_notify_reboot, | ||
832 | .next = NULL, | ||
833 | .priority = INT_MAX, | ||
834 | }; | ||
835 | |||
836 | static void kgdb_register_callbacks(void) | 787 | static void kgdb_register_callbacks(void) |
837 | { | 788 | { |
838 | if (!kgdb_io_module_registered) { | 789 | if (!kgdb_io_module_registered) { |
@@ -840,8 +791,6 @@ static void kgdb_register_callbacks(void) | |||
840 | kgdb_arch_init(); | 791 | kgdb_arch_init(); |
841 | if (!dbg_is_early) | 792 | if (!dbg_is_early) |
842 | kgdb_arch_late(); | 793 | kgdb_arch_late(); |
843 | register_module_notifier(&dbg_module_load_nb); | ||
844 | register_reboot_notifier(&dbg_reboot_notifier); | ||
845 | atomic_notifier_chain_register(&panic_notifier_list, | 794 | atomic_notifier_chain_register(&panic_notifier_list, |
846 | &kgdb_panic_event_nb); | 795 | &kgdb_panic_event_nb); |
847 | #ifdef CONFIG_MAGIC_SYSRQ | 796 | #ifdef CONFIG_MAGIC_SYSRQ |
@@ -863,8 +812,6 @@ static void kgdb_unregister_callbacks(void) | |||
863 | */ | 812 | */ |
864 | if (kgdb_io_module_registered) { | 813 | if (kgdb_io_module_registered) { |
865 | kgdb_io_module_registered = 0; | 814 | kgdb_io_module_registered = 0; |
866 | unregister_reboot_notifier(&dbg_reboot_notifier); | ||
867 | unregister_module_notifier(&dbg_module_load_nb); | ||
868 | atomic_notifier_chain_unregister(&panic_notifier_list, | 815 | atomic_notifier_chain_unregister(&panic_notifier_list, |
869 | &kgdb_panic_event_nb); | 816 | &kgdb_panic_event_nb); |
870 | kgdb_arch_exit(); | 817 | kgdb_arch_exit(); |
diff --git a/kernel/debug/gdbstub.c b/kernel/debug/gdbstub.c index ce615e06448..34872482315 100644 --- a/kernel/debug/gdbstub.c +++ b/kernel/debug/gdbstub.c | |||
@@ -217,7 +217,7 @@ void gdbstub_msg_write(const char *s, int len) | |||
217 | 217 | ||
218 | /* Pack in hex chars */ | 218 | /* Pack in hex chars */ |
219 | for (i = 0; i < wcount; i++) | 219 | for (i = 0; i < wcount; i++) |
220 | bufptr = hex_byte_pack(bufptr, s[i]); | 220 | bufptr = pack_hex_byte(bufptr, s[i]); |
221 | *bufptr = '\0'; | 221 | *bufptr = '\0'; |
222 | 222 | ||
223 | /* Move up */ | 223 | /* Move up */ |
@@ -249,7 +249,7 @@ char *kgdb_mem2hex(char *mem, char *buf, int count) | |||
249 | if (err) | 249 | if (err) |
250 | return NULL; | 250 | return NULL; |
251 | while (count > 0) { | 251 | while (count > 0) { |
252 | buf = hex_byte_pack(buf, *tmp); | 252 | buf = pack_hex_byte(buf, *tmp); |
253 | tmp++; | 253 | tmp++; |
254 | count--; | 254 | count--; |
255 | } | 255 | } |
@@ -411,14 +411,14 @@ static char *pack_threadid(char *pkt, unsigned char *id) | |||
411 | limit = id + (BUF_THREAD_ID_SIZE / 2); | 411 | limit = id + (BUF_THREAD_ID_SIZE / 2); |
412 | while (id < limit) { | 412 | while (id < limit) { |
413 | if (!lzero || *id != 0) { | 413 | if (!lzero || *id != 0) { |
414 | pkt = hex_byte_pack(pkt, *id); | 414 | pkt = pack_hex_byte(pkt, *id); |
415 | lzero = 0; | 415 | lzero = 0; |
416 | } | 416 | } |
417 | id++; | 417 | id++; |
418 | } | 418 | } |
419 | 419 | ||
420 | if (lzero) | 420 | if (lzero) |
421 | pkt = hex_byte_pack(pkt, 0); | 421 | pkt = pack_hex_byte(pkt, 0); |
422 | 422 | ||
423 | return pkt; | 423 | return pkt; |
424 | } | 424 | } |
@@ -486,7 +486,7 @@ static void gdb_cmd_status(struct kgdb_state *ks) | |||
486 | dbg_remove_all_break(); | 486 | dbg_remove_all_break(); |
487 | 487 | ||
488 | remcom_out_buffer[0] = 'S'; | 488 | remcom_out_buffer[0] = 'S'; |
489 | hex_byte_pack(&remcom_out_buffer[1], ks->signo); | 489 | pack_hex_byte(&remcom_out_buffer[1], ks->signo); |
490 | } | 490 | } |
491 | 491 | ||
492 | static void gdb_get_regs_helper(struct kgdb_state *ks) | 492 | static void gdb_get_regs_helper(struct kgdb_state *ks) |
@@ -954,7 +954,7 @@ int gdb_serial_stub(struct kgdb_state *ks) | |||
954 | /* Reply to host that an exception has occurred */ | 954 | /* Reply to host that an exception has occurred */ |
955 | ptr = remcom_out_buffer; | 955 | ptr = remcom_out_buffer; |
956 | *ptr++ = 'T'; | 956 | *ptr++ = 'T'; |
957 | ptr = hex_byte_pack(ptr, ks->signo); | 957 | ptr = pack_hex_byte(ptr, ks->signo); |
958 | ptr += strlen(strcpy(ptr, "thread:")); | 958 | ptr += strlen(strcpy(ptr, "thread:")); |
959 | int_to_threadref(thref, shadow_pid(current->pid)); | 959 | int_to_threadref(thref, shadow_pid(current->pid)); |
960 | ptr = pack_threadid(ptr, thref); | 960 | ptr = pack_threadid(ptr, thref); |
@@ -1111,13 +1111,6 @@ void gdbstub_exit(int status) | |||
1111 | unsigned char checksum, ch, buffer[3]; | 1111 | unsigned char checksum, ch, buffer[3]; |
1112 | int loop; | 1112 | int loop; |
1113 | 1113 | ||
1114 | if (!kgdb_connected) | ||
1115 | return; | ||
1116 | kgdb_connected = 0; | ||
1117 | |||
1118 | if (!dbg_io_ops || dbg_kdb_mode) | ||
1119 | return; | ||
1120 | |||
1121 | buffer[0] = 'W'; | 1114 | buffer[0] = 'W'; |
1122 | buffer[1] = hex_asc_hi(status); | 1115 | buffer[1] = hex_asc_hi(status); |
1123 | buffer[2] = hex_asc_lo(status); | 1116 | buffer[2] = hex_asc_lo(status); |
@@ -1136,6 +1129,5 @@ void gdbstub_exit(int status) | |||
1136 | dbg_io_ops->write_char(hex_asc_lo(checksum)); | 1129 | dbg_io_ops->write_char(hex_asc_lo(checksum)); |
1137 | 1130 | ||
1138 | /* make sure the output is flushed, lest the bootloader clobber it */ | 1131 | /* make sure the output is flushed, lest the bootloader clobber it */ |
1139 | if (dbg_io_ops->flush) | 1132 | dbg_io_ops->flush(); |
1140 | dbg_io_ops->flush(); | ||
1141 | } | 1133 | } |
diff --git a/kernel/debug/kdb/kdb_bp.c b/kernel/debug/kdb/kdb_bp.c index 8418c2f8ec5..20059ef4459 100644 --- a/kernel/debug/kdb/kdb_bp.c +++ b/kernel/debug/kdb/kdb_bp.c | |||
@@ -153,13 +153,6 @@ static int _kdb_bp_install(struct pt_regs *regs, kdb_bp_t *bp) | |||
153 | } else { | 153 | } else { |
154 | kdb_printf("%s: failed to set breakpoint at 0x%lx\n", | 154 | kdb_printf("%s: failed to set breakpoint at 0x%lx\n", |
155 | __func__, bp->bp_addr); | 155 | __func__, bp->bp_addr); |
156 | #ifdef CONFIG_DEBUG_RODATA | ||
157 | if (!bp->bp_type) { | ||
158 | kdb_printf("Software breakpoints are unavailable.\n" | ||
159 | " Change the kernel CONFIG_DEBUG_RODATA=n\n" | ||
160 | " OR use hw breaks: help bph\n"); | ||
161 | } | ||
162 | #endif | ||
163 | return 1; | 156 | return 1; |
164 | } | 157 | } |
165 | return 0; | 158 | return 0; |
diff --git a/kernel/debug/kdb/kdb_bt.c b/kernel/debug/kdb/kdb_bt.c index b03e0e814e4..7179eac7b41 100644 --- a/kernel/debug/kdb/kdb_bt.c +++ b/kernel/debug/kdb/kdb_bt.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/sched.h> | 15 | #include <linux/sched.h> |
16 | #include <linux/kdb.h> | 16 | #include <linux/kdb.h> |
17 | #include <linux/nmi.h> | 17 | #include <linux/nmi.h> |
18 | #include <asm/system.h> | ||
18 | #include "kdb_private.h" | 19 | #include "kdb_private.h" |
19 | 20 | ||
20 | 21 | ||
@@ -129,8 +130,6 @@ kdb_bt(int argc, const char **argv) | |||
129 | } | 130 | } |
130 | /* Now the inactive tasks */ | 131 | /* Now the inactive tasks */ |
131 | kdb_do_each_thread(g, p) { | 132 | kdb_do_each_thread(g, p) { |
132 | if (KDB_FLAG(CMD_INTERRUPT)) | ||
133 | return 0; | ||
134 | if (task_curr(p)) | 133 | if (task_curr(p)) |
135 | continue; | 134 | continue; |
136 | if (kdb_bt1(p, mask, argcount, btaprompt)) | 135 | if (kdb_bt1(p, mask, argcount, btaprompt)) |
diff --git a/kernel/debug/kdb/kdb_debugger.c b/kernel/debug/kdb/kdb_debugger.c index be7b33b73d3..d9ca9aa481e 100644 --- a/kernel/debug/kdb/kdb_debugger.c +++ b/kernel/debug/kdb/kdb_debugger.c | |||
@@ -11,8 +11,6 @@ | |||
11 | #include <linux/kgdb.h> | 11 | #include <linux/kgdb.h> |
12 | #include <linux/kdb.h> | 12 | #include <linux/kdb.h> |
13 | #include <linux/kdebug.h> | 13 | #include <linux/kdebug.h> |
14 | #include <linux/export.h> | ||
15 | #include <linux/hardirq.h> | ||
16 | #include "kdb_private.h" | 14 | #include "kdb_private.h" |
17 | #include "../debug_core.h" | 15 | #include "../debug_core.h" |
18 | 16 | ||
@@ -53,9 +51,6 @@ int kdb_stub(struct kgdb_state *ks) | |||
53 | if (atomic_read(&kgdb_setting_breakpoint)) | 51 | if (atomic_read(&kgdb_setting_breakpoint)) |
54 | reason = KDB_REASON_KEYBOARD; | 52 | reason = KDB_REASON_KEYBOARD; |
55 | 53 | ||
56 | if (in_nmi()) | ||
57 | reason = KDB_REASON_NMI; | ||
58 | |||
59 | for (i = 0, bp = kdb_breakpoints; i < KDB_MAXBPT; i++, bp++) { | 54 | for (i = 0, bp = kdb_breakpoints; i < KDB_MAXBPT; i++, bp++) { |
60 | if ((bp->bp_enabled) && (bp->bp_addr == addr)) { | 55 | if ((bp->bp_enabled) && (bp->bp_addr == addr)) { |
61 | reason = KDB_REASON_BREAK; | 56 | reason = KDB_REASON_BREAK; |
diff --git a/kernel/debug/kdb/kdb_io.c b/kernel/debug/kdb/kdb_io.c index 14ff4849262..4802eb5840e 100644 --- a/kernel/debug/kdb/kdb_io.c +++ b/kernel/debug/kdb/kdb_io.c | |||
@@ -552,7 +552,6 @@ int vkdb_printf(const char *fmt, va_list ap) | |||
552 | { | 552 | { |
553 | int diag; | 553 | int diag; |
554 | int linecount; | 554 | int linecount; |
555 | int colcount; | ||
556 | int logging, saved_loglevel = 0; | 555 | int logging, saved_loglevel = 0; |
557 | int saved_trap_printk; | 556 | int saved_trap_printk; |
558 | int got_printf_lock = 0; | 557 | int got_printf_lock = 0; |
@@ -585,10 +584,6 @@ int vkdb_printf(const char *fmt, va_list ap) | |||
585 | if (diag || linecount <= 1) | 584 | if (diag || linecount <= 1) |
586 | linecount = 24; | 585 | linecount = 24; |
587 | 586 | ||
588 | diag = kdbgetintenv("COLUMNS", &colcount); | ||
589 | if (diag || colcount <= 1) | ||
590 | colcount = 80; | ||
591 | |||
592 | diag = kdbgetintenv("LOGGING", &logging); | 587 | diag = kdbgetintenv("LOGGING", &logging); |
593 | if (diag) | 588 | if (diag) |
594 | logging = 0; | 589 | logging = 0; |
@@ -694,8 +689,8 @@ kdb_printit: | |||
694 | if (!dbg_kdb_mode && kgdb_connected) { | 689 | if (!dbg_kdb_mode && kgdb_connected) { |
695 | gdbstub_msg_write(kdb_buffer, retlen); | 690 | gdbstub_msg_write(kdb_buffer, retlen); |
696 | } else { | 691 | } else { |
697 | if (dbg_io_ops && !dbg_io_ops->is_console) { | 692 | if (!dbg_io_ops->is_console) { |
698 | len = retlen; | 693 | len = strlen(kdb_buffer); |
699 | cp = kdb_buffer; | 694 | cp = kdb_buffer; |
700 | while (len--) { | 695 | while (len--) { |
701 | dbg_io_ops->write_char(*cp); | 696 | dbg_io_ops->write_char(*cp); |
@@ -714,30 +709,15 @@ kdb_printit: | |||
714 | printk(KERN_INFO "%s", kdb_buffer); | 709 | printk(KERN_INFO "%s", kdb_buffer); |
715 | } | 710 | } |
716 | 711 | ||
717 | if (KDB_STATE(PAGER)) { | 712 | if (KDB_STATE(PAGER) && strchr(kdb_buffer, '\n')) |
718 | /* | 713 | kdb_nextline++; |
719 | * Check printed string to decide how to bump the | ||
720 | * kdb_nextline to control when the more prompt should | ||
721 | * show up. | ||
722 | */ | ||
723 | int got = 0; | ||
724 | len = retlen; | ||
725 | while (len--) { | ||
726 | if (kdb_buffer[len] == '\n') { | ||
727 | kdb_nextline++; | ||
728 | got = 0; | ||
729 | } else if (kdb_buffer[len] == '\r') { | ||
730 | got = 0; | ||
731 | } else { | ||
732 | got++; | ||
733 | } | ||
734 | } | ||
735 | kdb_nextline += got / (colcount + 1); | ||
736 | } | ||
737 | 714 | ||
738 | /* check for having reached the LINES number of printed lines */ | 715 | /* check for having reached the LINES number of printed lines */ |
739 | if (kdb_nextline >= linecount) { | 716 | if (kdb_nextline == linecount) { |
740 | char buf1[16] = ""; | 717 | char buf1[16] = ""; |
718 | #if defined(CONFIG_SMP) | ||
719 | char buf2[32]; | ||
720 | #endif | ||
741 | 721 | ||
742 | /* Watch out for recursion here. Any routine that calls | 722 | /* Watch out for recursion here. Any routine that calls |
743 | * kdb_printf will come back through here. And kdb_read | 723 | * kdb_printf will come back through here. And kdb_read |
@@ -752,10 +732,18 @@ kdb_printit: | |||
752 | if (moreprompt == NULL) | 732 | if (moreprompt == NULL) |
753 | moreprompt = "more> "; | 733 | moreprompt = "more> "; |
754 | 734 | ||
735 | #if defined(CONFIG_SMP) | ||
736 | if (strchr(moreprompt, '%')) { | ||
737 | sprintf(buf2, moreprompt, get_cpu()); | ||
738 | put_cpu(); | ||
739 | moreprompt = buf2; | ||
740 | } | ||
741 | #endif | ||
742 | |||
755 | kdb_input_flush(); | 743 | kdb_input_flush(); |
756 | c = console_drivers; | 744 | c = console_drivers; |
757 | 745 | ||
758 | if (dbg_io_ops && !dbg_io_ops->is_console) { | 746 | if (!dbg_io_ops->is_console) { |
759 | len = strlen(moreprompt); | 747 | len = strlen(moreprompt); |
760 | cp = moreprompt; | 748 | cp = moreprompt; |
761 | while (len--) { | 749 | while (len--) { |
@@ -788,7 +776,7 @@ kdb_printit: | |||
788 | kdb_grepping_flag = 0; | 776 | kdb_grepping_flag = 0; |
789 | kdb_printf("\n"); | 777 | kdb_printf("\n"); |
790 | } else if (buf1[0] == ' ') { | 778 | } else if (buf1[0] == ' ') { |
791 | kdb_printf("\r"); | 779 | kdb_printf("\n"); |
792 | suspend_grep = 1; /* for this recursion */ | 780 | suspend_grep = 1; /* for this recursion */ |
793 | } else if (buf1[0] == '\n') { | 781 | } else if (buf1[0] == '\n') { |
794 | kdb_nextline = linecount - 1; | 782 | kdb_nextline = linecount - 1; |
diff --git a/kernel/debug/kdb/kdb_keyboard.c b/kernel/debug/kdb/kdb_keyboard.c index 118527aa60e..4bca634975c 100644 --- a/kernel/debug/kdb/kdb_keyboard.c +++ b/kernel/debug/kdb/kdb_keyboard.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #define KBD_STAT_MOUSE_OBF 0x20 /* Mouse output buffer full */ | 25 | #define KBD_STAT_MOUSE_OBF 0x20 /* Mouse output buffer full */ |
26 | 26 | ||
27 | static int kbd_exists; | 27 | static int kbd_exists; |
28 | static int kbd_last_ret; | ||
29 | 28 | ||
30 | /* | 29 | /* |
31 | * Check if the keyboard controller has a keypress for us. | 30 | * Check if the keyboard controller has a keypress for us. |
@@ -91,11 +90,8 @@ int kdb_get_kbd_char(void) | |||
91 | return -1; | 90 | return -1; |
92 | } | 91 | } |
93 | 92 | ||
94 | if ((scancode & 0x80) != 0) { | 93 | if ((scancode & 0x80) != 0) |
95 | if (scancode == 0x9c) | ||
96 | kbd_last_ret = 0; | ||
97 | return -1; | 94 | return -1; |
98 | } | ||
99 | 95 | ||
100 | scancode &= 0x7f; | 96 | scancode &= 0x7f; |
101 | 97 | ||
@@ -182,82 +178,35 @@ int kdb_get_kbd_char(void) | |||
182 | return -1; /* ignore unprintables */ | 178 | return -1; /* ignore unprintables */ |
183 | } | 179 | } |
184 | 180 | ||
185 | if (scancode == 0x1c) { | 181 | if ((scancode & 0x7f) == 0x1c) { |
186 | kbd_last_ret = 1; | 182 | /* |
187 | return 13; | 183 | * enter key. All done. Absorb the release scancode. |
188 | } | 184 | */ |
189 | |||
190 | return keychar & 0xff; | ||
191 | } | ||
192 | EXPORT_SYMBOL_GPL(kdb_get_kbd_char); | ||
193 | |||
194 | /* | ||
195 | * Best effort cleanup of ENTER break codes on leaving KDB. Called on | ||
196 | * exiting KDB, when we know we processed an ENTER or KP ENTER scan | ||
197 | * code. | ||
198 | */ | ||
199 | void kdb_kbd_cleanup_state(void) | ||
200 | { | ||
201 | int scancode, scanstatus; | ||
202 | |||
203 | /* | ||
204 | * Nothing to clean up, since either | ||
205 | * ENTER was never pressed, or has already | ||
206 | * gotten cleaned up. | ||
207 | */ | ||
208 | if (!kbd_last_ret) | ||
209 | return; | ||
210 | |||
211 | kbd_last_ret = 0; | ||
212 | /* | ||
213 | * Enter key. Need to absorb the break code here, lest it gets | ||
214 | * leaked out if we exit KDB as the result of processing 'g'. | ||
215 | * | ||
216 | * This has several interesting implications: | ||
217 | * + Need to handle KP ENTER, which has break code 0xe0 0x9c. | ||
218 | * + Need to handle repeat ENTER and repeat KP ENTER. Repeats | ||
219 | * only get a break code at the end of the repeated | ||
220 | * sequence. This means we can't propagate the repeated key | ||
221 | * press, and must swallow it away. | ||
222 | * + Need to handle possible PS/2 mouse input. | ||
223 | * + Need to handle mashed keys. | ||
224 | */ | ||
225 | |||
226 | while (1) { | ||
227 | while ((inb(KBD_STATUS_REG) & KBD_STAT_OBF) == 0) | 185 | while ((inb(KBD_STATUS_REG) & KBD_STAT_OBF) == 0) |
228 | cpu_relax(); | 186 | ; |
229 | 187 | ||
230 | /* | 188 | /* |
231 | * Fetch the scancode. | 189 | * Fetch the scancode |
232 | */ | 190 | */ |
233 | scancode = inb(KBD_DATA_REG); | 191 | scancode = inb(KBD_DATA_REG); |
234 | scanstatus = inb(KBD_STATUS_REG); | 192 | scanstatus = inb(KBD_STATUS_REG); |
235 | 193 | ||
236 | /* | 194 | while (scanstatus & KBD_STAT_MOUSE_OBF) { |
237 | * Skip mouse input. | 195 | scancode = inb(KBD_DATA_REG); |
238 | */ | 196 | scanstatus = inb(KBD_STATUS_REG); |
239 | if (scanstatus & KBD_STAT_MOUSE_OBF) | 197 | } |
240 | continue; | ||
241 | 198 | ||
242 | /* | 199 | if (scancode != 0x9c) { |
243 | * If we see 0xe0, this is either a break code for KP | 200 | /* |
244 | * ENTER, or a repeat make for KP ENTER. Either way, | 201 | * Wasn't an enter-release, why not? |
245 | * since the second byte is equivalent to an ENTER, | 202 | */ |
246 | * skip the 0xe0 and try again. | 203 | kdb_printf("kdb: expected enter got 0x%x status 0x%x\n", |
247 | * | 204 | scancode, scanstatus); |
248 | * If we see 0x1c, this must be a repeat ENTER or KP | 205 | } |
249 | * ENTER (and we swallowed 0xe0 before). Try again. | ||
250 | * | ||
251 | * We can also see make and break codes for other keys | ||
252 | * mashed before or after pressing ENTER. Thus, if we | ||
253 | * see anything other than 0x9c, we have to try again. | ||
254 | * | ||
255 | * Note, if you held some key as ENTER was depressed, | ||
256 | * that break code would get leaked out. | ||
257 | */ | ||
258 | if (scancode != 0x9c) | ||
259 | continue; | ||
260 | 206 | ||
261 | return; | 207 | return 13; |
262 | } | 208 | } |
209 | |||
210 | return keychar & 0xff; | ||
263 | } | 211 | } |
212 | EXPORT_SYMBOL_GPL(kdb_get_kbd_char); | ||
diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c index 4d5f8d5612f..63786e71a3c 100644 --- a/kernel/debug/kdb/kdb_main.c +++ b/kernel/debug/kdb/kdb_main.c | |||
@@ -14,14 +14,12 @@ | |||
14 | #include <linux/ctype.h> | 14 | #include <linux/ctype.h> |
15 | #include <linux/string.h> | 15 | #include <linux/string.h> |
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/kmsg_dump.h> | ||
18 | #include <linux/reboot.h> | 17 | #include <linux/reboot.h> |
19 | #include <linux/sched.h> | 18 | #include <linux/sched.h> |
20 | #include <linux/sysrq.h> | 19 | #include <linux/sysrq.h> |
21 | #include <linux/smp.h> | 20 | #include <linux/smp.h> |
22 | #include <linux/utsname.h> | 21 | #include <linux/utsname.h> |
23 | #include <linux/vmalloc.h> | 22 | #include <linux/vmalloc.h> |
24 | #include <linux/atomic.h> | ||
25 | #include <linux/module.h> | 23 | #include <linux/module.h> |
26 | #include <linux/mm.h> | 24 | #include <linux/mm.h> |
27 | #include <linux/init.h> | 25 | #include <linux/init.h> |
@@ -140,10 +138,11 @@ static const int __nkdb_err = sizeof(kdbmsgs) / sizeof(kdbmsg_t); | |||
140 | static char *__env[] = { | 138 | static char *__env[] = { |
141 | #if defined(CONFIG_SMP) | 139 | #if defined(CONFIG_SMP) |
142 | "PROMPT=[%d]kdb> ", | 140 | "PROMPT=[%d]kdb> ", |
141 | "MOREPROMPT=[%d]more> ", | ||
143 | #else | 142 | #else |
144 | "PROMPT=kdb> ", | 143 | "PROMPT=kdb> ", |
145 | #endif | ||
146 | "MOREPROMPT=more> ", | 144 | "MOREPROMPT=more> ", |
145 | #endif | ||
147 | "RADIX=16", | 146 | "RADIX=16", |
148 | "MDCOUNT=8", /* lines of md output */ | 147 | "MDCOUNT=8", /* lines of md output */ |
149 | KDB_PLATFORM_ENV, | 148 | KDB_PLATFORM_ENV, |
@@ -1236,6 +1235,18 @@ static int kdb_local(kdb_reason_t reason, int error, struct pt_regs *regs, | |||
1236 | *cmdbuf = '\0'; | 1235 | *cmdbuf = '\0'; |
1237 | *(cmd_hist[cmd_head]) = '\0'; | 1236 | *(cmd_hist[cmd_head]) = '\0'; |
1238 | 1237 | ||
1238 | if (KDB_FLAG(ONLY_DO_DUMP)) { | ||
1239 | /* kdb is off but a catastrophic error requires a dump. | ||
1240 | * Take the dump and reboot. | ||
1241 | * Turn on logging so the kdb output appears in the log | ||
1242 | * buffer in the dump. | ||
1243 | */ | ||
1244 | const char *setargs[] = { "set", "LOGGING", "1" }; | ||
1245 | kdb_set(2, setargs); | ||
1246 | kdb_reboot(0, NULL); | ||
1247 | /*NOTREACHED*/ | ||
1248 | } | ||
1249 | |||
1239 | do_full_getstr: | 1250 | do_full_getstr: |
1240 | #if defined(CONFIG_SMP) | 1251 | #if defined(CONFIG_SMP) |
1241 | snprintf(kdb_prompt_str, CMD_BUFLEN, kdbgetenv("PROMPT"), | 1252 | snprintf(kdb_prompt_str, CMD_BUFLEN, kdbgetenv("PROMPT"), |
@@ -1389,9 +1400,6 @@ int kdb_main_loop(kdb_reason_t reason, kdb_reason_t reason2, int error, | |||
1389 | if (KDB_STATE(DOING_SS)) | 1400 | if (KDB_STATE(DOING_SS)) |
1390 | KDB_STATE_CLEAR(SSBPT); | 1401 | KDB_STATE_CLEAR(SSBPT); |
1391 | 1402 | ||
1392 | /* Clean up any keyboard devices before leaving */ | ||
1393 | kdb_kbd_cleanup_state(); | ||
1394 | |||
1395 | return result; | 1403 | return result; |
1396 | } | 1404 | } |
1397 | 1405 | ||
@@ -1974,7 +1982,7 @@ static int kdb_lsmod(int argc, const char **argv) | |||
1974 | kdb_printf("%-20s%8u 0x%p ", mod->name, | 1982 | kdb_printf("%-20s%8u 0x%p ", mod->name, |
1975 | mod->core_size, (void *)mod); | 1983 | mod->core_size, (void *)mod); |
1976 | #ifdef CONFIG_MODULE_UNLOAD | 1984 | #ifdef CONFIG_MODULE_UNLOAD |
1977 | kdb_printf("%4ld ", module_refcount(mod)); | 1985 | kdb_printf("%4d ", module_refcount(mod)); |
1978 | #endif | 1986 | #endif |
1979 | if (mod->state == MODULE_STATE_GOING) | 1987 | if (mod->state == MODULE_STATE_GOING) |
1980 | kdb_printf(" (Unloading)"); | 1988 | kdb_printf(" (Unloading)"); |
@@ -2029,15 +2037,8 @@ static int kdb_env(int argc, const char **argv) | |||
2029 | */ | 2037 | */ |
2030 | static int kdb_dmesg(int argc, const char **argv) | 2038 | static int kdb_dmesg(int argc, const char **argv) |
2031 | { | 2039 | { |
2032 | int diag; | 2040 | char *syslog_data[4], *start, *end, c = '\0', *p; |
2033 | int logging; | 2041 | int diag, logging, logsize, lines = 0, adjust = 0, n; |
2034 | int lines = 0; | ||
2035 | int adjust = 0; | ||
2036 | int n = 0; | ||
2037 | int skip = 0; | ||
2038 | struct kmsg_dumper dumper = { .active = 1 }; | ||
2039 | size_t len; | ||
2040 | char buf[201]; | ||
2041 | 2042 | ||
2042 | if (argc > 2) | 2043 | if (argc > 2) |
2043 | return KDB_ARGCOUNT; | 2044 | return KDB_ARGCOUNT; |
@@ -2060,10 +2061,22 @@ static int kdb_dmesg(int argc, const char **argv) | |||
2060 | kdb_set(2, setargs); | 2061 | kdb_set(2, setargs); |
2061 | } | 2062 | } |
2062 | 2063 | ||
2063 | kmsg_dump_rewind_nolock(&dumper); | 2064 | /* syslog_data[0,1] physical start, end+1. syslog_data[2,3] |
2064 | while (kmsg_dump_get_line_nolock(&dumper, 1, NULL, 0, NULL)) | 2065 | * logical start, end+1. */ |
2065 | n++; | 2066 | kdb_syslog_data(syslog_data); |
2066 | 2067 | if (syslog_data[2] == syslog_data[3]) | |
2068 | return 0; | ||
2069 | logsize = syslog_data[1] - syslog_data[0]; | ||
2070 | start = syslog_data[2]; | ||
2071 | end = syslog_data[3]; | ||
2072 | #define KDB_WRAP(p) (((p - syslog_data[0]) % logsize) + syslog_data[0]) | ||
2073 | for (n = 0, p = start; p < end; ++p) { | ||
2074 | c = *KDB_WRAP(p); | ||
2075 | if (c == '\n') | ||
2076 | ++n; | ||
2077 | } | ||
2078 | if (c != '\n') | ||
2079 | ++n; | ||
2067 | if (lines < 0) { | 2080 | if (lines < 0) { |
2068 | if (adjust >= n) | 2081 | if (adjust >= n) |
2069 | kdb_printf("buffer only contains %d lines, nothing " | 2082 | kdb_printf("buffer only contains %d lines, nothing " |
@@ -2071,11 +2084,21 @@ static int kdb_dmesg(int argc, const char **argv) | |||
2071 | else if (adjust - lines >= n) | 2084 | else if (adjust - lines >= n) |
2072 | kdb_printf("buffer only contains %d lines, last %d " | 2085 | kdb_printf("buffer only contains %d lines, last %d " |
2073 | "lines printed\n", n, n - adjust); | 2086 | "lines printed\n", n, n - adjust); |
2074 | skip = adjust; | 2087 | if (adjust) { |
2075 | lines = abs(lines); | 2088 | for (; start < end && adjust; ++start) { |
2089 | if (*KDB_WRAP(start) == '\n') | ||
2090 | --adjust; | ||
2091 | } | ||
2092 | if (start < end) | ||
2093 | ++start; | ||
2094 | } | ||
2095 | for (p = start; p < end && lines; ++p) { | ||
2096 | if (*KDB_WRAP(p) == '\n') | ||
2097 | ++lines; | ||
2098 | } | ||
2099 | end = p; | ||
2076 | } else if (lines > 0) { | 2100 | } else if (lines > 0) { |
2077 | skip = n - lines - adjust; | 2101 | int skip = n - (adjust + lines); |
2078 | lines = abs(lines); | ||
2079 | if (adjust >= n) { | 2102 | if (adjust >= n) { |
2080 | kdb_printf("buffer only contains %d lines, " | 2103 | kdb_printf("buffer only contains %d lines, " |
2081 | "nothing printed\n", n); | 2104 | "nothing printed\n", n); |
@@ -2086,56 +2109,39 @@ static int kdb_dmesg(int argc, const char **argv) | |||
2086 | kdb_printf("buffer only contains %d lines, first " | 2109 | kdb_printf("buffer only contains %d lines, first " |
2087 | "%d lines printed\n", n, lines); | 2110 | "%d lines printed\n", n, lines); |
2088 | } | 2111 | } |
2089 | } else { | 2112 | for (; start < end && skip; ++start) { |
2090 | lines = n; | 2113 | if (*KDB_WRAP(start) == '\n') |
2091 | } | 2114 | --skip; |
2092 | |||
2093 | if (skip >= n || skip < 0) | ||
2094 | return 0; | ||
2095 | |||
2096 | kmsg_dump_rewind_nolock(&dumper); | ||
2097 | while (kmsg_dump_get_line_nolock(&dumper, 1, buf, sizeof(buf), &len)) { | ||
2098 | if (skip) { | ||
2099 | skip--; | ||
2100 | continue; | ||
2101 | } | 2115 | } |
2102 | if (!lines--) | 2116 | for (p = start; p < end && lines; ++p) { |
2103 | break; | 2117 | if (*KDB_WRAP(p) == '\n') |
2118 | --lines; | ||
2119 | } | ||
2120 | end = p; | ||
2121 | } | ||
2122 | /* Do a line at a time (max 200 chars) to reduce protocol overhead */ | ||
2123 | c = '\n'; | ||
2124 | while (start != end) { | ||
2125 | char buf[201]; | ||
2126 | p = buf; | ||
2104 | if (KDB_FLAG(CMD_INTERRUPT)) | 2127 | if (KDB_FLAG(CMD_INTERRUPT)) |
2105 | return 0; | 2128 | return 0; |
2106 | 2129 | while (start < end && (c = *KDB_WRAP(start)) && | |
2107 | kdb_printf("%.*s\n", (int)len - 1, buf); | 2130 | (p - buf) < sizeof(buf)-1) { |
2131 | ++start; | ||
2132 | *p++ = c; | ||
2133 | if (c == '\n') | ||
2134 | break; | ||
2135 | } | ||
2136 | *p = '\0'; | ||
2137 | kdb_printf("%s", buf); | ||
2108 | } | 2138 | } |
2139 | if (c != '\n') | ||
2140 | kdb_printf("\n"); | ||
2109 | 2141 | ||
2110 | return 0; | 2142 | return 0; |
2111 | } | 2143 | } |
2112 | #endif /* CONFIG_PRINTK */ | 2144 | #endif /* CONFIG_PRINTK */ |
2113 | |||
2114 | /* Make sure we balance enable/disable calls, must disable first. */ | ||
2115 | static atomic_t kdb_nmi_disabled; | ||
2116 | |||
2117 | static int kdb_disable_nmi(int argc, const char *argv[]) | ||
2118 | { | ||
2119 | if (atomic_read(&kdb_nmi_disabled)) | ||
2120 | return 0; | ||
2121 | atomic_set(&kdb_nmi_disabled, 1); | ||
2122 | arch_kgdb_ops.enable_nmi(0); | ||
2123 | return 0; | ||
2124 | } | ||
2125 | |||
2126 | static int kdb_param_enable_nmi(const char *val, const struct kernel_param *kp) | ||
2127 | { | ||
2128 | if (!atomic_add_unless(&kdb_nmi_disabled, -1, 0)) | ||
2129 | return -EINVAL; | ||
2130 | arch_kgdb_ops.enable_nmi(1); | ||
2131 | return 0; | ||
2132 | } | ||
2133 | |||
2134 | static const struct kernel_param_ops kdb_param_ops_enable_nmi = { | ||
2135 | .set = kdb_param_enable_nmi, | ||
2136 | }; | ||
2137 | module_param_cb(enable_nmi, &kdb_param_ops_enable_nmi, NULL, 0600); | ||
2138 | |||
2139 | /* | 2145 | /* |
2140 | * kdb_cpu - This function implements the 'cpu' command. | 2146 | * kdb_cpu - This function implements the 'cpu' command. |
2141 | * cpu [<cpunum>] | 2147 | * cpu [<cpunum>] |
@@ -2880,10 +2886,6 @@ static void __init kdb_inittab(void) | |||
2880 | kdb_register_repeat("dmesg", kdb_dmesg, "[lines]", | 2886 | kdb_register_repeat("dmesg", kdb_dmesg, "[lines]", |
2881 | "Display syslog buffer", 0, KDB_REPEAT_NONE); | 2887 | "Display syslog buffer", 0, KDB_REPEAT_NONE); |
2882 | #endif | 2888 | #endif |
2883 | if (arch_kgdb_ops.enable_nmi) { | ||
2884 | kdb_register_repeat("disable_nmi", kdb_disable_nmi, "", | ||
2885 | "Disable NMI entry to KDB", 0, KDB_REPEAT_NONE); | ||
2886 | } | ||
2887 | kdb_register_repeat("defcmd", kdb_defcmd, "name \"usage\" \"help\"", | 2889 | kdb_register_repeat("defcmd", kdb_defcmd, "name \"usage\" \"help\"", |
2888 | "Define a set of commands, down to endefcmd", 0, KDB_REPEAT_NONE); | 2890 | "Define a set of commands, down to endefcmd", 0, KDB_REPEAT_NONE); |
2889 | kdb_register_repeat("kill", kdb_kill, "<-signal> <pid>", | 2891 | kdb_register_repeat("kill", kdb_kill, "<-signal> <pid>", |
diff --git a/kernel/debug/kdb/kdb_private.h b/kernel/debug/kdb/kdb_private.h index 392ec6a2584..e381d105b40 100644 --- a/kernel/debug/kdb/kdb_private.h +++ b/kernel/debug/kdb/kdb_private.h | |||
@@ -205,6 +205,7 @@ extern char kdb_grep_string[]; | |||
205 | extern int kdb_grep_leading; | 205 | extern int kdb_grep_leading; |
206 | extern int kdb_grep_trailing; | 206 | extern int kdb_grep_trailing; |
207 | extern char *kdb_cmds[]; | 207 | extern char *kdb_cmds[]; |
208 | extern void kdb_syslog_data(char *syslog_data[]); | ||
208 | extern unsigned long kdb_task_state_string(const char *); | 209 | extern unsigned long kdb_task_state_string(const char *); |
209 | extern char kdb_task_state_char (const struct task_struct *); | 210 | extern char kdb_task_state_char (const struct task_struct *); |
210 | extern unsigned long kdb_task_state(const struct task_struct *p, | 211 | extern unsigned long kdb_task_state(const struct task_struct *p, |
@@ -245,13 +246,6 @@ extern void debug_kusage(void); | |||
245 | 246 | ||
246 | extern void kdb_set_current_task(struct task_struct *); | 247 | extern void kdb_set_current_task(struct task_struct *); |
247 | extern struct task_struct *kdb_current_task; | 248 | extern struct task_struct *kdb_current_task; |
248 | |||
249 | #ifdef CONFIG_KDB_KEYBOARD | ||
250 | extern void kdb_kbd_cleanup_state(void); | ||
251 | #else /* ! CONFIG_KDB_KEYBOARD */ | ||
252 | #define kdb_kbd_cleanup_state() | ||
253 | #endif /* ! CONFIG_KDB_KEYBOARD */ | ||
254 | |||
255 | #ifdef CONFIG_MODULES | 249 | #ifdef CONFIG_MODULES |
256 | extern struct list_head *kdb_modules; | 250 | extern struct list_head *kdb_modules; |
257 | #endif /* CONFIG_MODULES */ | 251 | #endif /* CONFIG_MODULES */ |
diff --git a/kernel/debug/kdb/kdb_support.c b/kernel/debug/kdb/kdb_support.c index d35cc2d3a4c..5532dd37aa8 100644 --- a/kernel/debug/kdb/kdb_support.c +++ b/kernel/debug/kdb/kdb_support.c | |||
@@ -384,9 +384,9 @@ static int kdb_getphys(void *res, unsigned long addr, size_t size) | |||
384 | if (!pfn_valid(pfn)) | 384 | if (!pfn_valid(pfn)) |
385 | return 1; | 385 | return 1; |
386 | page = pfn_to_page(pfn); | 386 | page = pfn_to_page(pfn); |
387 | vaddr = kmap_atomic(page); | 387 | vaddr = kmap_atomic(page, KM_KDB); |
388 | memcpy(res, vaddr + (addr & (PAGE_SIZE - 1)), size); | 388 | memcpy(res, vaddr + (addr & (PAGE_SIZE - 1)), size); |
389 | kunmap_atomic(vaddr); | 389 | kunmap_atomic(vaddr, KM_KDB); |
390 | 390 | ||
391 | return 0; | 391 | return 0; |
392 | } | 392 | } |
@@ -636,7 +636,7 @@ char kdb_task_state_char (const struct task_struct *p) | |||
636 | (p->exit_state & EXIT_ZOMBIE) ? 'Z' : | 636 | (p->exit_state & EXIT_ZOMBIE) ? 'Z' : |
637 | (p->exit_state & EXIT_DEAD) ? 'E' : | 637 | (p->exit_state & EXIT_DEAD) ? 'E' : |
638 | (p->state & TASK_INTERRUPTIBLE) ? 'S' : '?'; | 638 | (p->state & TASK_INTERRUPTIBLE) ? 'S' : '?'; |
639 | if (is_idle_task(p)) { | 639 | if (p->pid == 0) { |
640 | /* Idle task. Is it really idle, apart from the kdb | 640 | /* Idle task. Is it really idle, apart from the kdb |
641 | * interrupt? */ | 641 | * interrupt? */ |
642 | if (!kdb_task_has_cpu(p) || kgdb_info[cpu].irq_depth == 1) { | 642 | if (!kdb_task_has_cpu(p) || kgdb_info[cpu].irq_depth == 1) { |