diff options
| -rw-r--r-- | Documentation/kernel-parameters.txt | 17 | ||||
| -rw-r--r-- | arch/x86/include/asm/processor.h | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/common.c | 29 | ||||
| -rw-r--r-- | arch/x86/kernel/early_printk.c | 8 | ||||
| -rw-r--r-- | arch/x86/kernel/kgdb.c | 47 | ||||
| -rw-r--r-- | arch/x86/kernel/setup.c | 1 | ||||
| -rw-r--r-- | arch/x86/kernel/traps.c | 14 | ||||
| -rw-r--r-- | drivers/serial/kgdboc.c | 19 | ||||
| -rw-r--r-- | drivers/usb/early/ehci-dbgp.c | 120 | ||||
| -rw-r--r-- | include/linux/kgdb.h | 14 | ||||
| -rw-r--r-- | init/main.c | 4 | ||||
| -rw-r--r-- | kernel/debug/debug_core.c | 16 |
12 files changed, 255 insertions, 36 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index bdce359820bb..f5fce483930c 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
| @@ -713,6 +713,12 @@ and is between 256 and 4096 characters. It is defined in the file | |||
| 713 | The VGA output is eventually overwritten by the real | 713 | The VGA output is eventually overwritten by the real |
| 714 | console. | 714 | console. |
| 715 | 715 | ||
| 716 | ekgdboc= [X86,KGDB] Allow early kernel console debugging | ||
| 717 | ekgdboc=kbd | ||
| 718 | |||
| 719 | This is desgined to be used in conjunction with | ||
| 720 | the boot argument: earlyprintk=vga | ||
| 721 | |||
| 716 | eata= [HW,SCSI] | 722 | eata= [HW,SCSI] |
| 717 | 723 | ||
| 718 | edd= [EDD] | 724 | edd= [EDD] |
| @@ -1121,6 +1127,17 @@ and is between 256 and 4096 characters. It is defined in the file | |||
| 1121 | use the HighMem zone if it exists, and the Normal | 1127 | use the HighMem zone if it exists, and the Normal |
| 1122 | zone if it does not. | 1128 | zone if it does not. |
| 1123 | 1129 | ||
| 1130 | kgdbdbgp= [KGDB,HW] kgdb over EHCI usb debug port. | ||
| 1131 | Format: <Controller#>[,poll interval] | ||
| 1132 | The controller # is the number of the ehci usb debug | ||
| 1133 | port as it is probed via PCI. The poll interval is | ||
| 1134 | optional and is the number seconds in between | ||
| 1135 | each poll cycle to the debug port in case you need | ||
| 1136 | the functionality for interrupting the kernel with | ||
| 1137 | gdb or control-c on the dbgp connection. When | ||
| 1138 | not using this parameter you use sysrq-g to break into | ||
| 1139 | the kernel debugger. | ||
| 1140 | |||
| 1124 | kgdboc= [KGDB,HW] kgdb over consoles. | 1141 | kgdboc= [KGDB,HW] kgdb over consoles. |
| 1125 | Requires a tty driver that supports console polling, | 1142 | Requires a tty driver that supports console polling, |
| 1126 | or a supported polling keyboard driver (non-usb). | 1143 | or a supported polling keyboard driver (non-usb). |
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 5a51379dcbe4..7e5c6a60b8ee 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h | |||
| @@ -789,6 +789,8 @@ static inline void wbinvd_halt(void) | |||
| 789 | extern void enable_sep_cpu(void); | 789 | extern void enable_sep_cpu(void); |
| 790 | extern int sysenter_setup(void); | 790 | extern int sysenter_setup(void); |
| 791 | 791 | ||
| 792 | extern void early_trap_init(void); | ||
| 793 | |||
| 792 | /* Defined in head.S */ | 794 | /* Defined in head.S */ |
| 793 | extern struct desc_ptr early_gdt_descr; | 795 | extern struct desc_ptr early_gdt_descr; |
| 794 | 796 | ||
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index c1c00d0b1692..cc83a002786e 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
| @@ -1084,6 +1084,20 @@ static void clear_all_debug_regs(void) | |||
| 1084 | } | 1084 | } |
| 1085 | } | 1085 | } |
| 1086 | 1086 | ||
| 1087 | #ifdef CONFIG_KGDB | ||
| 1088 | /* | ||
| 1089 | * Restore debug regs if using kgdbwait and you have a kernel debugger | ||
| 1090 | * connection established. | ||
| 1091 | */ | ||
| 1092 | static void dbg_restore_debug_regs(void) | ||
| 1093 | { | ||
| 1094 | if (unlikely(kgdb_connected && arch_kgdb_ops.correct_hw_break)) | ||
| 1095 | arch_kgdb_ops.correct_hw_break(); | ||
| 1096 | } | ||
| 1097 | #else /* ! CONFIG_KGDB */ | ||
| 1098 | #define dbg_restore_debug_regs() | ||
| 1099 | #endif /* ! CONFIG_KGDB */ | ||
| 1100 | |||
| 1087 | /* | 1101 | /* |
| 1088 | * cpu_init() initializes state that is per-CPU. Some data is already | 1102 | * cpu_init() initializes state that is per-CPU. Some data is already |
| 1089 | * initialized (naturally) in the bootstrap process, such as the GDT | 1103 | * initialized (naturally) in the bootstrap process, such as the GDT |
| @@ -1174,18 +1188,8 @@ void __cpuinit cpu_init(void) | |||
| 1174 | load_TR_desc(); | 1188 | load_TR_desc(); |
| 1175 | load_LDT(&init_mm.context); | 1189 | load_LDT(&init_mm.context); |
| 1176 | 1190 | ||
| 1177 | #ifdef CONFIG_KGDB | 1191 | clear_all_debug_regs(); |
| 1178 | /* | 1192 | dbg_restore_debug_regs(); |
| 1179 | * If the kgdb is connected no debug regs should be altered. This | ||
| 1180 | * is only applicable when KGDB and a KGDB I/O module are built | ||
| 1181 | * into the kernel and you are using early debugging with | ||
| 1182 | * kgdbwait. KGDB will control the kernel HW breakpoint registers. | ||
| 1183 | */ | ||
| 1184 | if (kgdb_connected && arch_kgdb_ops.correct_hw_break) | ||
| 1185 | arch_kgdb_ops.correct_hw_break(); | ||
| 1186 | else | ||
| 1187 | #endif | ||
| 1188 | clear_all_debug_regs(); | ||
| 1189 | 1193 | ||
| 1190 | fpu_init(); | 1194 | fpu_init(); |
| 1191 | 1195 | ||
| @@ -1239,6 +1243,7 @@ void __cpuinit cpu_init(void) | |||
| 1239 | #endif | 1243 | #endif |
| 1240 | 1244 | ||
| 1241 | clear_all_debug_regs(); | 1245 | clear_all_debug_regs(); |
| 1246 | dbg_restore_debug_regs(); | ||
| 1242 | 1247 | ||
| 1243 | /* | 1248 | /* |
| 1244 | * Force FPU initialization: | 1249 | * Force FPU initialization: |
diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c index b9c830c12b4a..fa99bae75ace 100644 --- a/arch/x86/kernel/early_printk.c +++ b/arch/x86/kernel/early_printk.c | |||
| @@ -41,6 +41,14 @@ static void early_vga_write(struct console *con, const char *str, unsigned n) | |||
| 41 | writew(0x720, VGABASE + 2*(max_xpos*j + i)); | 41 | writew(0x720, VGABASE + 2*(max_xpos*j + i)); |
| 42 | current_ypos = max_ypos-1; | 42 | current_ypos = max_ypos-1; |
| 43 | } | 43 | } |
| 44 | #ifdef CONFIG_KGDB_KDB | ||
| 45 | if (c == '\b') { | ||
| 46 | if (current_xpos > 0) | ||
| 47 | current_xpos--; | ||
| 48 | } else if (c == '\r') { | ||
| 49 | current_xpos = 0; | ||
| 50 | } else | ||
| 51 | #endif | ||
| 44 | if (c == '\n') { | 52 | if (c == '\n') { |
| 45 | current_xpos = 0; | 53 | current_xpos = 0; |
| 46 | current_ypos++; | 54 | current_ypos++; |
diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c index 95b89d4cb8f1..4f4af75b9482 100644 --- a/arch/x86/kernel/kgdb.c +++ b/arch/x86/kernel/kgdb.c | |||
| @@ -199,6 +199,8 @@ static struct hw_breakpoint { | |||
| 199 | struct perf_event **pev; | 199 | struct perf_event **pev; |
| 200 | } breakinfo[4]; | 200 | } breakinfo[4]; |
| 201 | 201 | ||
| 202 | static unsigned long early_dr7; | ||
| 203 | |||
| 202 | static void kgdb_correct_hw_break(void) | 204 | static void kgdb_correct_hw_break(void) |
| 203 | { | 205 | { |
| 204 | int breakno; | 206 | int breakno; |
| @@ -210,6 +212,14 @@ static void kgdb_correct_hw_break(void) | |||
| 210 | int cpu = raw_smp_processor_id(); | 212 | int cpu = raw_smp_processor_id(); |
| 211 | if (!breakinfo[breakno].enabled) | 213 | if (!breakinfo[breakno].enabled) |
| 212 | continue; | 214 | continue; |
| 215 | if (dbg_is_early) { | ||
| 216 | set_debugreg(breakinfo[breakno].addr, breakno); | ||
| 217 | early_dr7 |= encode_dr7(breakno, | ||
| 218 | breakinfo[breakno].len, | ||
| 219 | breakinfo[breakno].type); | ||
| 220 | set_debugreg(early_dr7, 7); | ||
| 221 | continue; | ||
| 222 | } | ||
| 213 | bp = *per_cpu_ptr(breakinfo[breakno].pev, cpu); | 223 | bp = *per_cpu_ptr(breakinfo[breakno].pev, cpu); |
| 214 | info = counter_arch_bp(bp); | 224 | info = counter_arch_bp(bp); |
| 215 | if (bp->attr.disabled != 1) | 225 | if (bp->attr.disabled != 1) |
| @@ -224,7 +234,8 @@ static void kgdb_correct_hw_break(void) | |||
| 224 | if (!val) | 234 | if (!val) |
| 225 | bp->attr.disabled = 0; | 235 | bp->attr.disabled = 0; |
| 226 | } | 236 | } |
| 227 | hw_breakpoint_restore(); | 237 | if (!dbg_is_early) |
| 238 | hw_breakpoint_restore(); | ||
| 228 | } | 239 | } |
| 229 | 240 | ||
| 230 | static int hw_break_reserve_slot(int breakno) | 241 | static int hw_break_reserve_slot(int breakno) |
| @@ -233,6 +244,9 @@ static int hw_break_reserve_slot(int breakno) | |||
| 233 | int cnt = 0; | 244 | int cnt = 0; |
| 234 | struct perf_event **pevent; | 245 | struct perf_event **pevent; |
| 235 | 246 | ||
| 247 | if (dbg_is_early) | ||
| 248 | return 0; | ||
| 249 | |||
| 236 | for_each_online_cpu(cpu) { | 250 | for_each_online_cpu(cpu) { |
| 237 | cnt++; | 251 | cnt++; |
| 238 | pevent = per_cpu_ptr(breakinfo[breakno].pev, cpu); | 252 | pevent = per_cpu_ptr(breakinfo[breakno].pev, cpu); |
| @@ -258,6 +272,9 @@ static int hw_break_release_slot(int breakno) | |||
| 258 | struct perf_event **pevent; | 272 | struct perf_event **pevent; |
| 259 | int cpu; | 273 | int cpu; |
| 260 | 274 | ||
| 275 | if (dbg_is_early) | ||
| 276 | return 0; | ||
| 277 | |||
| 261 | for_each_online_cpu(cpu) { | 278 | for_each_online_cpu(cpu) { |
| 262 | pevent = per_cpu_ptr(breakinfo[breakno].pev, cpu); | 279 | pevent = per_cpu_ptr(breakinfo[breakno].pev, cpu); |
| 263 | if (dbg_release_bp_slot(*pevent)) | 280 | if (dbg_release_bp_slot(*pevent)) |
| @@ -302,7 +319,11 @@ static void kgdb_remove_all_hw_break(void) | |||
| 302 | bp = *per_cpu_ptr(breakinfo[i].pev, cpu); | 319 | bp = *per_cpu_ptr(breakinfo[i].pev, cpu); |
| 303 | if (bp->attr.disabled == 1) | 320 | if (bp->attr.disabled == 1) |
| 304 | continue; | 321 | continue; |
| 305 | arch_uninstall_hw_breakpoint(bp); | 322 | if (dbg_is_early) |
| 323 | early_dr7 &= ~encode_dr7(i, breakinfo[i].len, | ||
| 324 | breakinfo[i].type); | ||
| 325 | else | ||
| 326 | arch_uninstall_hw_breakpoint(bp); | ||
| 306 | bp->attr.disabled = 1; | 327 | bp->attr.disabled = 1; |
| 307 | } | 328 | } |
| 308 | } | 329 | } |
| @@ -379,6 +400,11 @@ void kgdb_disable_hw_debug(struct pt_regs *regs) | |||
| 379 | for (i = 0; i < 4; i++) { | 400 | for (i = 0; i < 4; i++) { |
| 380 | if (!breakinfo[i].enabled) | 401 | if (!breakinfo[i].enabled) |
| 381 | continue; | 402 | continue; |
| 403 | if (dbg_is_early) { | ||
| 404 | early_dr7 &= ~encode_dr7(i, breakinfo[i].len, | ||
| 405 | breakinfo[i].type); | ||
| 406 | continue; | ||
| 407 | } | ||
| 382 | bp = *per_cpu_ptr(breakinfo[i].pev, cpu); | 408 | bp = *per_cpu_ptr(breakinfo[i].pev, cpu); |
| 383 | if (bp->attr.disabled == 1) | 409 | if (bp->attr.disabled == 1) |
| 384 | continue; | 410 | continue; |
| @@ -596,14 +622,15 @@ static struct notifier_block kgdb_notifier = { | |||
| 596 | */ | 622 | */ |
| 597 | int kgdb_arch_init(void) | 623 | int kgdb_arch_init(void) |
| 598 | { | 624 | { |
| 625 | return register_die_notifier(&kgdb_notifier); | ||
| 626 | } | ||
| 627 | |||
| 628 | void kgdb_arch_late(void) | ||
| 629 | { | ||
| 599 | int i, cpu; | 630 | int i, cpu; |
| 600 | int ret; | ||
| 601 | struct perf_event_attr attr; | 631 | struct perf_event_attr attr; |
| 602 | struct perf_event **pevent; | 632 | struct perf_event **pevent; |
| 603 | 633 | ||
| 604 | ret = register_die_notifier(&kgdb_notifier); | ||
| 605 | if (ret != 0) | ||
| 606 | return ret; | ||
| 607 | /* | 634 | /* |
| 608 | * Pre-allocate the hw breakpoint structions in the non-atomic | 635 | * Pre-allocate the hw breakpoint structions in the non-atomic |
| 609 | * portion of kgdb because this operation requires mutexs to | 636 | * portion of kgdb because this operation requires mutexs to |
| @@ -615,12 +642,15 @@ int kgdb_arch_init(void) | |||
| 615 | attr.bp_type = HW_BREAKPOINT_W; | 642 | attr.bp_type = HW_BREAKPOINT_W; |
| 616 | attr.disabled = 1; | 643 | attr.disabled = 1; |
| 617 | for (i = 0; i < 4; i++) { | 644 | for (i = 0; i < 4; i++) { |
| 645 | if (breakinfo[i].pev) | ||
| 646 | continue; | ||
| 618 | breakinfo[i].pev = register_wide_hw_breakpoint(&attr, NULL); | 647 | breakinfo[i].pev = register_wide_hw_breakpoint(&attr, NULL); |
| 619 | if (IS_ERR(breakinfo[i].pev)) { | 648 | if (IS_ERR(breakinfo[i].pev)) { |
| 620 | printk(KERN_ERR "kgdb: Could not allocate hw breakpoints\n"); | 649 | printk(KERN_ERR "kgdb: Could not allocate hw" |
| 650 | "breakpoints\nDisabling the kernel debugger\n"); | ||
| 621 | breakinfo[i].pev = NULL; | 651 | breakinfo[i].pev = NULL; |
| 622 | kgdb_arch_exit(); | 652 | kgdb_arch_exit(); |
| 623 | return -1; | 653 | return; |
| 624 | } | 654 | } |
| 625 | for_each_online_cpu(cpu) { | 655 | for_each_online_cpu(cpu) { |
| 626 | pevent = per_cpu_ptr(breakinfo[i].pev, cpu); | 656 | pevent = per_cpu_ptr(breakinfo[i].pev, cpu); |
| @@ -631,7 +661,6 @@ int kgdb_arch_init(void) | |||
| 631 | } | 661 | } |
| 632 | } | 662 | } |
| 633 | } | 663 | } |
| 634 | return ret; | ||
| 635 | } | 664 | } |
| 636 | 665 | ||
| 637 | /** | 666 | /** |
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index c4851eff57b3..e8029896309a 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
| @@ -725,6 +725,7 @@ void __init setup_arch(char **cmdline_p) | |||
| 725 | /* VMI may relocate the fixmap; do this before touching ioremap area */ | 725 | /* VMI may relocate the fixmap; do this before touching ioremap area */ |
| 726 | vmi_init(); | 726 | vmi_init(); |
| 727 | 727 | ||
| 728 | early_trap_init(); | ||
| 728 | early_cpu_init(); | 729 | early_cpu_init(); |
| 729 | early_ioremap_init(); | 730 | early_ioremap_init(); |
| 730 | 731 | ||
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 7eaad4c5110a..142d70c74b02 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c | |||
| @@ -808,6 +808,16 @@ dotraplinkage void do_iret_error(struct pt_regs *regs, long error_code) | |||
| 808 | } | 808 | } |
| 809 | #endif | 809 | #endif |
| 810 | 810 | ||
| 811 | /* Set of traps needed for early debugging. */ | ||
| 812 | void __init early_trap_init(void) | ||
| 813 | { | ||
| 814 | set_intr_gate_ist(1, &debug, DEBUG_STACK); | ||
| 815 | /* int3 can be called from all */ | ||
| 816 | set_system_intr_gate_ist(3, &int3, DEBUG_STACK); | ||
| 817 | set_intr_gate(14, &page_fault); | ||
| 818 | load_idt(&idt_descr); | ||
| 819 | } | ||
| 820 | |||
| 811 | void __init trap_init(void) | 821 | void __init trap_init(void) |
| 812 | { | 822 | { |
| 813 | int i; | 823 | int i; |
| @@ -821,10 +831,7 @@ void __init trap_init(void) | |||
| 821 | #endif | 831 | #endif |
| 822 | 832 | ||
| 823 | set_intr_gate(0, ÷_error); | 833 | set_intr_gate(0, ÷_error); |
| 824 | set_intr_gate_ist(1, &debug, DEBUG_STACK); | ||
| 825 | set_intr_gate_ist(2, &nmi, NMI_STACK); | 834 | set_intr_gate_ist(2, &nmi, NMI_STACK); |
| 826 | /* int3 can be called from all */ | ||
| 827 | set_system_intr_gate_ist(3, &int3, DEBUG_STACK); | ||
| 828 | /* int4 can be called from all */ | 835 | /* int4 can be called from all */ |
| 829 | set_system_intr_gate(4, &overflow); | 836 | set_system_intr_gate(4, &overflow); |
| 830 | set_intr_gate(5, &bounds); | 837 | set_intr_gate(5, &bounds); |
| @@ -840,7 +847,6 @@ void __init trap_init(void) | |||
| 840 | set_intr_gate(11, &segment_not_present); | 847 | set_intr_gate(11, &segment_not_present); |
| 841 | set_intr_gate_ist(12, &stack_segment, STACKFAULT_STACK); | 848 | set_intr_gate_ist(12, &stack_segment, STACKFAULT_STACK); |
| 842 | set_intr_gate(13, &general_protection); | 849 | set_intr_gate(13, &general_protection); |
| 843 | set_intr_gate(14, &page_fault); | ||
| 844 | set_intr_gate(15, &spurious_interrupt_bug); | 850 | set_intr_gate(15, &spurious_interrupt_bug); |
| 845 | set_intr_gate(16, &coprocessor_error); | 851 | set_intr_gate(16, &coprocessor_error); |
| 846 | set_intr_gate(17, &alignment_check); | 852 | set_intr_gate(17, &alignment_check); |
diff --git a/drivers/serial/kgdboc.c b/drivers/serial/kgdboc.c index b765ab48dfe7..a9a94ae72349 100644 --- a/drivers/serial/kgdboc.c +++ b/drivers/serial/kgdboc.c | |||
| @@ -223,6 +223,25 @@ static struct kgdb_io kgdboc_io_ops = { | |||
| 223 | .post_exception = kgdboc_post_exp_handler, | 223 | .post_exception = kgdboc_post_exp_handler, |
| 224 | }; | 224 | }; |
| 225 | 225 | ||
| 226 | #ifdef CONFIG_KGDB_SERIAL_CONSOLE | ||
| 227 | /* This is only available if kgdboc is a built in for early debugging */ | ||
| 228 | int __init kgdboc_early_init(char *opt) | ||
| 229 | { | ||
| 230 | /* save the first character of the config string because the | ||
| 231 | * init routine can destroy it. | ||
| 232 | */ | ||
| 233 | char save_ch; | ||
| 234 | |||
| 235 | kgdboc_option_setup(opt); | ||
| 236 | save_ch = config[0]; | ||
| 237 | init_kgdboc(); | ||
| 238 | config[0] = save_ch; | ||
| 239 | return 0; | ||
| 240 | } | ||
| 241 | |||
| 242 | early_param("ekgdboc", kgdboc_early_init); | ||
| 243 | #endif /* CONFIG_KGDB_SERIAL_CONSOLE */ | ||
| 244 | |||
| 226 | module_init(init_kgdboc); | 245 | module_init(init_kgdboc); |
| 227 | module_exit(cleanup_kgdboc); | 246 | module_exit(cleanup_kgdboc); |
| 228 | module_param_call(kgdboc, param_set_kgdboc_var, param_get_string, &kps, 0644); | 247 | module_param_call(kgdboc, param_set_kgdboc_var, param_get_string, &kps, 0644); |
diff --git a/drivers/usb/early/ehci-dbgp.c b/drivers/usb/early/ehci-dbgp.c index 6e98a3697844..94ecdbc758ce 100644 --- a/drivers/usb/early/ehci-dbgp.c +++ b/drivers/usb/early/ehci-dbgp.c | |||
| @@ -19,6 +19,9 @@ | |||
| 19 | #include <linux/usb/ch9.h> | 19 | #include <linux/usb/ch9.h> |
| 20 | #include <linux/usb/ehci_def.h> | 20 | #include <linux/usb/ehci_def.h> |
| 21 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
| 22 | #include <linux/serial_core.h> | ||
| 23 | #include <linux/kgdb.h> | ||
| 24 | #include <linux/kthread.h> | ||
| 22 | #include <asm/io.h> | 25 | #include <asm/io.h> |
| 23 | #include <asm/pci-direct.h> | 26 | #include <asm/pci-direct.h> |
| 24 | #include <asm/fixmap.h> | 27 | #include <asm/fixmap.h> |
| @@ -55,6 +58,7 @@ static struct ehci_regs __iomem *ehci_regs; | |||
| 55 | static struct ehci_dbg_port __iomem *ehci_debug; | 58 | static struct ehci_dbg_port __iomem *ehci_debug; |
| 56 | static int dbgp_not_safe; /* Cannot use debug device during ehci reset */ | 59 | static int dbgp_not_safe; /* Cannot use debug device during ehci reset */ |
| 57 | static unsigned int dbgp_endpoint_out; | 60 | static unsigned int dbgp_endpoint_out; |
| 61 | static unsigned int dbgp_endpoint_in; | ||
| 58 | 62 | ||
| 59 | struct ehci_dev { | 63 | struct ehci_dev { |
| 60 | u32 bus; | 64 | u32 bus; |
| @@ -91,6 +95,13 @@ static inline u32 dbgp_len_update(u32 x, u32 len) | |||
| 91 | return (x & ~0x0f) | (len & 0x0f); | 95 | return (x & ~0x0f) | (len & 0x0f); |
| 92 | } | 96 | } |
| 93 | 97 | ||
| 98 | #ifdef CONFIG_KGDB | ||
| 99 | static struct kgdb_io kgdbdbgp_io_ops; | ||
| 100 | #define dbgp_kgdb_mode (dbg_io_ops == &kgdbdbgp_io_ops) | ||
| 101 | #else | ||
| 102 | #define dbgp_kgdb_mode (0) | ||
| 103 | #endif | ||
| 104 | |||
| 94 | /* | 105 | /* |
| 95 | * USB Packet IDs (PIDs) | 106 | * USB Packet IDs (PIDs) |
| 96 | */ | 107 | */ |
| @@ -182,11 +193,10 @@ static void dbgp_breath(void) | |||
| 182 | /* Sleep to give the debug port a chance to breathe */ | 193 | /* Sleep to give the debug port a chance to breathe */ |
| 183 | } | 194 | } |
| 184 | 195 | ||
| 185 | static int dbgp_wait_until_done(unsigned ctrl) | 196 | static int dbgp_wait_until_done(unsigned ctrl, int loop) |
| 186 | { | 197 | { |
| 187 | u32 pids, lpid; | 198 | u32 pids, lpid; |
| 188 | int ret; | 199 | int ret; |
| 189 | int loop = DBGP_LOOPS; | ||
| 190 | 200 | ||
| 191 | retry: | 201 | retry: |
| 192 | writel(ctrl | DBGP_GO, &ehci_debug->control); | 202 | writel(ctrl | DBGP_GO, &ehci_debug->control); |
| @@ -276,13 +286,13 @@ static int dbgp_bulk_write(unsigned devnum, unsigned endpoint, | |||
| 276 | dbgp_set_data(bytes, size); | 286 | dbgp_set_data(bytes, size); |
| 277 | writel(addr, &ehci_debug->address); | 287 | writel(addr, &ehci_debug->address); |
| 278 | writel(pids, &ehci_debug->pids); | 288 | writel(pids, &ehci_debug->pids); |
| 279 | ret = dbgp_wait_until_done(ctrl); | 289 | ret = dbgp_wait_until_done(ctrl, DBGP_LOOPS); |
| 280 | 290 | ||
| 281 | return ret; | 291 | return ret; |
| 282 | } | 292 | } |
| 283 | 293 | ||
| 284 | static int dbgp_bulk_read(unsigned devnum, unsigned endpoint, void *data, | 294 | static int dbgp_bulk_read(unsigned devnum, unsigned endpoint, void *data, |
| 285 | int size) | 295 | int size, int loops) |
| 286 | { | 296 | { |
| 287 | u32 pids, addr, ctrl; | 297 | u32 pids, addr, ctrl; |
| 288 | int ret; | 298 | int ret; |
| @@ -302,7 +312,7 @@ static int dbgp_bulk_read(unsigned devnum, unsigned endpoint, void *data, | |||
| 302 | 312 | ||
| 303 | writel(addr, &ehci_debug->address); | 313 | writel(addr, &ehci_debug->address); |
| 304 | writel(pids, &ehci_debug->pids); | 314 | writel(pids, &ehci_debug->pids); |
| 305 | ret = dbgp_wait_until_done(ctrl); | 315 | ret = dbgp_wait_until_done(ctrl, loops); |
| 306 | if (ret < 0) | 316 | if (ret < 0) |
| 307 | return ret; | 317 | return ret; |
| 308 | 318 | ||
| @@ -343,12 +353,12 @@ static int dbgp_control_msg(unsigned devnum, int requesttype, | |||
| 343 | dbgp_set_data(&req, sizeof(req)); | 353 | dbgp_set_data(&req, sizeof(req)); |
| 344 | writel(addr, &ehci_debug->address); | 354 | writel(addr, &ehci_debug->address); |
| 345 | writel(pids, &ehci_debug->pids); | 355 | writel(pids, &ehci_debug->pids); |
| 346 | ret = dbgp_wait_until_done(ctrl); | 356 | ret = dbgp_wait_until_done(ctrl, DBGP_LOOPS); |
| 347 | if (ret < 0) | 357 | if (ret < 0) |
| 348 | return ret; | 358 | return ret; |
| 349 | 359 | ||
| 350 | /* Read the result */ | 360 | /* Read the result */ |
| 351 | return dbgp_bulk_read(devnum, 0, data, size); | 361 | return dbgp_bulk_read(devnum, 0, data, size, DBGP_LOOPS); |
| 352 | } | 362 | } |
| 353 | 363 | ||
| 354 | /* Find a PCI capability */ | 364 | /* Find a PCI capability */ |
| @@ -559,6 +569,7 @@ try_again: | |||
| 559 | goto err; | 569 | goto err; |
| 560 | } | 570 | } |
| 561 | dbgp_endpoint_out = dbgp_desc.bDebugOutEndpoint; | 571 | dbgp_endpoint_out = dbgp_desc.bDebugOutEndpoint; |
| 572 | dbgp_endpoint_in = dbgp_desc.bDebugInEndpoint; | ||
| 562 | 573 | ||
| 563 | /* Move the device to 127 if it isn't already there */ | 574 | /* Move the device to 127 if it isn't already there */ |
| 564 | if (devnum != USB_DEBUG_DEVNUM) { | 575 | if (devnum != USB_DEBUG_DEVNUM) { |
| @@ -968,8 +979,9 @@ int dbgp_reset_prep(void) | |||
| 968 | if (!ehci_debug) | 979 | if (!ehci_debug) |
| 969 | return 0; | 980 | return 0; |
| 970 | 981 | ||
| 971 | if (early_dbgp_console.index != -1 && | 982 | if ((early_dbgp_console.index != -1 && |
| 972 | !(early_dbgp_console.flags & CON_BOOT)) | 983 | !(early_dbgp_console.flags & CON_BOOT)) || |
| 984 | dbgp_kgdb_mode) | ||
| 973 | return 1; | 985 | return 1; |
| 974 | /* This means the console is not initialized, or should get | 986 | /* This means the console is not initialized, or should get |
| 975 | * shutdown so as to allow for reuse of the usb device, which | 987 | * shutdown so as to allow for reuse of the usb device, which |
| @@ -982,3 +994,93 @@ int dbgp_reset_prep(void) | |||
| 982 | return 0; | 994 | return 0; |
| 983 | } | 995 | } |
| 984 | EXPORT_SYMBOL_GPL(dbgp_reset_prep); | 996 | EXPORT_SYMBOL_GPL(dbgp_reset_prep); |
| 997 | |||
| 998 | #ifdef CONFIG_KGDB | ||
| 999 | |||
| 1000 | static char kgdbdbgp_buf[DBGP_MAX_PACKET]; | ||
| 1001 | static int kgdbdbgp_buf_sz; | ||
| 1002 | static int kgdbdbgp_buf_idx; | ||
| 1003 | static int kgdbdbgp_loop_cnt = DBGP_LOOPS; | ||
| 1004 | |||
| 1005 | static int kgdbdbgp_read_char(void) | ||
| 1006 | { | ||
| 1007 | int ret; | ||
| 1008 | |||
| 1009 | if (kgdbdbgp_buf_idx < kgdbdbgp_buf_sz) { | ||
| 1010 | char ch = kgdbdbgp_buf[kgdbdbgp_buf_idx++]; | ||
| 1011 | return ch; | ||
| 1012 | } | ||
| 1013 | |||
| 1014 | ret = dbgp_bulk_read(USB_DEBUG_DEVNUM, dbgp_endpoint_in, | ||
| 1015 | &kgdbdbgp_buf, DBGP_MAX_PACKET, | ||
| 1016 | kgdbdbgp_loop_cnt); | ||
| 1017 | if (ret <= 0) | ||
| 1018 | return NO_POLL_CHAR; | ||
| 1019 | kgdbdbgp_buf_sz = ret; | ||
| 1020 | kgdbdbgp_buf_idx = 1; | ||
| 1021 | return kgdbdbgp_buf[0]; | ||
| 1022 | } | ||
| 1023 | |||
| 1024 | static void kgdbdbgp_write_char(u8 chr) | ||
| 1025 | { | ||
| 1026 | early_dbgp_write(NULL, &chr, 1); | ||
| 1027 | } | ||
| 1028 | |||
| 1029 | static struct kgdb_io kgdbdbgp_io_ops = { | ||
| 1030 | .name = "kgdbdbgp", | ||
| 1031 | .read_char = kgdbdbgp_read_char, | ||
| 1032 | .write_char = kgdbdbgp_write_char, | ||
| 1033 | }; | ||
| 1034 | |||
| 1035 | static int kgdbdbgp_wait_time; | ||
| 1036 | |||
| 1037 | static int __init kgdbdbgp_parse_config(char *str) | ||
| 1038 | { | ||
| 1039 | char *ptr; | ||
| 1040 | |||
| 1041 | if (!ehci_debug) { | ||
| 1042 | if (early_dbgp_init(str)) | ||
| 1043 | return -1; | ||
| 1044 | } | ||
| 1045 | ptr = strchr(str, ','); | ||
| 1046 | if (ptr) { | ||
| 1047 | ptr++; | ||
| 1048 | kgdbdbgp_wait_time = simple_strtoul(ptr, &ptr, 10); | ||
| 1049 | } | ||
| 1050 | kgdb_register_io_module(&kgdbdbgp_io_ops); | ||
| 1051 | kgdbdbgp_io_ops.is_console = early_dbgp_console.index != -1; | ||
| 1052 | |||
| 1053 | return 0; | ||
| 1054 | } | ||
| 1055 | early_param("kgdbdbgp", kgdbdbgp_parse_config); | ||
| 1056 | |||
| 1057 | static int kgdbdbgp_reader_thread(void *ptr) | ||
| 1058 | { | ||
| 1059 | int ret; | ||
| 1060 | |||
| 1061 | while (readl(&ehci_debug->control) & DBGP_ENABLED) { | ||
| 1062 | kgdbdbgp_loop_cnt = 1; | ||
| 1063 | ret = kgdbdbgp_read_char(); | ||
| 1064 | kgdbdbgp_loop_cnt = DBGP_LOOPS; | ||
| 1065 | if (ret != NO_POLL_CHAR) { | ||
| 1066 | if (ret == 0x3 || ret == '$') { | ||
| 1067 | if (ret == '$') | ||
| 1068 | kgdbdbgp_buf_idx--; | ||
| 1069 | kgdb_breakpoint(); | ||
| 1070 | } | ||
| 1071 | continue; | ||
| 1072 | } | ||
| 1073 | schedule_timeout_interruptible(kgdbdbgp_wait_time * HZ); | ||
| 1074 | } | ||
| 1075 | return 0; | ||
| 1076 | } | ||
| 1077 | |||
| 1078 | static int __init kgdbdbgp_start_thread(void) | ||
| 1079 | { | ||
| 1080 | if (dbgp_kgdb_mode && kgdbdbgp_wait_time) | ||
| 1081 | kthread_run(kgdbdbgp_reader_thread, NULL, "%s", "dbgp"); | ||
| 1082 | |||
| 1083 | return 0; | ||
| 1084 | } | ||
| 1085 | module_init(kgdbdbgp_start_thread); | ||
| 1086 | #endif /* CONFIG_KGDB */ | ||
diff --git a/include/linux/kgdb.h b/include/linux/kgdb.h index 6c784ab6856a..9340f34d1bb5 100644 --- a/include/linux/kgdb.h +++ b/include/linux/kgdb.h | |||
| @@ -208,6 +208,17 @@ extern int kgdb_arch_set_breakpoint(unsigned long addr, char *saved_instr); | |||
| 208 | extern int kgdb_arch_remove_breakpoint(unsigned long addr, char *bundle); | 208 | extern int kgdb_arch_remove_breakpoint(unsigned long addr, char *bundle); |
| 209 | 209 | ||
| 210 | /** | 210 | /** |
| 211 | * kgdb_arch_late - Perform any architecture specific initalization. | ||
| 212 | * | ||
| 213 | * This function will handle the late initalization of any | ||
| 214 | * architecture specific callbacks. This is an optional function for | ||
| 215 | * handling things like late initialization of hw breakpoints. The | ||
| 216 | * default implementation does nothing. | ||
| 217 | */ | ||
| 218 | extern void kgdb_arch_late(void); | ||
| 219 | |||
| 220 | |||
| 221 | /** | ||
| 211 | * struct kgdb_arch - Describe architecture specific values. | 222 | * struct kgdb_arch - Describe architecture specific values. |
| 212 | * @gdb_bpt_instr: The instruction to trigger a breakpoint. | 223 | * @gdb_bpt_instr: The instruction to trigger a breakpoint. |
| 213 | * @flags: Flags for the breakpoint, currently just %KGDB_HW_BREAKPOINT. | 224 | * @flags: Flags for the breakpoint, currently just %KGDB_HW_BREAKPOINT. |
| @@ -285,7 +296,10 @@ extern int kgdb_single_step; | |||
| 285 | extern atomic_t kgdb_active; | 296 | extern atomic_t kgdb_active; |
| 286 | #define in_dbg_master() \ | 297 | #define in_dbg_master() \ |
| 287 | (raw_smp_processor_id() == atomic_read(&kgdb_active)) | 298 | (raw_smp_processor_id() == atomic_read(&kgdb_active)) |
| 299 | extern bool dbg_is_early; | ||
| 300 | extern void __init dbg_late_init(void); | ||
| 288 | #else /* ! CONFIG_KGDB */ | 301 | #else /* ! CONFIG_KGDB */ |
| 289 | #define in_dbg_master() (0) | 302 | #define in_dbg_master() (0) |
| 303 | #define dbg_late_init() | ||
| 290 | #endif /* ! CONFIG_KGDB */ | 304 | #endif /* ! CONFIG_KGDB */ |
| 291 | #endif /* _KGDB_H_ */ | 305 | #endif /* _KGDB_H_ */ |
diff --git a/init/main.c b/init/main.c index 372771333d98..22881b5e95e3 100644 --- a/init/main.c +++ b/init/main.c | |||
| @@ -62,7 +62,7 @@ | |||
| 62 | #include <linux/sched.h> | 62 | #include <linux/sched.h> |
| 63 | #include <linux/signal.h> | 63 | #include <linux/signal.h> |
| 64 | #include <linux/idr.h> | 64 | #include <linux/idr.h> |
| 65 | #include <linux/kdb.h> | 65 | #include <linux/kgdb.h> |
| 66 | #include <linux/ftrace.h> | 66 | #include <linux/ftrace.h> |
| 67 | #include <linux/async.h> | 67 | #include <linux/async.h> |
| 68 | #include <linux/kmemcheck.h> | 68 | #include <linux/kmemcheck.h> |
| @@ -676,7 +676,7 @@ asmlinkage void __init start_kernel(void) | |||
| 676 | buffer_init(); | 676 | buffer_init(); |
| 677 | key_init(); | 677 | key_init(); |
| 678 | security_init(); | 678 | security_init(); |
| 679 | kdb_init(KDB_INIT_FULL); | 679 | dbg_late_init(); |
| 680 | vfs_caches_init(totalram_pages); | 680 | vfs_caches_init(totalram_pages); |
| 681 | signals_init(); | 681 | signals_init(); |
| 682 | /* rootfs populating might need page-writeback */ | 682 | /* rootfs populating might need page-writeback */ |
diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c index 64b5588c9638..5cb7cd1de10c 100644 --- a/kernel/debug/debug_core.c +++ b/kernel/debug/debug_core.c | |||
| @@ -78,6 +78,8 @@ static DEFINE_SPINLOCK(kgdb_registration_lock); | |||
| 78 | static int kgdb_con_registered; | 78 | static int kgdb_con_registered; |
| 79 | /* determine if kgdb console output should be used */ | 79 | /* determine if kgdb console output should be used */ |
| 80 | static int kgdb_use_con; | 80 | static int kgdb_use_con; |
| 81 | /* Flag for alternate operations for early debugging */ | ||
| 82 | bool dbg_is_early = true; | ||
| 81 | /* Next cpu to become the master debug core */ | 83 | /* Next cpu to become the master debug core */ |
| 82 | int dbg_switch_cpu; | 84 | int dbg_switch_cpu; |
| 83 | 85 | ||
| @@ -777,11 +779,25 @@ static struct notifier_block kgdb_panic_event_nb = { | |||
| 777 | .priority = INT_MAX, | 779 | .priority = INT_MAX, |
| 778 | }; | 780 | }; |
| 779 | 781 | ||
| 782 | void __weak kgdb_arch_late(void) | ||
| 783 | { | ||
| 784 | } | ||
| 785 | |||
| 786 | void __init dbg_late_init(void) | ||
| 787 | { | ||
| 788 | dbg_is_early = false; | ||
| 789 | if (kgdb_io_module_registered) | ||
| 790 | kgdb_arch_late(); | ||
| 791 | kdb_init(KDB_INIT_FULL); | ||
| 792 | } | ||
| 793 | |||
| 780 | static void kgdb_register_callbacks(void) | 794 | static void kgdb_register_callbacks(void) |
| 781 | { | 795 | { |
| 782 | if (!kgdb_io_module_registered) { | 796 | if (!kgdb_io_module_registered) { |
| 783 | kgdb_io_module_registered = 1; | 797 | kgdb_io_module_registered = 1; |
| 784 | kgdb_arch_init(); | 798 | kgdb_arch_init(); |
| 799 | if (!dbg_is_early) | ||
| 800 | kgdb_arch_late(); | ||
| 785 | atomic_notifier_chain_register(&panic_notifier_list, | 801 | atomic_notifier_chain_register(&panic_notifier_list, |
| 786 | &kgdb_panic_event_nb); | 802 | &kgdb_panic_event_nb); |
| 787 | #ifdef CONFIG_MAGIC_SYSRQ | 803 | #ifdef CONFIG_MAGIC_SYSRQ |
