diff options
-rw-r--r-- | arch/x86/include/asm/kgdb.h | 3 | ||||
-rw-r--r-- | arch/x86/kernel/kgdb.c | 22 | ||||
-rw-r--r-- | arch/x86/kernel/traps.c | 6 | ||||
-rw-r--r-- | include/linux/kgdb.h | 1 | ||||
-rw-r--r-- | kernel/debug/debug_core.c | 2 | ||||
-rw-r--r-- | lib/Kconfig.kgdb | 9 |
6 files changed, 41 insertions, 2 deletions
diff --git a/arch/x86/include/asm/kgdb.h b/arch/x86/include/asm/kgdb.h index e6c6c808489f..006da3687cdc 100644 --- a/arch/x86/include/asm/kgdb.h +++ b/arch/x86/include/asm/kgdb.h | |||
@@ -76,4 +76,7 @@ static inline void arch_kgdb_breakpoint(void) | |||
76 | #define BREAK_INSTR_SIZE 1 | 76 | #define BREAK_INSTR_SIZE 1 |
77 | #define CACHE_FLUSH_IS_SAFE 1 | 77 | #define CACHE_FLUSH_IS_SAFE 1 |
78 | 78 | ||
79 | extern int kgdb_ll_trap(int cmd, const char *str, | ||
80 | struct pt_regs *regs, long err, int trap, int sig); | ||
81 | |||
79 | #endif /* _ASM_X86_KGDB_H */ | 82 | #endif /* _ASM_X86_KGDB_H */ |
diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c index acba57169938..95b89d4cb8f1 100644 --- a/arch/x86/kernel/kgdb.c +++ b/arch/x86/kernel/kgdb.c | |||
@@ -538,7 +538,7 @@ static int __kgdb_notify(struct die_args *args, unsigned long cmd) | |||
538 | return NOTIFY_DONE; | 538 | return NOTIFY_DONE; |
539 | } | 539 | } |
540 | 540 | ||
541 | if (kgdb_handle_exception(args->trapnr, args->signr, args->err, regs)) | 541 | if (kgdb_handle_exception(args->trapnr, args->signr, cmd, regs)) |
542 | return NOTIFY_DONE; | 542 | return NOTIFY_DONE; |
543 | 543 | ||
544 | /* Must touch watchdog before return to normal operation */ | 544 | /* Must touch watchdog before return to normal operation */ |
@@ -546,6 +546,26 @@ static int __kgdb_notify(struct die_args *args, unsigned long cmd) | |||
546 | return NOTIFY_STOP; | 546 | return NOTIFY_STOP; |
547 | } | 547 | } |
548 | 548 | ||
549 | #ifdef CONFIG_KGDB_LOW_LEVEL_TRAP | ||
550 | int kgdb_ll_trap(int cmd, const char *str, | ||
551 | struct pt_regs *regs, long err, int trap, int sig) | ||
552 | { | ||
553 | struct die_args args = { | ||
554 | .regs = regs, | ||
555 | .str = str, | ||
556 | .err = err, | ||
557 | .trapnr = trap, | ||
558 | .signr = sig, | ||
559 | |||
560 | }; | ||
561 | |||
562 | if (!kgdb_io_module_registered) | ||
563 | return NOTIFY_DONE; | ||
564 | |||
565 | return __kgdb_notify(&args, cmd); | ||
566 | } | ||
567 | #endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */ | ||
568 | |||
549 | static int | 569 | static int |
550 | kgdb_notify(struct notifier_block *self, unsigned long cmd, void *ptr) | 570 | kgdb_notify(struct notifier_block *self, unsigned long cmd, void *ptr) |
551 | { | 571 | { |
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 02cfb9b8f5b1..7eaad4c5110a 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/kprobes.h> | 15 | #include <linux/kprobes.h> |
16 | #include <linux/uaccess.h> | 16 | #include <linux/uaccess.h> |
17 | #include <linux/kdebug.h> | 17 | #include <linux/kdebug.h> |
18 | #include <linux/kgdb.h> | ||
18 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
19 | #include <linux/module.h> | 20 | #include <linux/module.h> |
20 | #include <linux/ptrace.h> | 21 | #include <linux/ptrace.h> |
@@ -451,6 +452,11 @@ void restart_nmi(void) | |||
451 | /* May run on IST stack. */ | 452 | /* May run on IST stack. */ |
452 | dotraplinkage void __kprobes do_int3(struct pt_regs *regs, long error_code) | 453 | dotraplinkage void __kprobes do_int3(struct pt_regs *regs, long error_code) |
453 | { | 454 | { |
455 | #ifdef CONFIG_KGDB_LOW_LEVEL_TRAP | ||
456 | if (kgdb_ll_trap(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP) | ||
457 | == NOTIFY_STOP) | ||
458 | return; | ||
459 | #endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */ | ||
454 | #ifdef CONFIG_KPROBES | 460 | #ifdef CONFIG_KPROBES |
455 | if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP) | 461 | if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP) |
456 | == NOTIFY_STOP) | 462 | == NOTIFY_STOP) |
diff --git a/include/linux/kgdb.h b/include/linux/kgdb.h index 406f6f9286f3..19d1b29a2694 100644 --- a/include/linux/kgdb.h +++ b/include/linux/kgdb.h | |||
@@ -60,6 +60,7 @@ struct uart_port; | |||
60 | void kgdb_breakpoint(void); | 60 | void kgdb_breakpoint(void); |
61 | 61 | ||
62 | extern int kgdb_connected; | 62 | extern int kgdb_connected; |
63 | extern int kgdb_io_module_registered; | ||
63 | 64 | ||
64 | extern atomic_t kgdb_setting_breakpoint; | 65 | extern atomic_t kgdb_setting_breakpoint; |
65 | extern atomic_t kgdb_cpu_doing_single_step; | 66 | extern atomic_t kgdb_cpu_doing_single_step; |
diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c index 88a83a225374..375e42f0baf0 100644 --- a/kernel/debug/debug_core.c +++ b/kernel/debug/debug_core.c | |||
@@ -66,7 +66,7 @@ int kgdb_connected; | |||
66 | EXPORT_SYMBOL_GPL(kgdb_connected); | 66 | EXPORT_SYMBOL_GPL(kgdb_connected); |
67 | 67 | ||
68 | /* All the KGDB handlers are installed */ | 68 | /* All the KGDB handlers are installed */ |
69 | static int kgdb_io_module_registered; | 69 | int kgdb_io_module_registered; |
70 | 70 | ||
71 | /* Guard for recursive entry */ | 71 | /* Guard for recursive entry */ |
72 | static int exception_level; | 72 | static int exception_level; |
diff --git a/lib/Kconfig.kgdb b/lib/Kconfig.kgdb index ee8ae7132f20..c56ccb4ad292 100644 --- a/lib/Kconfig.kgdb +++ b/lib/Kconfig.kgdb | |||
@@ -57,6 +57,15 @@ config KGDB_TESTS_BOOT_STRING | |||
57 | information about other strings you could use beyond the | 57 | information about other strings you could use beyond the |
58 | default of V1F100. | 58 | default of V1F100. |
59 | 59 | ||
60 | config KGDB_LOW_LEVEL_TRAP | ||
61 | bool "KGDB: Allow debugging with traps in notifiers" | ||
62 | depends on X86 | ||
63 | default n | ||
64 | help | ||
65 | This will add an extra call back to kgdb for the breakpoint | ||
66 | exception handler on which will will allow kgdb to step | ||
67 | through a notify handler. | ||
68 | |||
60 | config KGDB_KDB | 69 | config KGDB_KDB |
61 | bool "KGDB_KDB: include kdb frontend for kgdb" | 70 | bool "KGDB_KDB: include kdb frontend for kgdb" |
62 | default n | 71 | default n |