diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-22 23:35:12 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-22 23:35:12 -0400 |
| commit | 8814011679d1a47d8b0158fc991727a5859471a0 (patch) | |
| tree | f5d84ea8dba4fb7e18312deb04ff51ba35f9b901 | |
| parent | 5cc103506289de7ee0a0b526ae0381541990cad4 (diff) | |
| parent | 495363d380b4f4745bd8677912688654afc44020 (diff) | |
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jwessel/linux-2.6-kgdb
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jwessel/linux-2.6-kgdb:
kdb,debug_core: adjust master cpu switch logic against new debug_core locking
debug_core: refactor locking for master/slave cpus
x86,kgdb: remove unnecessary call to kgdb_correct_hw_break()
debug_core: disable hw_breakpoints on all cores in kgdb_cpu_enter()
kdb,kgdb: fix sparse fixups
kdb: Fix oops in kdb_unregister
kdb,ftdump: Remove reference to internal kdb include
kdb: Allow kernel loadable modules to add kdb shell functions
debug_core: stop rcu warnings on kernel resume
debug_core: move all watch dog syncs to a single function
x86,kgdb: fix debugger hw breakpoint test regression in 2.6.35
| -rw-r--r-- | arch/x86/kernel/kgdb.c | 11 | ||||
| -rw-r--r-- | drivers/serial/kgdboc.c | 2 | ||||
| -rw-r--r-- | include/linux/kdb.h | 51 | ||||
| -rw-r--r-- | kernel/debug/debug_core.c | 139 | ||||
| -rw-r--r-- | kernel/debug/debug_core.h | 1 | ||||
| -rw-r--r-- | kernel/debug/kdb/kdb_debugger.c | 3 | ||||
| -rw-r--r-- | kernel/debug/kdb/kdb_io.c | 2 | ||||
| -rw-r--r-- | kernel/debug/kdb/kdb_main.c | 18 | ||||
| -rw-r--r-- | kernel/debug/kdb/kdb_private.h | 48 | ||||
| -rw-r--r-- | kernel/trace/trace_kdb.c | 1 |
10 files changed, 144 insertions, 132 deletions
diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c index 852b81967a37..d81cfebb848f 100644 --- a/arch/x86/kernel/kgdb.c +++ b/arch/x86/kernel/kgdb.c | |||
| @@ -477,8 +477,6 @@ int kgdb_arch_handle_exception(int e_vector, int signo, int err_code, | |||
| 477 | raw_smp_processor_id()); | 477 | raw_smp_processor_id()); |
| 478 | } | 478 | } |
| 479 | 479 | ||
| 480 | kgdb_correct_hw_break(); | ||
| 481 | |||
| 482 | return 0; | 480 | return 0; |
| 483 | } | 481 | } |
| 484 | 482 | ||
| @@ -621,7 +619,12 @@ int kgdb_arch_init(void) | |||
| 621 | static void kgdb_hw_overflow_handler(struct perf_event *event, int nmi, | 619 | static void kgdb_hw_overflow_handler(struct perf_event *event, int nmi, |
| 622 | struct perf_sample_data *data, struct pt_regs *regs) | 620 | struct perf_sample_data *data, struct pt_regs *regs) |
| 623 | { | 621 | { |
| 624 | kgdb_ll_trap(DIE_DEBUG, "debug", regs, 0, 0, SIGTRAP); | 622 | struct task_struct *tsk = current; |
| 623 | int i; | ||
| 624 | |||
| 625 | for (i = 0; i < 4; i++) | ||
| 626 | if (breakinfo[i].enabled) | ||
| 627 | tsk->thread.debugreg6 |= (DR_TRAP0 << i); | ||
| 625 | } | 628 | } |
| 626 | 629 | ||
| 627 | void kgdb_arch_late(void) | 630 | void kgdb_arch_late(void) |
| @@ -644,7 +647,7 @@ void kgdb_arch_late(void) | |||
| 644 | if (breakinfo[i].pev) | 647 | if (breakinfo[i].pev) |
| 645 | continue; | 648 | continue; |
| 646 | breakinfo[i].pev = register_wide_hw_breakpoint(&attr, NULL); | 649 | breakinfo[i].pev = register_wide_hw_breakpoint(&attr, NULL); |
| 647 | if (IS_ERR(breakinfo[i].pev)) { | 650 | if (IS_ERR((void * __force)breakinfo[i].pev)) { |
| 648 | printk(KERN_ERR "kgdb: Could not allocate hw" | 651 | printk(KERN_ERR "kgdb: Could not allocate hw" |
| 649 | "breakpoints\nDisabling the kernel debugger\n"); | 652 | "breakpoints\nDisabling the kernel debugger\n"); |
| 650 | breakinfo[i].pev = NULL; | 653 | breakinfo[i].pev = NULL; |
diff --git a/drivers/serial/kgdboc.c b/drivers/serial/kgdboc.c index 39f9a1adaa75..d4b711c9a416 100644 --- a/drivers/serial/kgdboc.c +++ b/drivers/serial/kgdboc.c | |||
| @@ -243,7 +243,7 @@ static struct kgdb_io kgdboc_io_ops = { | |||
| 243 | 243 | ||
| 244 | #ifdef CONFIG_KGDB_SERIAL_CONSOLE | 244 | #ifdef CONFIG_KGDB_SERIAL_CONSOLE |
| 245 | /* This is only available if kgdboc is a built in for early debugging */ | 245 | /* This is only available if kgdboc is a built in for early debugging */ |
| 246 | int __init kgdboc_early_init(char *opt) | 246 | static int __init kgdboc_early_init(char *opt) |
| 247 | { | 247 | { |
| 248 | /* save the first character of the config string because the | 248 | /* save the first character of the config string because the |
| 249 | * init routine can destroy it. | 249 | * init routine can destroy it. |
diff --git a/include/linux/kdb.h b/include/linux/kdb.h index ea6e5244ed3f..aadff7cc2b84 100644 --- a/include/linux/kdb.h +++ b/include/linux/kdb.h | |||
| @@ -28,6 +28,41 @@ extern int kdb_poll_idx; | |||
| 28 | extern int kdb_initial_cpu; | 28 | extern int kdb_initial_cpu; |
| 29 | extern atomic_t kdb_event; | 29 | extern atomic_t kdb_event; |
| 30 | 30 | ||
| 31 | /* Types and messages used for dynamically added kdb shell commands */ | ||
| 32 | |||
| 33 | #define KDB_MAXARGS 16 /* Maximum number of arguments to a function */ | ||
| 34 | |||
| 35 | typedef enum { | ||
| 36 | KDB_REPEAT_NONE = 0, /* Do not repeat this command */ | ||
| 37 | KDB_REPEAT_NO_ARGS, /* Repeat the command without arguments */ | ||
| 38 | KDB_REPEAT_WITH_ARGS, /* Repeat the command including its arguments */ | ||
| 39 | } kdb_repeat_t; | ||
| 40 | |||
| 41 | typedef int (*kdb_func_t)(int, const char **); | ||
| 42 | |||
| 43 | /* KDB return codes from a command or internal kdb function */ | ||
| 44 | #define KDB_NOTFOUND (-1) | ||
| 45 | #define KDB_ARGCOUNT (-2) | ||
| 46 | #define KDB_BADWIDTH (-3) | ||
| 47 | #define KDB_BADRADIX (-4) | ||
| 48 | #define KDB_NOTENV (-5) | ||
| 49 | #define KDB_NOENVVALUE (-6) | ||
| 50 | #define KDB_NOTIMP (-7) | ||
| 51 | #define KDB_ENVFULL (-8) | ||
| 52 | #define KDB_ENVBUFFULL (-9) | ||
| 53 | #define KDB_TOOMANYBPT (-10) | ||
| 54 | #define KDB_TOOMANYDBREGS (-11) | ||
| 55 | #define KDB_DUPBPT (-12) | ||
| 56 | #define KDB_BPTNOTFOUND (-13) | ||
| 57 | #define KDB_BADMODE (-14) | ||
| 58 | #define KDB_BADINT (-15) | ||
| 59 | #define KDB_INVADDRFMT (-16) | ||
| 60 | #define KDB_BADREG (-17) | ||
| 61 | #define KDB_BADCPUNUM (-18) | ||
| 62 | #define KDB_BADLENGTH (-19) | ||
| 63 | #define KDB_NOBP (-20) | ||
| 64 | #define KDB_BADADDR (-21) | ||
| 65 | |||
| 31 | /* | 66 | /* |
| 32 | * kdb_diemsg | 67 | * kdb_diemsg |
| 33 | * | 68 | * |
| @@ -104,10 +139,26 @@ int kdb_process_cpu(const struct task_struct *p) | |||
| 104 | 139 | ||
| 105 | /* kdb access to register set for stack dumping */ | 140 | /* kdb access to register set for stack dumping */ |
| 106 | extern struct pt_regs *kdb_current_regs; | 141 | extern struct pt_regs *kdb_current_regs; |
| 142 | #ifdef CONFIG_KALLSYMS | ||
| 143 | extern const char *kdb_walk_kallsyms(loff_t *pos); | ||
| 144 | #else /* ! CONFIG_KALLSYMS */ | ||
| 145 | static inline const char *kdb_walk_kallsyms(loff_t *pos) | ||
| 146 | { | ||
| 147 | return NULL; | ||
| 148 | } | ||
| 149 | #endif /* ! CONFIG_KALLSYMS */ | ||
| 107 | 150 | ||
| 151 | /* Dynamic kdb shell command registration */ | ||
| 152 | extern int kdb_register(char *, kdb_func_t, char *, char *, short); | ||
| 153 | extern int kdb_register_repeat(char *, kdb_func_t, char *, char *, | ||
| 154 | short, kdb_repeat_t); | ||
| 155 | extern int kdb_unregister(char *); | ||
| 108 | #else /* ! CONFIG_KGDB_KDB */ | 156 | #else /* ! CONFIG_KGDB_KDB */ |
| 109 | #define kdb_printf(...) | 157 | #define kdb_printf(...) |
| 110 | #define kdb_init(x) | 158 | #define kdb_init(x) |
| 159 | #define kdb_register(...) | ||
| 160 | #define kdb_register_repeat(...) | ||
| 161 | #define kdb_uregister(x) | ||
| 111 | #endif /* CONFIG_KGDB_KDB */ | 162 | #endif /* CONFIG_KGDB_KDB */ |
| 112 | enum { | 163 | enum { |
| 113 | KDB_NOT_INITIALIZED, | 164 | KDB_NOT_INITIALIZED, |
diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c index de407c78178d..fec596da9bd0 100644 --- a/kernel/debug/debug_core.c +++ b/kernel/debug/debug_core.c | |||
| @@ -47,6 +47,7 @@ | |||
| 47 | #include <linux/pid.h> | 47 | #include <linux/pid.h> |
| 48 | #include <linux/smp.h> | 48 | #include <linux/smp.h> |
| 49 | #include <linux/mm.h> | 49 | #include <linux/mm.h> |
| 50 | #include <linux/rcupdate.h> | ||
| 50 | 51 | ||
| 51 | #include <asm/cacheflush.h> | 52 | #include <asm/cacheflush.h> |
| 52 | #include <asm/byteorder.h> | 53 | #include <asm/byteorder.h> |
| @@ -109,13 +110,15 @@ static struct kgdb_bkpt kgdb_break[KGDB_MAX_BREAKPOINTS] = { | |||
| 109 | */ | 110 | */ |
| 110 | atomic_t kgdb_active = ATOMIC_INIT(-1); | 111 | atomic_t kgdb_active = ATOMIC_INIT(-1); |
| 111 | EXPORT_SYMBOL_GPL(kgdb_active); | 112 | EXPORT_SYMBOL_GPL(kgdb_active); |
| 113 | static DEFINE_RAW_SPINLOCK(dbg_master_lock); | ||
| 114 | static DEFINE_RAW_SPINLOCK(dbg_slave_lock); | ||
| 112 | 115 | ||
| 113 | /* | 116 | /* |
| 114 | * We use NR_CPUs not PERCPU, in case kgdb is used to debug early | 117 | * We use NR_CPUs not PERCPU, in case kgdb is used to debug early |
| 115 | * bootup code (which might not have percpu set up yet): | 118 | * bootup code (which might not have percpu set up yet): |
| 116 | */ | 119 | */ |
| 117 | static atomic_t passive_cpu_wait[NR_CPUS]; | 120 | static atomic_t masters_in_kgdb; |
| 118 | static atomic_t cpu_in_kgdb[NR_CPUS]; | 121 | static atomic_t slaves_in_kgdb; |
| 119 | static atomic_t kgdb_break_tasklet_var; | 122 | static atomic_t kgdb_break_tasklet_var; |
| 120 | atomic_t kgdb_setting_breakpoint; | 123 | atomic_t kgdb_setting_breakpoint; |
| 121 | 124 | ||
| @@ -457,26 +460,32 @@ static int kgdb_reenter_check(struct kgdb_state *ks) | |||
| 457 | return 1; | 460 | return 1; |
| 458 | } | 461 | } |
| 459 | 462 | ||
| 460 | static void dbg_cpu_switch(int cpu, int next_cpu) | 463 | static void dbg_touch_watchdogs(void) |
| 461 | { | 464 | { |
| 462 | /* Mark the cpu we are switching away from as a slave when it | 465 | touch_softlockup_watchdog_sync(); |
| 463 | * holds the kgdb_active token. This must be done so that the | 466 | clocksource_touch_watchdog(); |
| 464 | * that all the cpus wait in for the debug core will not enter | 467 | rcu_cpu_stall_reset(); |
| 465 | * again as the master. */ | ||
| 466 | if (cpu == atomic_read(&kgdb_active)) { | ||
| 467 | kgdb_info[cpu].exception_state |= DCPU_IS_SLAVE; | ||
| 468 | kgdb_info[cpu].exception_state &= ~DCPU_WANT_MASTER; | ||
| 469 | } | ||
| 470 | kgdb_info[next_cpu].exception_state |= DCPU_NEXT_MASTER; | ||
| 471 | } | 468 | } |
| 472 | 469 | ||
| 473 | static int kgdb_cpu_enter(struct kgdb_state *ks, struct pt_regs *regs) | 470 | static int kgdb_cpu_enter(struct kgdb_state *ks, struct pt_regs *regs, |
| 471 | int exception_state) | ||
| 474 | { | 472 | { |
| 475 | unsigned long flags; | 473 | unsigned long flags; |
| 476 | int sstep_tries = 100; | 474 | int sstep_tries = 100; |
| 477 | int error; | 475 | int error; |
| 478 | int i, cpu; | 476 | int cpu; |
| 479 | int trace_on = 0; | 477 | int trace_on = 0; |
| 478 | int online_cpus = num_online_cpus(); | ||
| 479 | |||
| 480 | kgdb_info[ks->cpu].enter_kgdb++; | ||
| 481 | kgdb_info[ks->cpu].exception_state |= exception_state; | ||
| 482 | |||
| 483 | if (exception_state == DCPU_WANT_MASTER) | ||
| 484 | atomic_inc(&masters_in_kgdb); | ||
| 485 | else | ||
| 486 | atomic_inc(&slaves_in_kgdb); | ||
| 487 | kgdb_disable_hw_debug(ks->linux_regs); | ||
| 488 | |||
| 480 | acquirelock: | 489 | acquirelock: |
| 481 | /* | 490 | /* |
| 482 | * Interrupts will be restored by the 'trap return' code, except when | 491 | * Interrupts will be restored by the 'trap return' code, except when |
| @@ -489,14 +498,15 @@ acquirelock: | |||
| 489 | kgdb_info[cpu].task = current; | 498 | kgdb_info[cpu].task = current; |
| 490 | kgdb_info[cpu].ret_state = 0; | 499 | kgdb_info[cpu].ret_state = 0; |
| 491 | kgdb_info[cpu].irq_depth = hardirq_count() >> HARDIRQ_SHIFT; | 500 | kgdb_info[cpu].irq_depth = hardirq_count() >> HARDIRQ_SHIFT; |
| 492 | /* | ||
| 493 | * Make sure the above info reaches the primary CPU before | ||
| 494 | * our cpu_in_kgdb[] flag setting does: | ||
| 495 | */ | ||
| 496 | atomic_inc(&cpu_in_kgdb[cpu]); | ||
| 497 | 501 | ||
| 498 | if (exception_level == 1) | 502 | /* Make sure the above info reaches the primary CPU */ |
| 503 | smp_mb(); | ||
| 504 | |||
| 505 | if (exception_level == 1) { | ||
| 506 | if (raw_spin_trylock(&dbg_master_lock)) | ||
| 507 | atomic_xchg(&kgdb_active, cpu); | ||
| 499 | goto cpu_master_loop; | 508 | goto cpu_master_loop; |
| 509 | } | ||
| 500 | 510 | ||
| 501 | /* | 511 | /* |
| 502 | * CPU will loop if it is a slave or request to become a kgdb | 512 | * CPU will loop if it is a slave or request to become a kgdb |
| @@ -508,10 +518,12 @@ cpu_loop: | |||
| 508 | kgdb_info[cpu].exception_state &= ~DCPU_NEXT_MASTER; | 518 | kgdb_info[cpu].exception_state &= ~DCPU_NEXT_MASTER; |
| 509 | goto cpu_master_loop; | 519 | goto cpu_master_loop; |
| 510 | } else if (kgdb_info[cpu].exception_state & DCPU_WANT_MASTER) { | 520 | } else if (kgdb_info[cpu].exception_state & DCPU_WANT_MASTER) { |
| 511 | if (atomic_cmpxchg(&kgdb_active, -1, cpu) == cpu) | 521 | if (raw_spin_trylock(&dbg_master_lock)) { |
| 522 | atomic_xchg(&kgdb_active, cpu); | ||
| 512 | break; | 523 | break; |
| 524 | } | ||
| 513 | } else if (kgdb_info[cpu].exception_state & DCPU_IS_SLAVE) { | 525 | } else if (kgdb_info[cpu].exception_state & DCPU_IS_SLAVE) { |
| 514 | if (!atomic_read(&passive_cpu_wait[cpu])) | 526 | if (!raw_spin_is_locked(&dbg_slave_lock)) |
| 515 | goto return_normal; | 527 | goto return_normal; |
| 516 | } else { | 528 | } else { |
| 517 | return_normal: | 529 | return_normal: |
| @@ -522,9 +534,12 @@ return_normal: | |||
| 522 | arch_kgdb_ops.correct_hw_break(); | 534 | arch_kgdb_ops.correct_hw_break(); |
| 523 | if (trace_on) | 535 | if (trace_on) |
| 524 | tracing_on(); | 536 | tracing_on(); |
| 525 | atomic_dec(&cpu_in_kgdb[cpu]); | 537 | kgdb_info[cpu].exception_state &= |
| 526 | touch_softlockup_watchdog_sync(); | 538 | ~(DCPU_WANT_MASTER | DCPU_IS_SLAVE); |
| 527 | clocksource_touch_watchdog(); | 539 | kgdb_info[cpu].enter_kgdb--; |
| 540 | smp_mb__before_atomic_dec(); | ||
| 541 | atomic_dec(&slaves_in_kgdb); | ||
| 542 | dbg_touch_watchdogs(); | ||
| 528 | local_irq_restore(flags); | 543 | local_irq_restore(flags); |
| 529 | return 0; | 544 | return 0; |
| 530 | } | 545 | } |
| @@ -541,8 +556,8 @@ return_normal: | |||
| 541 | (kgdb_info[cpu].task && | 556 | (kgdb_info[cpu].task && |
| 542 | kgdb_info[cpu].task->pid != kgdb_sstep_pid) && --sstep_tries) { | 557 | kgdb_info[cpu].task->pid != kgdb_sstep_pid) && --sstep_tries) { |
| 543 | atomic_set(&kgdb_active, -1); | 558 | atomic_set(&kgdb_active, -1); |
| 544 | touch_softlockup_watchdog_sync(); | 559 | raw_spin_unlock(&dbg_master_lock); |
| 545 | clocksource_touch_watchdog(); | 560 | dbg_touch_watchdogs(); |
| 546 | local_irq_restore(flags); | 561 | local_irq_restore(flags); |
| 547 | 562 | ||
| 548 | goto acquirelock; | 563 | goto acquirelock; |
| @@ -563,16 +578,12 @@ return_normal: | |||
| 563 | if (dbg_io_ops->pre_exception) | 578 | if (dbg_io_ops->pre_exception) |
| 564 | dbg_io_ops->pre_exception(); | 579 | dbg_io_ops->pre_exception(); |
| 565 | 580 | ||
| 566 | kgdb_disable_hw_debug(ks->linux_regs); | ||
| 567 | |||
| 568 | /* | 581 | /* |
| 569 | * Get the passive CPU lock which will hold all the non-primary | 582 | * Get the passive CPU lock which will hold all the non-primary |
| 570 | * CPU in a spin state while the debugger is active | 583 | * CPU in a spin state while the debugger is active |
| 571 | */ | 584 | */ |
| 572 | if (!kgdb_single_step) { | 585 | if (!kgdb_single_step) |
| 573 | for (i = 0; i < NR_CPUS; i++) | 586 | raw_spin_lock(&dbg_slave_lock); |
| 574 | atomic_inc(&passive_cpu_wait[i]); | ||
| 575 | } | ||
| 576 | 587 | ||
| 577 | #ifdef CONFIG_SMP | 588 | #ifdef CONFIG_SMP |
| 578 | /* Signal the other CPUs to enter kgdb_wait() */ | 589 | /* Signal the other CPUs to enter kgdb_wait() */ |
| @@ -583,10 +594,9 @@ return_normal: | |||
| 583 | /* | 594 | /* |
| 584 | * Wait for the other CPUs to be notified and be waiting for us: | 595 | * Wait for the other CPUs to be notified and be waiting for us: |
| 585 | */ | 596 | */ |
| 586 | for_each_online_cpu(i) { | 597 | while (kgdb_do_roundup && (atomic_read(&masters_in_kgdb) + |
| 587 | while (kgdb_do_roundup && !atomic_read(&cpu_in_kgdb[i])) | 598 | atomic_read(&slaves_in_kgdb)) != online_cpus) |
| 588 | cpu_relax(); | 599 | cpu_relax(); |
| 589 | } | ||
| 590 | 600 | ||
| 591 | /* | 601 | /* |
| 592 | * At this point the primary processor is completely | 602 | * At this point the primary processor is completely |
| @@ -615,7 +625,8 @@ cpu_master_loop: | |||
| 615 | if (error == DBG_PASS_EVENT) { | 625 | if (error == DBG_PASS_EVENT) { |
| 616 | dbg_kdb_mode = !dbg_kdb_mode; | 626 | dbg_kdb_mode = !dbg_kdb_mode; |
| 617 | } else if (error == DBG_SWITCH_CPU_EVENT) { | 627 | } else if (error == DBG_SWITCH_CPU_EVENT) { |
| 618 | dbg_cpu_switch(cpu, dbg_switch_cpu); | 628 | kgdb_info[dbg_switch_cpu].exception_state |= |
| 629 | DCPU_NEXT_MASTER; | ||
| 619 | goto cpu_loop; | 630 | goto cpu_loop; |
| 620 | } else { | 631 | } else { |
| 621 | kgdb_info[cpu].ret_state = error; | 632 | kgdb_info[cpu].ret_state = error; |
| @@ -627,24 +638,11 @@ cpu_master_loop: | |||
| 627 | if (dbg_io_ops->post_exception) | 638 | if (dbg_io_ops->post_exception) |
| 628 | dbg_io_ops->post_exception(); | 639 | dbg_io_ops->post_exception(); |
| 629 | 640 | ||
| 630 | atomic_dec(&cpu_in_kgdb[ks->cpu]); | ||
| 631 | |||
| 632 | if (!kgdb_single_step) { | 641 | if (!kgdb_single_step) { |
| 633 | for (i = NR_CPUS-1; i >= 0; i--) | 642 | raw_spin_unlock(&dbg_slave_lock); |
| 634 | atomic_dec(&passive_cpu_wait[i]); | 643 | /* Wait till all the CPUs have quit from the debugger. */ |
| 635 | /* | 644 | while (kgdb_do_roundup && atomic_read(&slaves_in_kgdb)) |
| 636 | * Wait till all the CPUs have quit from the debugger, | 645 | cpu_relax(); |
| 637 | * but allow a CPU that hit an exception and is | ||
| 638 | * waiting to become the master to remain in the debug | ||
| 639 | * core. | ||
| 640 | */ | ||
| 641 | for_each_online_cpu(i) { | ||
| 642 | while (kgdb_do_roundup && | ||
| 643 | atomic_read(&cpu_in_kgdb[i]) && | ||
| 644 | !(kgdb_info[i].exception_state & | ||
| 645 | DCPU_WANT_MASTER)) | ||
| 646 | cpu_relax(); | ||
| 647 | } | ||
| 648 | } | 646 | } |
| 649 | 647 | ||
| 650 | kgdb_restore: | 648 | kgdb_restore: |
| @@ -655,12 +653,20 @@ kgdb_restore: | |||
| 655 | else | 653 | else |
| 656 | kgdb_sstep_pid = 0; | 654 | kgdb_sstep_pid = 0; |
| 657 | } | 655 | } |
| 656 | if (arch_kgdb_ops.correct_hw_break) | ||
| 657 | arch_kgdb_ops.correct_hw_break(); | ||
| 658 | if (trace_on) | 658 | if (trace_on) |
| 659 | tracing_on(); | 659 | tracing_on(); |
| 660 | |||
| 661 | kgdb_info[cpu].exception_state &= | ||
| 662 | ~(DCPU_WANT_MASTER | DCPU_IS_SLAVE); | ||
| 663 | kgdb_info[cpu].enter_kgdb--; | ||
| 664 | smp_mb__before_atomic_dec(); | ||
| 665 | atomic_dec(&masters_in_kgdb); | ||
| 660 | /* Free kgdb_active */ | 666 | /* Free kgdb_active */ |
| 661 | atomic_set(&kgdb_active, -1); | 667 | atomic_set(&kgdb_active, -1); |
| 662 | touch_softlockup_watchdog_sync(); | 668 | raw_spin_unlock(&dbg_master_lock); |
| 663 | clocksource_touch_watchdog(); | 669 | dbg_touch_watchdogs(); |
| 664 | local_irq_restore(flags); | 670 | local_irq_restore(flags); |
| 665 | 671 | ||
| 666 | return kgdb_info[cpu].ret_state; | 672 | return kgdb_info[cpu].ret_state; |
| @@ -678,7 +684,6 @@ kgdb_handle_exception(int evector, int signo, int ecode, struct pt_regs *regs) | |||
| 678 | { | 684 | { |
| 679 | struct kgdb_state kgdb_var; | 685 | struct kgdb_state kgdb_var; |
| 680 | struct kgdb_state *ks = &kgdb_var; | 686 | struct kgdb_state *ks = &kgdb_var; |
| 681 | int ret; | ||
| 682 | 687 | ||
| 683 | ks->cpu = raw_smp_processor_id(); | 688 | ks->cpu = raw_smp_processor_id(); |
| 684 | ks->ex_vector = evector; | 689 | ks->ex_vector = evector; |
| @@ -689,11 +694,10 @@ kgdb_handle_exception(int evector, int signo, int ecode, struct pt_regs *regs) | |||
| 689 | 694 | ||
| 690 | if (kgdb_reenter_check(ks)) | 695 | if (kgdb_reenter_check(ks)) |
| 691 | return 0; /* Ouch, double exception ! */ | 696 | return 0; /* Ouch, double exception ! */ |
| 692 | kgdb_info[ks->cpu].exception_state |= DCPU_WANT_MASTER; | 697 | if (kgdb_info[ks->cpu].enter_kgdb != 0) |
| 693 | ret = kgdb_cpu_enter(ks, regs); | 698 | return 0; |
| 694 | kgdb_info[ks->cpu].exception_state &= ~(DCPU_WANT_MASTER | | 699 | |
| 695 | DCPU_IS_SLAVE); | 700 | return kgdb_cpu_enter(ks, regs, DCPU_WANT_MASTER); |
| 696 | return ret; | ||
| 697 | } | 701 | } |
| 698 | 702 | ||
| 699 | int kgdb_nmicallback(int cpu, void *regs) | 703 | int kgdb_nmicallback(int cpu, void *regs) |
| @@ -706,12 +710,9 @@ int kgdb_nmicallback(int cpu, void *regs) | |||
| 706 | ks->cpu = cpu; | 710 | ks->cpu = cpu; |
| 707 | ks->linux_regs = regs; | 711 | ks->linux_regs = regs; |
| 708 | 712 | ||
| 709 | if (!atomic_read(&cpu_in_kgdb[cpu]) && | 713 | if (kgdb_info[ks->cpu].enter_kgdb == 0 && |
| 710 | atomic_read(&kgdb_active) != -1 && | 714 | raw_spin_is_locked(&dbg_master_lock)) { |
| 711 | atomic_read(&kgdb_active) != cpu) { | 715 | kgdb_cpu_enter(ks, regs, DCPU_IS_SLAVE); |
| 712 | kgdb_info[cpu].exception_state |= DCPU_IS_SLAVE; | ||
| 713 | kgdb_cpu_enter(ks, regs); | ||
| 714 | kgdb_info[cpu].exception_state &= ~DCPU_IS_SLAVE; | ||
| 715 | return 0; | 716 | return 0; |
| 716 | } | 717 | } |
| 717 | #endif | 718 | #endif |
diff --git a/kernel/debug/debug_core.h b/kernel/debug/debug_core.h index c5d753d80f67..3494c28a7e7a 100644 --- a/kernel/debug/debug_core.h +++ b/kernel/debug/debug_core.h | |||
| @@ -40,6 +40,7 @@ struct debuggerinfo_struct { | |||
| 40 | int exception_state; | 40 | int exception_state; |
| 41 | int ret_state; | 41 | int ret_state; |
| 42 | int irq_depth; | 42 | int irq_depth; |
| 43 | int enter_kgdb; | ||
| 43 | }; | 44 | }; |
| 44 | 45 | ||
| 45 | extern struct debuggerinfo_struct kgdb_info[]; | 46 | extern struct debuggerinfo_struct kgdb_info[]; |
diff --git a/kernel/debug/kdb/kdb_debugger.c b/kernel/debug/kdb/kdb_debugger.c index bf6e8270e957..dd0b1b7dd02c 100644 --- a/kernel/debug/kdb/kdb_debugger.c +++ b/kernel/debug/kdb/kdb_debugger.c | |||
| @@ -86,7 +86,7 @@ int kdb_stub(struct kgdb_state *ks) | |||
| 86 | } | 86 | } |
| 87 | /* Set initial kdb state variables */ | 87 | /* Set initial kdb state variables */ |
| 88 | KDB_STATE_CLEAR(KGDB_TRANS); | 88 | KDB_STATE_CLEAR(KGDB_TRANS); |
| 89 | kdb_initial_cpu = ks->cpu; | 89 | kdb_initial_cpu = atomic_read(&kgdb_active); |
| 90 | kdb_current_task = kgdb_info[ks->cpu].task; | 90 | kdb_current_task = kgdb_info[ks->cpu].task; |
| 91 | kdb_current_regs = kgdb_info[ks->cpu].debuggerinfo; | 91 | kdb_current_regs = kgdb_info[ks->cpu].debuggerinfo; |
| 92 | /* Remove any breakpoints as needed by kdb and clear single step */ | 92 | /* Remove any breakpoints as needed by kdb and clear single step */ |
| @@ -105,7 +105,6 @@ int kdb_stub(struct kgdb_state *ks) | |||
| 105 | ks->pass_exception = 1; | 105 | ks->pass_exception = 1; |
| 106 | KDB_FLAG_SET(CATASTROPHIC); | 106 | KDB_FLAG_SET(CATASTROPHIC); |
| 107 | } | 107 | } |
| 108 | kdb_initial_cpu = ks->cpu; | ||
| 109 | if (KDB_STATE(SSBPT) && reason == KDB_REASON_SSTEP) { | 108 | if (KDB_STATE(SSBPT) && reason == KDB_REASON_SSTEP) { |
| 110 | KDB_STATE_CLEAR(SSBPT); | 109 | KDB_STATE_CLEAR(SSBPT); |
| 111 | KDB_STATE_CLEAR(DOING_SS); | 110 | KDB_STATE_CLEAR(DOING_SS); |
diff --git a/kernel/debug/kdb/kdb_io.c b/kernel/debug/kdb/kdb_io.c index c9b7f4f90bba..96fdaac46a80 100644 --- a/kernel/debug/kdb/kdb_io.c +++ b/kernel/debug/kdb/kdb_io.c | |||
| @@ -823,4 +823,4 @@ int kdb_printf(const char *fmt, ...) | |||
| 823 | 823 | ||
| 824 | return r; | 824 | return r; |
| 825 | } | 825 | } |
| 826 | 826 | EXPORT_SYMBOL_GPL(kdb_printf); | |
diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c index caf057a3de0e..d7bda21a106b 100644 --- a/kernel/debug/kdb/kdb_main.c +++ b/kernel/debug/kdb/kdb_main.c | |||
| @@ -1749,13 +1749,13 @@ static int kdb_go(int argc, const char **argv) | |||
| 1749 | int nextarg; | 1749 | int nextarg; |
| 1750 | long offset; | 1750 | long offset; |
| 1751 | 1751 | ||
| 1752 | if (raw_smp_processor_id() != kdb_initial_cpu) { | ||
| 1753 | kdb_printf("go must execute on the entry cpu, " | ||
| 1754 | "please use \"cpu %d\" and then execute go\n", | ||
| 1755 | kdb_initial_cpu); | ||
| 1756 | return KDB_BADCPUNUM; | ||
| 1757 | } | ||
| 1752 | if (argc == 1) { | 1758 | if (argc == 1) { |
| 1753 | if (raw_smp_processor_id() != kdb_initial_cpu) { | ||
| 1754 | kdb_printf("go <address> must be issued from the " | ||
| 1755 | "initial cpu, do cpu %d first\n", | ||
| 1756 | kdb_initial_cpu); | ||
| 1757 | return KDB_ARGCOUNT; | ||
| 1758 | } | ||
| 1759 | nextarg = 1; | 1759 | nextarg = 1; |
| 1760 | diag = kdbgetaddrarg(argc, argv, &nextarg, | 1760 | diag = kdbgetaddrarg(argc, argv, &nextarg, |
| 1761 | &addr, &offset, NULL); | 1761 | &addr, &offset, NULL); |
| @@ -2783,6 +2783,8 @@ int kdb_register_repeat(char *cmd, | |||
| 2783 | 2783 | ||
| 2784 | return 0; | 2784 | return 0; |
| 2785 | } | 2785 | } |
| 2786 | EXPORT_SYMBOL_GPL(kdb_register_repeat); | ||
| 2787 | |||
| 2786 | 2788 | ||
| 2787 | /* | 2789 | /* |
| 2788 | * kdb_register - Compatibility register function for commands that do | 2790 | * kdb_register - Compatibility register function for commands that do |
| @@ -2805,6 +2807,7 @@ int kdb_register(char *cmd, | |||
| 2805 | return kdb_register_repeat(cmd, func, usage, help, minlen, | 2807 | return kdb_register_repeat(cmd, func, usage, help, minlen, |
| 2806 | KDB_REPEAT_NONE); | 2808 | KDB_REPEAT_NONE); |
| 2807 | } | 2809 | } |
| 2810 | EXPORT_SYMBOL_GPL(kdb_register); | ||
| 2808 | 2811 | ||
| 2809 | /* | 2812 | /* |
| 2810 | * kdb_unregister - This function is used to unregister a kernel | 2813 | * kdb_unregister - This function is used to unregister a kernel |
| @@ -2823,7 +2826,7 @@ int kdb_unregister(char *cmd) | |||
| 2823 | /* | 2826 | /* |
| 2824 | * find the command. | 2827 | * find the command. |
| 2825 | */ | 2828 | */ |
| 2826 | for (i = 0, kp = kdb_commands; i < kdb_max_commands; i++, kp++) { | 2829 | for_each_kdbcmd(kp, i) { |
| 2827 | if (kp->cmd_name && (strcmp(kp->cmd_name, cmd) == 0)) { | 2830 | if (kp->cmd_name && (strcmp(kp->cmd_name, cmd) == 0)) { |
| 2828 | kp->cmd_name = NULL; | 2831 | kp->cmd_name = NULL; |
| 2829 | return 0; | 2832 | return 0; |
| @@ -2833,6 +2836,7 @@ int kdb_unregister(char *cmd) | |||
| 2833 | /* Couldn't find it. */ | 2836 | /* Couldn't find it. */ |
| 2834 | return 1; | 2837 | return 1; |
| 2835 | } | 2838 | } |
| 2839 | EXPORT_SYMBOL_GPL(kdb_unregister); | ||
| 2836 | 2840 | ||
| 2837 | /* Initialize the kdb command table. */ | 2841 | /* Initialize the kdb command table. */ |
| 2838 | static void __init kdb_inittab(void) | 2842 | static void __init kdb_inittab(void) |
diff --git a/kernel/debug/kdb/kdb_private.h b/kernel/debug/kdb/kdb_private.h index be775f7e81e0..35d69ed1dfb5 100644 --- a/kernel/debug/kdb/kdb_private.h +++ b/kernel/debug/kdb/kdb_private.h | |||
| @@ -15,29 +15,6 @@ | |||
| 15 | #include <linux/kgdb.h> | 15 | #include <linux/kgdb.h> |
| 16 | #include "../debug_core.h" | 16 | #include "../debug_core.h" |
| 17 | 17 | ||
| 18 | /* Kernel Debugger Error codes. Must not overlap with command codes. */ | ||
| 19 | #define KDB_NOTFOUND (-1) | ||
| 20 | #define KDB_ARGCOUNT (-2) | ||
| 21 | #define KDB_BADWIDTH (-3) | ||
| 22 | #define KDB_BADRADIX (-4) | ||
| 23 | #define KDB_NOTENV (-5) | ||
| 24 | #define KDB_NOENVVALUE (-6) | ||
| 25 | #define KDB_NOTIMP (-7) | ||
| 26 | #define KDB_ENVFULL (-8) | ||
| 27 | #define KDB_ENVBUFFULL (-9) | ||
| 28 | #define KDB_TOOMANYBPT (-10) | ||
| 29 | #define KDB_TOOMANYDBREGS (-11) | ||
| 30 | #define KDB_DUPBPT (-12) | ||
| 31 | #define KDB_BPTNOTFOUND (-13) | ||
| 32 | #define KDB_BADMODE (-14) | ||
| 33 | #define KDB_BADINT (-15) | ||
| 34 | #define KDB_INVADDRFMT (-16) | ||
| 35 | #define KDB_BADREG (-17) | ||
| 36 | #define KDB_BADCPUNUM (-18) | ||
| 37 | #define KDB_BADLENGTH (-19) | ||
| 38 | #define KDB_NOBP (-20) | ||
| 39 | #define KDB_BADADDR (-21) | ||
| 40 | |||
| 41 | /* Kernel Debugger Command codes. Must not overlap with error codes. */ | 18 | /* Kernel Debugger Command codes. Must not overlap with error codes. */ |
| 42 | #define KDB_CMD_GO (-1001) | 19 | #define KDB_CMD_GO (-1001) |
| 43 | #define KDB_CMD_CPU (-1002) | 20 | #define KDB_CMD_CPU (-1002) |
| @@ -93,17 +70,6 @@ | |||
| 93 | */ | 70 | */ |
| 94 | #define KDB_MAXBPT 16 | 71 | #define KDB_MAXBPT 16 |
| 95 | 72 | ||
| 96 | /* Maximum number of arguments to a function */ | ||
| 97 | #define KDB_MAXARGS 16 | ||
| 98 | |||
| 99 | typedef enum { | ||
| 100 | KDB_REPEAT_NONE = 0, /* Do not repeat this command */ | ||
| 101 | KDB_REPEAT_NO_ARGS, /* Repeat the command without arguments */ | ||
| 102 | KDB_REPEAT_WITH_ARGS, /* Repeat the command including its arguments */ | ||
| 103 | } kdb_repeat_t; | ||
| 104 | |||
| 105 | typedef int (*kdb_func_t)(int, const char **); | ||
| 106 | |||
| 107 | /* Symbol table format returned by kallsyms. */ | 73 | /* Symbol table format returned by kallsyms. */ |
| 108 | typedef struct __ksymtab { | 74 | typedef struct __ksymtab { |
| 109 | unsigned long value; /* Address of symbol */ | 75 | unsigned long value; /* Address of symbol */ |
| @@ -123,11 +89,6 @@ extern int kallsyms_symbol_next(char *prefix_name, int flag); | |||
| 123 | extern int kallsyms_symbol_complete(char *prefix_name, int max_len); | 89 | extern int kallsyms_symbol_complete(char *prefix_name, int max_len); |
| 124 | 90 | ||
| 125 | /* Exported Symbols for kernel loadable modules to use. */ | 91 | /* Exported Symbols for kernel loadable modules to use. */ |
| 126 | extern int kdb_register(char *, kdb_func_t, char *, char *, short); | ||
| 127 | extern int kdb_register_repeat(char *, kdb_func_t, char *, char *, | ||
| 128 | short, kdb_repeat_t); | ||
| 129 | extern int kdb_unregister(char *); | ||
| 130 | |||
| 131 | extern int kdb_getarea_size(void *, unsigned long, size_t); | 92 | extern int kdb_getarea_size(void *, unsigned long, size_t); |
| 132 | extern int kdb_putarea_size(unsigned long, void *, size_t); | 93 | extern int kdb_putarea_size(unsigned long, void *, size_t); |
| 133 | 94 | ||
| @@ -144,6 +105,7 @@ extern int kdb_getword(unsigned long *, unsigned long, size_t); | |||
| 144 | extern int kdb_putword(unsigned long, unsigned long, size_t); | 105 | extern int kdb_putword(unsigned long, unsigned long, size_t); |
| 145 | 106 | ||
| 146 | extern int kdbgetularg(const char *, unsigned long *); | 107 | extern int kdbgetularg(const char *, unsigned long *); |
| 108 | extern int kdbgetu64arg(const char *, u64 *); | ||
| 147 | extern char *kdbgetenv(const char *); | 109 | extern char *kdbgetenv(const char *); |
| 148 | extern int kdbgetaddrarg(int, const char **, int*, unsigned long *, | 110 | extern int kdbgetaddrarg(int, const char **, int*, unsigned long *, |
| 149 | long *, char **); | 111 | long *, char **); |
| @@ -255,14 +217,6 @@ extern void kdb_ps1(const struct task_struct *p); | |||
| 255 | extern void kdb_print_nameval(const char *name, unsigned long val); | 217 | extern void kdb_print_nameval(const char *name, unsigned long val); |
| 256 | extern void kdb_send_sig_info(struct task_struct *p, struct siginfo *info); | 218 | extern void kdb_send_sig_info(struct task_struct *p, struct siginfo *info); |
| 257 | extern void kdb_meminfo_proc_show(void); | 219 | extern void kdb_meminfo_proc_show(void); |
| 258 | #ifdef CONFIG_KALLSYMS | ||
| 259 | extern const char *kdb_walk_kallsyms(loff_t *pos); | ||
| 260 | #else /* ! CONFIG_KALLSYMS */ | ||
| 261 | static inline const char *kdb_walk_kallsyms(loff_t *pos) | ||
| 262 | { | ||
| 263 | return NULL; | ||
| 264 | } | ||
| 265 | #endif /* ! CONFIG_KALLSYMS */ | ||
| 266 | extern char *kdb_getstr(char *, size_t, char *); | 220 | extern char *kdb_getstr(char *, size_t, char *); |
| 267 | 221 | ||
| 268 | /* Defines for kdb_symbol_print */ | 222 | /* Defines for kdb_symbol_print */ |
diff --git a/kernel/trace/trace_kdb.c b/kernel/trace/trace_kdb.c index 7b8ecd751d93..3c5c5dfea0b3 100644 --- a/kernel/trace/trace_kdb.c +++ b/kernel/trace/trace_kdb.c | |||
| @@ -13,7 +13,6 @@ | |||
| 13 | #include <linux/kdb.h> | 13 | #include <linux/kdb.h> |
| 14 | #include <linux/ftrace.h> | 14 | #include <linux/ftrace.h> |
| 15 | 15 | ||
| 16 | #include "../debug/kdb/kdb_private.h" | ||
| 17 | #include "trace.h" | 16 | #include "trace.h" |
| 18 | #include "trace_output.h" | 17 | #include "trace_output.h" |
| 19 | 18 | ||
