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 | { |