diff options
author | Jason Wessel <jason.wessel@windriver.com> | 2010-11-15 08:07:35 -0600 |
---|---|---|
committer | Jason Wessel <jason.wessel@windriver.com> | 2010-11-17 13:54:57 -0600 |
commit | 10a6e67648d4b47769953bd24759ba9609bf00df (patch) | |
tree | 87a7381db182f858bda6b275c421ee01f674b5de /arch | |
parent | 5450d904054b4ed582793ad6ecb5469f03cc4c46 (diff) | |
download | lwn-10a6e67648d4b47769953bd24759ba9609bf00df.tar.gz lwn-10a6e67648d4b47769953bd24759ba9609bf00df.zip |
kgdb,x86: fix regression in detach handling
The fix from ba773f7c510c0b252145933926c636c439889207
(x86,kgdb: Fix hw breakpoint regression) was not entirely complete.
The kgdb_remove_all_hw_break() function also needs to call the
hw_break_release_slot() or else a breakpoint can get activated again
after the debugger has detached.
The kgdb test suite exposes the behavior in the form of either a hang
or repetitive failure. The kernel config that exposes the problem
contains all of the following:
CONFIG_DEBUG_RODATA=y
CONFIG_KGDB_TESTS=y
CONFIG_KGDB_TESTS_ON_BOOT=y
CONFIG_KGDB_TESTS_BOOT_STRING="V1F100"
Reported-by: Frederic Weisbecker <fweisbec@gmail.com>
Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
Tested-by: Frederic Weisbecker <fweisbec@gmail.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/kernel/kgdb.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c index ec592caac4b4..cd21b654dec6 100644 --- a/arch/x86/kernel/kgdb.c +++ b/arch/x86/kernel/kgdb.c @@ -315,14 +315,18 @@ static void kgdb_remove_all_hw_break(void) if (!breakinfo[i].enabled) continue; bp = *per_cpu_ptr(breakinfo[i].pev, cpu); - if (bp->attr.disabled == 1) + if (!bp->attr.disabled) { + arch_uninstall_hw_breakpoint(bp); + bp->attr.disabled = 1; continue; + } if (dbg_is_early) early_dr7 &= ~encode_dr7(i, breakinfo[i].len, breakinfo[i].type); - else - arch_uninstall_hw_breakpoint(bp); - bp->attr.disabled = 1; + else if (hw_break_release_slot(i)) + printk(KERN_ERR "KGDB: hw bpt remove failed %lx\n", + breakinfo[i].addr); + breakinfo[i].enabled = 0; } } |