diff options
Diffstat (limited to 'kernel/debug/debug_core.c')
| -rw-r--r-- | kernel/debug/debug_core.c | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c index 0506d447aed2..7d2f35e5df2f 100644 --- a/kernel/debug/debug_core.c +++ b/kernel/debug/debug_core.c | |||
| @@ -575,8 +575,12 @@ return_normal: | |||
| 575 | raw_spin_lock(&dbg_slave_lock); | 575 | raw_spin_lock(&dbg_slave_lock); |
| 576 | 576 | ||
| 577 | #ifdef CONFIG_SMP | 577 | #ifdef CONFIG_SMP |
| 578 | /* If send_ready set, slaves are already waiting */ | ||
| 579 | if (ks->send_ready) | ||
| 580 | atomic_set(ks->send_ready, 1); | ||
| 581 | |||
| 578 | /* Signal the other CPUs to enter kgdb_wait() */ | 582 | /* Signal the other CPUs to enter kgdb_wait() */ |
| 579 | if ((!kgdb_single_step) && kgdb_do_roundup) | 583 | else if ((!kgdb_single_step) && kgdb_do_roundup) |
| 580 | kgdb_roundup_cpus(flags); | 584 | kgdb_roundup_cpus(flags); |
| 581 | #endif | 585 | #endif |
| 582 | 586 | ||
| @@ -678,11 +682,11 @@ kgdb_handle_exception(int evector, int signo, int ecode, struct pt_regs *regs) | |||
| 678 | if (arch_kgdb_ops.enable_nmi) | 682 | if (arch_kgdb_ops.enable_nmi) |
| 679 | arch_kgdb_ops.enable_nmi(0); | 683 | arch_kgdb_ops.enable_nmi(0); |
| 680 | 684 | ||
| 685 | memset(ks, 0, sizeof(struct kgdb_state)); | ||
| 681 | ks->cpu = raw_smp_processor_id(); | 686 | ks->cpu = raw_smp_processor_id(); |
| 682 | ks->ex_vector = evector; | 687 | ks->ex_vector = evector; |
| 683 | ks->signo = signo; | 688 | ks->signo = signo; |
| 684 | ks->err_code = ecode; | 689 | ks->err_code = ecode; |
| 685 | ks->kgdb_usethreadid = 0; | ||
| 686 | ks->linux_regs = regs; | 690 | ks->linux_regs = regs; |
| 687 | 691 | ||
| 688 | if (kgdb_reenter_check(ks)) | 692 | if (kgdb_reenter_check(ks)) |
| @@ -732,6 +736,30 @@ int kgdb_nmicallback(int cpu, void *regs) | |||
| 732 | return 1; | 736 | return 1; |
| 733 | } | 737 | } |
| 734 | 738 | ||
| 739 | int kgdb_nmicallin(int cpu, int trapnr, void *regs, atomic_t *send_ready) | ||
| 740 | { | ||
| 741 | #ifdef CONFIG_SMP | ||
| 742 | if (!kgdb_io_ready(0) || !send_ready) | ||
| 743 | return 1; | ||
| 744 | |||
| 745 | if (kgdb_info[cpu].enter_kgdb == 0) { | ||
| 746 | struct kgdb_state kgdb_var; | ||
| 747 | struct kgdb_state *ks = &kgdb_var; | ||
| 748 | |||
| 749 | memset(ks, 0, sizeof(struct kgdb_state)); | ||
| 750 | ks->cpu = cpu; | ||
| 751 | ks->ex_vector = trapnr; | ||
| 752 | ks->signo = SIGTRAP; | ||
| 753 | ks->err_code = KGDB_KDB_REASON_SYSTEM_NMI; | ||
| 754 | ks->linux_regs = regs; | ||
| 755 | ks->send_ready = send_ready; | ||
| 756 | kgdb_cpu_enter(ks, regs, DCPU_WANT_MASTER); | ||
| 757 | return 0; | ||
| 758 | } | ||
| 759 | #endif | ||
| 760 | return 1; | ||
| 761 | } | ||
| 762 | |||
| 735 | static void kgdb_console_write(struct console *co, const char *s, | 763 | static void kgdb_console_write(struct console *co, const char *s, |
| 736 | unsigned count) | 764 | unsigned count) |
| 737 | { | 765 | { |
