diff options
Diffstat (limited to 'arch/x86/kernel/kgdb.c')
-rw-r--r-- | arch/x86/kernel/kgdb.c | 56 |
1 files changed, 26 insertions, 30 deletions
diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c index b2258ca91003..95b89d4cb8f1 100644 --- a/arch/x86/kernel/kgdb.c +++ b/arch/x86/kernel/kgdb.c | |||
@@ -47,20 +47,8 @@ | |||
47 | #include <asm/debugreg.h> | 47 | #include <asm/debugreg.h> |
48 | #include <asm/apicdef.h> | 48 | #include <asm/apicdef.h> |
49 | #include <asm/system.h> | 49 | #include <asm/system.h> |
50 | |||
51 | #include <asm/apic.h> | 50 | #include <asm/apic.h> |
52 | 51 | ||
53 | /* | ||
54 | * Put the error code here just in case the user cares: | ||
55 | */ | ||
56 | static int gdb_x86errcode; | ||
57 | |||
58 | /* | ||
59 | * Likewise, the vector number here (since GDB only gets the signal | ||
60 | * number through the usual means, and that's not very specific): | ||
61 | */ | ||
62 | static int gdb_x86vector = -1; | ||
63 | |||
64 | /** | 52 | /** |
65 | * pt_regs_to_gdb_regs - Convert ptrace regs to GDB regs | 53 | * pt_regs_to_gdb_regs - Convert ptrace regs to GDB regs |
66 | * @gdb_regs: A pointer to hold the registers in the order GDB wants. | 54 | * @gdb_regs: A pointer to hold the registers in the order GDB wants. |
@@ -399,23 +387,6 @@ void kgdb_disable_hw_debug(struct pt_regs *regs) | |||
399 | } | 387 | } |
400 | } | 388 | } |
401 | 389 | ||
402 | /** | ||
403 | * kgdb_post_primary_code - Save error vector/code numbers. | ||
404 | * @regs: Original pt_regs. | ||
405 | * @e_vector: Original error vector. | ||
406 | * @err_code: Original error code. | ||
407 | * | ||
408 | * This is needed on architectures which support SMP and KGDB. | ||
409 | * This function is called after all the slave cpus have been put | ||
410 | * to a know spin state and the primary CPU has control over KGDB. | ||
411 | */ | ||
412 | void kgdb_post_primary_code(struct pt_regs *regs, int e_vector, int err_code) | ||
413 | { | ||
414 | /* primary processor is completely in the debugger */ | ||
415 | gdb_x86vector = e_vector; | ||
416 | gdb_x86errcode = err_code; | ||
417 | } | ||
418 | |||
419 | #ifdef CONFIG_SMP | 390 | #ifdef CONFIG_SMP |
420 | /** | 391 | /** |
421 | * kgdb_roundup_cpus - Get other CPUs into a holding pattern | 392 | * kgdb_roundup_cpus - Get other CPUs into a holding pattern |
@@ -567,7 +538,7 @@ static int __kgdb_notify(struct die_args *args, unsigned long cmd) | |||
567 | return NOTIFY_DONE; | 538 | return NOTIFY_DONE; |
568 | } | 539 | } |
569 | 540 | ||
570 | if (kgdb_handle_exception(args->trapnr, args->signr, args->err, regs)) | 541 | if (kgdb_handle_exception(args->trapnr, args->signr, cmd, regs)) |
571 | return NOTIFY_DONE; | 542 | return NOTIFY_DONE; |
572 | 543 | ||
573 | /* Must touch watchdog before return to normal operation */ | 544 | /* Must touch watchdog before return to normal operation */ |
@@ -575,6 +546,26 @@ static int __kgdb_notify(struct die_args *args, unsigned long cmd) | |||
575 | return NOTIFY_STOP; | 546 | return NOTIFY_STOP; |
576 | } | 547 | } |
577 | 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 | |||
578 | static int | 569 | static int |
579 | kgdb_notify(struct notifier_block *self, unsigned long cmd, void *ptr) | 570 | kgdb_notify(struct notifier_block *self, unsigned long cmd, void *ptr) |
580 | { | 571 | { |
@@ -690,6 +681,11 @@ unsigned long kgdb_arch_pc(int exception, struct pt_regs *regs) | |||
690 | return instruction_pointer(regs); | 681 | return instruction_pointer(regs); |
691 | } | 682 | } |
692 | 683 | ||
684 | void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long ip) | ||
685 | { | ||
686 | regs->ip = ip; | ||
687 | } | ||
688 | |||
693 | struct kgdb_arch arch_kgdb_ops = { | 689 | struct kgdb_arch arch_kgdb_ops = { |
694 | /* Breakpoint instruction: */ | 690 | /* Breakpoint instruction: */ |
695 | .gdb_bpt_instr = { 0xcc }, | 691 | .gdb_bpt_instr = { 0xcc }, |