aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/debug
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/debug')
-rw-r--r--kernel/debug/debug_core.c107
-rw-r--r--kernel/debug/debug_core.h24
-rw-r--r--kernel/debug/gdbstub.c36
3 files changed, 150 insertions, 17 deletions
diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c
index 7e03969330bc..6e1fa829fdeb 100644
--- a/kernel/debug/debug_core.c
+++ b/kernel/debug/debug_core.c
@@ -43,6 +43,7 @@
43#include <linux/sysrq.h> 43#include <linux/sysrq.h>
44#include <linux/init.h> 44#include <linux/init.h>
45#include <linux/kgdb.h> 45#include <linux/kgdb.h>
46#include <linux/kdb.h>
46#include <linux/pid.h> 47#include <linux/pid.h>
47#include <linux/smp.h> 48#include <linux/smp.h>
48#include <linux/mm.h> 49#include <linux/mm.h>
@@ -77,6 +78,11 @@ static DEFINE_SPINLOCK(kgdb_registration_lock);
77static int kgdb_con_registered; 78static int kgdb_con_registered;
78/* determine if kgdb console output should be used */ 79/* determine if kgdb console output should be used */
79static int kgdb_use_con; 80static int kgdb_use_con;
81/* Next cpu to become the master debug core */
82int dbg_switch_cpu;
83
84/* Use kdb or gdbserver mode */
85static int dbg_kdb_mode = 1;
80 86
81static int __init opt_kgdb_con(char *str) 87static int __init opt_kgdb_con(char *str)
82{ 88{
@@ -100,6 +106,7 @@ static struct kgdb_bkpt kgdb_break[KGDB_MAX_BREAKPOINTS] = {
100 * The CPU# of the active CPU, or -1 if none: 106 * The CPU# of the active CPU, or -1 if none:
101 */ 107 */
102atomic_t kgdb_active = ATOMIC_INIT(-1); 108atomic_t kgdb_active = ATOMIC_INIT(-1);
109EXPORT_SYMBOL_GPL(kgdb_active);
103 110
104/* 111/*
105 * We use NR_CPUs not PERCPU, in case kgdb is used to debug early 112 * We use NR_CPUs not PERCPU, in case kgdb is used to debug early
@@ -301,7 +308,7 @@ int dbg_set_sw_break(unsigned long addr)
301 return 0; 308 return 0;
302} 309}
303 310
304static int kgdb_deactivate_sw_breakpoints(void) 311int dbg_deactivate_sw_breakpoints(void)
305{ 312{
306 unsigned long addr; 313 unsigned long addr;
307 int error; 314 int error;
@@ -395,8 +402,14 @@ static int kgdb_io_ready(int print_wait)
395 return 1; 402 return 1;
396 if (atomic_read(&kgdb_setting_breakpoint)) 403 if (atomic_read(&kgdb_setting_breakpoint))
397 return 1; 404 return 1;
398 if (print_wait) 405 if (print_wait) {
406#ifdef CONFIG_KGDB_KDB
407 if (!dbg_kdb_mode)
408 printk(KERN_CRIT "KGDB: waiting... or $3#33 for KDB\n");
409#else
399 printk(KERN_CRIT "KGDB: Waiting for remote debugger\n"); 410 printk(KERN_CRIT "KGDB: Waiting for remote debugger\n");
411#endif
412 }
400 return 1; 413 return 1;
401} 414}
402 415
@@ -410,7 +423,7 @@ static int kgdb_reenter_check(struct kgdb_state *ks)
410 /* Panic on recursive debugger calls: */ 423 /* Panic on recursive debugger calls: */
411 exception_level++; 424 exception_level++;
412 addr = kgdb_arch_pc(ks->ex_vector, ks->linux_regs); 425 addr = kgdb_arch_pc(ks->ex_vector, ks->linux_regs);
413 kgdb_deactivate_sw_breakpoints(); 426 dbg_deactivate_sw_breakpoints();
414 427
415 /* 428 /*
416 * If the break point removed ok at the place exception 429 * If the break point removed ok at the place exception
@@ -443,11 +456,24 @@ static int kgdb_reenter_check(struct kgdb_state *ks)
443 return 1; 456 return 1;
444} 457}
445 458
459static void dbg_cpu_switch(int cpu, int next_cpu)
460{
461 /* Mark the cpu we are switching away from as a slave when it
462 * holds the kgdb_active token. This must be done so that the
463 * that all the cpus wait in for the debug core will not enter
464 * again as the master. */
465 if (cpu == atomic_read(&kgdb_active)) {
466 kgdb_info[cpu].exception_state |= DCPU_IS_SLAVE;
467 kgdb_info[cpu].exception_state &= ~DCPU_WANT_MASTER;
468 }
469 kgdb_info[next_cpu].exception_state |= DCPU_NEXT_MASTER;
470}
471
446static int kgdb_cpu_enter(struct kgdb_state *ks, struct pt_regs *regs) 472static int kgdb_cpu_enter(struct kgdb_state *ks, struct pt_regs *regs)
447{ 473{
448 unsigned long flags; 474 unsigned long flags;
449 int sstep_tries = 100; 475 int sstep_tries = 100;
450 int error = 0; 476 int error;
451 int i, cpu; 477 int i, cpu;
452 int trace_on = 0; 478 int trace_on = 0;
453acquirelock: 479acquirelock:
@@ -460,6 +486,8 @@ acquirelock:
460 cpu = ks->cpu; 486 cpu = ks->cpu;
461 kgdb_info[cpu].debuggerinfo = regs; 487 kgdb_info[cpu].debuggerinfo = regs;
462 kgdb_info[cpu].task = current; 488 kgdb_info[cpu].task = current;
489 kgdb_info[cpu].ret_state = 0;
490 kgdb_info[cpu].irq_depth = hardirq_count() >> HARDIRQ_SHIFT;
463 /* 491 /*
464 * Make sure the above info reaches the primary CPU before 492 * Make sure the above info reaches the primary CPU before
465 * our cpu_in_kgdb[] flag setting does: 493 * our cpu_in_kgdb[] flag setting does:
@@ -471,7 +499,11 @@ acquirelock:
471 * master cpu and acquire the kgdb_active lock: 499 * master cpu and acquire the kgdb_active lock:
472 */ 500 */
473 while (1) { 501 while (1) {
474 if (kgdb_info[cpu].exception_state & DCPU_WANT_MASTER) { 502cpu_loop:
503 if (kgdb_info[cpu].exception_state & DCPU_NEXT_MASTER) {
504 kgdb_info[cpu].exception_state &= ~DCPU_NEXT_MASTER;
505 goto cpu_master_loop;
506 } else if (kgdb_info[cpu].exception_state & DCPU_WANT_MASTER) {
475 if (atomic_cmpxchg(&kgdb_active, -1, cpu) == cpu) 507 if (atomic_cmpxchg(&kgdb_active, -1, cpu) == cpu)
476 break; 508 break;
477 } else if (kgdb_info[cpu].exception_state & DCPU_IS_SLAVE) { 509 } else if (kgdb_info[cpu].exception_state & DCPU_IS_SLAVE) {
@@ -513,7 +545,7 @@ return_normal:
513 } 545 }
514 546
515 if (!kgdb_io_ready(1)) { 547 if (!kgdb_io_ready(1)) {
516 error = 1; 548 kgdb_info[cpu].ret_state = 1;
517 goto kgdb_restore; /* No I/O connection, resume the system */ 549 goto kgdb_restore; /* No I/O connection, resume the system */
518 } 550 }
519 551
@@ -548,7 +580,7 @@ return_normal:
548 * Wait for the other CPUs to be notified and be waiting for us: 580 * Wait for the other CPUs to be notified and be waiting for us:
549 */ 581 */
550 for_each_online_cpu(i) { 582 for_each_online_cpu(i) {
551 while (!atomic_read(&cpu_in_kgdb[i])) 583 while (kgdb_do_roundup && !atomic_read(&cpu_in_kgdb[i]))
552 cpu_relax(); 584 cpu_relax();
553 } 585 }
554 586
@@ -557,7 +589,7 @@ return_normal:
557 * in the debugger and all secondary CPUs are quiescent 589 * in the debugger and all secondary CPUs are quiescent
558 */ 590 */
559 kgdb_post_primary_code(ks->linux_regs, ks->ex_vector, ks->err_code); 591 kgdb_post_primary_code(ks->linux_regs, ks->ex_vector, ks->err_code);
560 kgdb_deactivate_sw_breakpoints(); 592 dbg_deactivate_sw_breakpoints();
561 kgdb_single_step = 0; 593 kgdb_single_step = 0;
562 kgdb_contthread = current; 594 kgdb_contthread = current;
563 exception_level = 0; 595 exception_level = 0;
@@ -565,8 +597,26 @@ return_normal:
565 if (trace_on) 597 if (trace_on)
566 tracing_off(); 598 tracing_off();
567 599
568 /* Talk to debugger with gdbserial protocol */ 600 while (1) {
569 error = gdb_serial_stub(ks); 601cpu_master_loop:
602 if (dbg_kdb_mode) {
603 kgdb_connected = 1;
604 error = kdb_stub(ks);
605 } else {
606 error = gdb_serial_stub(ks);
607 }
608
609 if (error == DBG_PASS_EVENT) {
610 dbg_kdb_mode = !dbg_kdb_mode;
611 kgdb_connected = 0;
612 } else if (error == DBG_SWITCH_CPU_EVENT) {
613 dbg_cpu_switch(cpu, dbg_switch_cpu);
614 goto cpu_loop;
615 } else {
616 kgdb_info[cpu].ret_state = error;
617 break;
618 }
619 }
570 620
571 /* Call the I/O driver's post_exception routine */ 621 /* Call the I/O driver's post_exception routine */
572 if (dbg_io_ops->post_exception) 622 if (dbg_io_ops->post_exception)
@@ -578,11 +628,16 @@ return_normal:
578 for (i = NR_CPUS-1; i >= 0; i--) 628 for (i = NR_CPUS-1; i >= 0; i--)
579 atomic_dec(&passive_cpu_wait[i]); 629 atomic_dec(&passive_cpu_wait[i]);
580 /* 630 /*
581 * Wait till all the CPUs have quit 631 * Wait till all the CPUs have quit from the debugger,
582 * from the debugger. 632 * but allow a CPU that hit an exception and is
633 * waiting to become the master to remain in the debug
634 * core.
583 */ 635 */
584 for_each_online_cpu(i) { 636 for_each_online_cpu(i) {
585 while (atomic_read(&cpu_in_kgdb[i])) 637 while (kgdb_do_roundup &&
638 atomic_read(&cpu_in_kgdb[i]) &&
639 !(kgdb_info[i].exception_state &
640 DCPU_WANT_MASTER))
586 cpu_relax(); 641 cpu_relax();
587 } 642 }
588 } 643 }
@@ -603,7 +658,7 @@ kgdb_restore:
603 clocksource_touch_watchdog(); 658 clocksource_touch_watchdog();
604 local_irq_restore(flags); 659 local_irq_restore(flags);
605 660
606 return error; 661 return kgdb_info[cpu].ret_state;
607} 662}
608 663
609/* 664/*
@@ -632,7 +687,8 @@ kgdb_handle_exception(int evector, int signo, int ecode, struct pt_regs *regs)
632 return 0; /* Ouch, double exception ! */ 687 return 0; /* Ouch, double exception ! */
633 kgdb_info[ks->cpu].exception_state |= DCPU_WANT_MASTER; 688 kgdb_info[ks->cpu].exception_state |= DCPU_WANT_MASTER;
634 ret = kgdb_cpu_enter(ks, regs); 689 ret = kgdb_cpu_enter(ks, regs);
635 kgdb_info[ks->cpu].exception_state &= ~DCPU_WANT_MASTER; 690 kgdb_info[ks->cpu].exception_state &= ~(DCPU_WANT_MASTER |
691 DCPU_IS_SLAVE);
636 return ret; 692 return ret;
637} 693}
638 694
@@ -665,7 +721,7 @@ static void kgdb_console_write(struct console *co, const char *s,
665 721
666 /* If we're debugging, or KGDB has not connected, don't try 722 /* If we're debugging, or KGDB has not connected, don't try
667 * and print. */ 723 * and print. */
668 if (!kgdb_connected || atomic_read(&kgdb_active) != -1) 724 if (!kgdb_connected || atomic_read(&kgdb_active) != -1 || dbg_kdb_mode)
669 return; 725 return;
670 726
671 local_irq_save(flags); 727 local_irq_save(flags);
@@ -687,8 +743,14 @@ static void sysrq_handle_dbg(int key, struct tty_struct *tty)
687 printk(KERN_CRIT "ERROR: No KGDB I/O module available\n"); 743 printk(KERN_CRIT "ERROR: No KGDB I/O module available\n");
688 return; 744 return;
689 } 745 }
690 if (!kgdb_connected) 746 if (!kgdb_connected) {
747#ifdef CONFIG_KGDB_KDB
748 if (!dbg_kdb_mode)
749 printk(KERN_CRIT "KGDB or $3#33 for KDB\n");
750#else
691 printk(KERN_CRIT "Entering KGDB\n"); 751 printk(KERN_CRIT "Entering KGDB\n");
752#endif
753 }
692 754
693 kgdb_breakpoint(); 755 kgdb_breakpoint();
694} 756}
@@ -817,6 +879,16 @@ void kgdb_unregister_io_module(struct kgdb_io *old_dbg_io_ops)
817} 879}
818EXPORT_SYMBOL_GPL(kgdb_unregister_io_module); 880EXPORT_SYMBOL_GPL(kgdb_unregister_io_module);
819 881
882int dbg_io_get_char(void)
883{
884 int ret = dbg_io_ops->read_char();
885 if (!dbg_kdb_mode)
886 return ret;
887 if (ret == 127)
888 return 8;
889 return ret;
890}
891
820/** 892/**
821 * kgdb_breakpoint - generate breakpoint exception 893 * kgdb_breakpoint - generate breakpoint exception
822 * 894 *
@@ -839,6 +911,7 @@ static int __init opt_kgdb_wait(char *str)
839{ 911{
840 kgdb_break_asap = 1; 912 kgdb_break_asap = 1;
841 913
914 kdb_init(KDB_INIT_EARLY);
842 if (kgdb_io_module_registered) 915 if (kgdb_io_module_registered)
843 kgdb_initial_breakpoint(); 916 kgdb_initial_breakpoint();
844 917
diff --git a/kernel/debug/debug_core.h b/kernel/debug/debug_core.h
index db554f9be51d..44cf3de8cf9e 100644
--- a/kernel/debug/debug_core.h
+++ b/kernel/debug/debug_core.h
@@ -38,6 +38,8 @@ struct debuggerinfo_struct {
38 void *debuggerinfo; 38 void *debuggerinfo;
39 struct task_struct *task; 39 struct task_struct *task;
40 int exception_state; 40 int exception_state;
41 int ret_state;
42 int irq_depth;
41}; 43};
42 44
43extern struct debuggerinfo_struct kgdb_info[]; 45extern struct debuggerinfo_struct kgdb_info[];
@@ -47,9 +49,31 @@ extern int dbg_remove_all_break(void);
47extern int dbg_set_sw_break(unsigned long addr); 49extern int dbg_set_sw_break(unsigned long addr);
48extern int dbg_remove_sw_break(unsigned long addr); 50extern int dbg_remove_sw_break(unsigned long addr);
49extern int dbg_activate_sw_breakpoints(void); 51extern int dbg_activate_sw_breakpoints(void);
52extern int dbg_deactivate_sw_breakpoints(void);
53
54/* polled character access to i/o module */
55extern int dbg_io_get_char(void);
56
57/* stub return value for switching between the gdbstub and kdb */
58#define DBG_PASS_EVENT -12345
59/* Switch from one cpu to another */
60#define DBG_SWITCH_CPU_EVENT -123456
61extern int dbg_switch_cpu;
50 62
51/* gdbstub interface functions */ 63/* gdbstub interface functions */
52extern int gdb_serial_stub(struct kgdb_state *ks); 64extern int gdb_serial_stub(struct kgdb_state *ks);
53extern void gdbstub_msg_write(const char *s, int len); 65extern void gdbstub_msg_write(const char *s, int len);
54 66
67/* gdbstub functions used for kdb <-> gdbstub transition */
68extern int gdbstub_state(struct kgdb_state *ks, char *cmd);
69
70#ifdef CONFIG_KGDB_KDB
71extern int kdb_stub(struct kgdb_state *ks);
72#else /* ! CONFIG_KGDB_KDB */
73static inline int kdb_stub(struct kgdb_state *ks)
74{
75 return DBG_PASS_EVENT;
76}
77#endif /* CONFIG_KGDB_KDB */
78
55#endif /* _DEBUG_CORE_H_ */ 79#endif /* _DEBUG_CORE_H_ */
diff --git a/kernel/debug/gdbstub.c b/kernel/debug/gdbstub.c
index ccdf0929f12d..188203a19657 100644
--- a/kernel/debug/gdbstub.c
+++ b/kernel/debug/gdbstub.c
@@ -887,6 +887,13 @@ int gdb_serial_stub(struct kgdb_state *ks)
887 case 'Z': /* Break point set */ 887 case 'Z': /* Break point set */
888 gdb_cmd_break(ks); 888 gdb_cmd_break(ks);
889 break; 889 break;
890#ifdef CONFIG_KGDB_KDB
891 case '3': /* Escape into back into kdb */
892 if (remcom_in_buffer[1] == '\0') {
893 gdb_cmd_detachkill(ks);
894 return DBG_PASS_EVENT;
895 }
896#endif
890 case 'C': /* Exception passing */ 897 case 'C': /* Exception passing */
891 tmp = gdb_cmd_exception_pass(ks); 898 tmp = gdb_cmd_exception_pass(ks);
892 if (tmp > 0) 899 if (tmp > 0)
@@ -932,3 +939,32 @@ kgdb_exit:
932 error = 1; 939 error = 1;
933 return error; 940 return error;
934} 941}
942
943int gdbstub_state(struct kgdb_state *ks, char *cmd)
944{
945 int error;
946
947 switch (cmd[0]) {
948 case 'e':
949 error = kgdb_arch_handle_exception(ks->ex_vector,
950 ks->signo,
951 ks->err_code,
952 remcom_in_buffer,
953 remcom_out_buffer,
954 ks->linux_regs);
955 return error;
956 case 's':
957 case 'c':
958 strcpy(remcom_in_buffer, cmd);
959 return 0;
960 case '?':
961 gdb_cmd_status(ks);
962 break;
963 case '\0':
964 strcpy(remcom_out_buffer, "");
965 break;
966 }
967 dbg_io_ops->write_char('+');
968 put_packet(remcom_out_buffer);
969 return 0;
970}