diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-11 22:01:14 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-11 22:01:14 -0500 |
commit | 9b66bfb28049594fe2bb2b91607ba302f511ce8b (patch) | |
tree | e96e79b1864699800c3f2c2e06b482a995744daf /kernel | |
parent | c2136301e43cbb3b71d0163a9949f30dafcb4590 (diff) | |
parent | b5dfcb09debc38582c3cb72a3c1a88b919b07f2d (diff) |
Merge branch 'x86-uv-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 UV debug changes from Ingo Molnar:
"Various SGI UV debuggability improvements, amongst them KDB support,
with related core KDB enabling patches changing kernel/debug/kdb/"
* 'x86-uv-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
Revert "x86/UV: Add uvtrace support"
x86/UV: Add call to KGDB/KDB from NMI handler
kdb: Add support for external NMI handler to call KGDB/KDB
x86/UV: Check for alloc_cpumask_var() failures properly in uv_nmi_setup()
x86/UV: Add uvtrace support
x86/UV: Add kdump to UV NMI handler
x86/UV: Add summary of cpu activity to UV NMI handler
x86/UV: Update UV support for external NMI signals
x86/UV: Move NMI support
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/debug/debug_core.c | 32 | ||||
-rw-r--r-- | kernel/debug/debug_core.h | 3 | ||||
-rw-r--r-- | kernel/debug/kdb/kdb_debugger.c | 5 | ||||
-rw-r--r-- | kernel/debug/kdb/kdb_main.c | 3 |
4 files changed, 40 insertions, 3 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 | { |
diff --git a/kernel/debug/debug_core.h b/kernel/debug/debug_core.h index 2235967e78b0..572aa4f5677c 100644 --- a/kernel/debug/debug_core.h +++ b/kernel/debug/debug_core.h | |||
@@ -26,6 +26,7 @@ struct kgdb_state { | |||
26 | unsigned long threadid; | 26 | unsigned long threadid; |
27 | long kgdb_usethreadid; | 27 | long kgdb_usethreadid; |
28 | struct pt_regs *linux_regs; | 28 | struct pt_regs *linux_regs; |
29 | atomic_t *send_ready; | ||
29 | }; | 30 | }; |
30 | 31 | ||
31 | /* Exception state values */ | 32 | /* Exception state values */ |
@@ -74,11 +75,13 @@ extern int kdb_stub(struct kgdb_state *ks); | |||
74 | extern int kdb_parse(const char *cmdstr); | 75 | extern int kdb_parse(const char *cmdstr); |
75 | extern int kdb_common_init_state(struct kgdb_state *ks); | 76 | extern int kdb_common_init_state(struct kgdb_state *ks); |
76 | extern int kdb_common_deinit_state(void); | 77 | extern int kdb_common_deinit_state(void); |
78 | #define KGDB_KDB_REASON_SYSTEM_NMI KDB_REASON_SYSTEM_NMI | ||
77 | #else /* ! CONFIG_KGDB_KDB */ | 79 | #else /* ! CONFIG_KGDB_KDB */ |
78 | static inline int kdb_stub(struct kgdb_state *ks) | 80 | static inline int kdb_stub(struct kgdb_state *ks) |
79 | { | 81 | { |
80 | return DBG_PASS_EVENT; | 82 | return DBG_PASS_EVENT; |
81 | } | 83 | } |
84 | #define KGDB_KDB_REASON_SYSTEM_NMI 0 | ||
82 | #endif /* CONFIG_KGDB_KDB */ | 85 | #endif /* CONFIG_KGDB_KDB */ |
83 | 86 | ||
84 | #endif /* _DEBUG_CORE_H_ */ | 87 | #endif /* _DEBUG_CORE_H_ */ |
diff --git a/kernel/debug/kdb/kdb_debugger.c b/kernel/debug/kdb/kdb_debugger.c index 328d18ef31e4..8859ca34dcfe 100644 --- a/kernel/debug/kdb/kdb_debugger.c +++ b/kernel/debug/kdb/kdb_debugger.c | |||
@@ -69,7 +69,10 @@ int kdb_stub(struct kgdb_state *ks) | |||
69 | if (atomic_read(&kgdb_setting_breakpoint)) | 69 | if (atomic_read(&kgdb_setting_breakpoint)) |
70 | reason = KDB_REASON_KEYBOARD; | 70 | reason = KDB_REASON_KEYBOARD; |
71 | 71 | ||
72 | if (in_nmi()) | 72 | if (ks->err_code == KDB_REASON_SYSTEM_NMI && ks->signo == SIGTRAP) |
73 | reason = KDB_REASON_SYSTEM_NMI; | ||
74 | |||
75 | else if (in_nmi()) | ||
73 | reason = KDB_REASON_NMI; | 76 | reason = KDB_REASON_NMI; |
74 | 77 | ||
75 | for (i = 0, bp = kdb_breakpoints; i < KDB_MAXBPT; i++, bp++) { | 78 | for (i = 0, bp = kdb_breakpoints; i < KDB_MAXBPT; i++, bp++) { |
diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c index 00eb8f7fbf41..0b097c8a1e50 100644 --- a/kernel/debug/kdb/kdb_main.c +++ b/kernel/debug/kdb/kdb_main.c | |||
@@ -1200,6 +1200,9 @@ static int kdb_local(kdb_reason_t reason, int error, struct pt_regs *regs, | |||
1200 | instruction_pointer(regs)); | 1200 | instruction_pointer(regs)); |
1201 | kdb_dumpregs(regs); | 1201 | kdb_dumpregs(regs); |
1202 | break; | 1202 | break; |
1203 | case KDB_REASON_SYSTEM_NMI: | ||
1204 | kdb_printf("due to System NonMaskable Interrupt\n"); | ||
1205 | break; | ||
1203 | case KDB_REASON_NMI: | 1206 | case KDB_REASON_NMI: |
1204 | kdb_printf("due to NonMaskable Interrupt @ " | 1207 | kdb_printf("due to NonMaskable Interrupt @ " |
1205 | kdb_machreg_fmt "\n", | 1208 | kdb_machreg_fmt "\n", |