diff options
author | Jason Wessel <jason.wessel@windriver.com> | 2010-05-20 22:04:29 -0400 |
---|---|---|
committer | Jason Wessel <jason.wessel@windriver.com> | 2010-05-20 22:04:29 -0400 |
commit | 0b4b3827db386ec6034a5aba1261025b039440c2 (patch) | |
tree | a3469de6930fe3e850c8e4c49c26a2a3b53612dd /arch/x86/kernel | |
parent | 29c843912a0baa7fa63033fe28e1ca7e796686a5 (diff) |
x86, kgdb, init: Add early and late debug states
The kernel debugger can operate well before mm_init(), but the x86
hardware breakpoint code which uses the perf api requires that the
kernel allocators are initialized.
This means the kernel debug core needs to provide an optional arch
specific call back to allow the initialization functions to run after
the kernel has been further initialized.
The kdb shell already had a similar restriction with an early
initialization and late initialization. The kdb_init() was moved into
the debug core's version of the late init which is called
dbg_late_init();
CC: kgdb-bugreport@lists.sourceforge.net
Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r-- | arch/x86/kernel/kgdb.c | 17 |
1 files changed, 10 insertions, 7 deletions
diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c index 95b89d4cb8f1..2b71ec41869f 100644 --- a/arch/x86/kernel/kgdb.c +++ b/arch/x86/kernel/kgdb.c | |||
@@ -596,14 +596,15 @@ static struct notifier_block kgdb_notifier = { | |||
596 | */ | 596 | */ |
597 | int kgdb_arch_init(void) | 597 | int kgdb_arch_init(void) |
598 | { | 598 | { |
599 | return register_die_notifier(&kgdb_notifier); | ||
600 | } | ||
601 | |||
602 | void kgdb_arch_late(void) | ||
603 | { | ||
599 | int i, cpu; | 604 | int i, cpu; |
600 | int ret; | ||
601 | struct perf_event_attr attr; | 605 | struct perf_event_attr attr; |
602 | struct perf_event **pevent; | 606 | struct perf_event **pevent; |
603 | 607 | ||
604 | ret = register_die_notifier(&kgdb_notifier); | ||
605 | if (ret != 0) | ||
606 | return ret; | ||
607 | /* | 608 | /* |
608 | * Pre-allocate the hw breakpoint structions in the non-atomic | 609 | * Pre-allocate the hw breakpoint structions in the non-atomic |
609 | * portion of kgdb because this operation requires mutexs to | 610 | * portion of kgdb because this operation requires mutexs to |
@@ -615,12 +616,15 @@ int kgdb_arch_init(void) | |||
615 | attr.bp_type = HW_BREAKPOINT_W; | 616 | attr.bp_type = HW_BREAKPOINT_W; |
616 | attr.disabled = 1; | 617 | attr.disabled = 1; |
617 | for (i = 0; i < 4; i++) { | 618 | for (i = 0; i < 4; i++) { |
619 | if (breakinfo[i].pev) | ||
620 | continue; | ||
618 | breakinfo[i].pev = register_wide_hw_breakpoint(&attr, NULL); | 621 | breakinfo[i].pev = register_wide_hw_breakpoint(&attr, NULL); |
619 | if (IS_ERR(breakinfo[i].pev)) { | 622 | if (IS_ERR(breakinfo[i].pev)) { |
620 | printk(KERN_ERR "kgdb: Could not allocate hw breakpoints\n"); | 623 | printk(KERN_ERR "kgdb: Could not allocate hw" |
624 | "breakpoints\nDisabling the kernel debugger\n"); | ||
621 | breakinfo[i].pev = NULL; | 625 | breakinfo[i].pev = NULL; |
622 | kgdb_arch_exit(); | 626 | kgdb_arch_exit(); |
623 | return -1; | 627 | return; |
624 | } | 628 | } |
625 | for_each_online_cpu(cpu) { | 629 | for_each_online_cpu(cpu) { |
626 | pevent = per_cpu_ptr(breakinfo[i].pev, cpu); | 630 | pevent = per_cpu_ptr(breakinfo[i].pev, cpu); |
@@ -631,7 +635,6 @@ int kgdb_arch_init(void) | |||
631 | } | 635 | } |
632 | } | 636 | } |
633 | } | 637 | } |
634 | return ret; | ||
635 | } | 638 | } |
636 | 639 | ||
637 | /** | 640 | /** |