diff options
author | K.Prasad <prasad@linux.vnet.ibm.com> | 2009-06-01 14:17:06 -0400 |
---|---|---|
committer | Frederic Weisbecker <fweisbec@gmail.com> | 2009-06-02 16:47:00 -0400 |
commit | 62edab9056a6cf0c9207339c8892c923a5217e45 (patch) | |
tree | 2becd775fdc2a25df3daacf69d80685b251fbed9 /arch/x86/kernel/hw_breakpoint.c | |
parent | 0722db015c246204044299eae3b02d18d3ca4faf (diff) |
hw-breakpoints: reset bits in dr6 after the corresponding exception is handled
This patch resets the bit in dr6 after the corresponding exception is
handled in code, so that we keep a clean track of the current virtual debug
status register.
[ Impact: keep track of breakpoints triggering completion ]
Signed-off-by: K.Prasad <prasad@linux.vnet.ibm.com>
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Diffstat (limited to 'arch/x86/kernel/hw_breakpoint.c')
-rw-r--r-- | arch/x86/kernel/hw_breakpoint.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/arch/x86/kernel/hw_breakpoint.c b/arch/x86/kernel/hw_breakpoint.c index 4867c9f3b5fb..69451473dbd2 100644 --- a/arch/x86/kernel/hw_breakpoint.c +++ b/arch/x86/kernel/hw_breakpoint.c | |||
@@ -314,8 +314,12 @@ int __kprobes hw_breakpoint_handler(struct die_args *args) | |||
314 | { | 314 | { |
315 | int i, cpu, rc = NOTIFY_STOP; | 315 | int i, cpu, rc = NOTIFY_STOP; |
316 | struct hw_breakpoint *bp; | 316 | struct hw_breakpoint *bp; |
317 | /* The DR6 value is stored in args->err */ | 317 | unsigned long dr7, dr6; |
318 | unsigned long dr7, dr6 = args->err; | 318 | unsigned long *dr6_p; |
319 | |||
320 | /* The DR6 value is pointed by args->err */ | ||
321 | dr6_p = (unsigned long *)ERR_PTR(args->err); | ||
322 | dr6 = *dr6_p; | ||
319 | 323 | ||
320 | /* Do an early return if no trap bits are set in DR6 */ | 324 | /* Do an early return if no trap bits are set in DR6 */ |
321 | if ((dr6 & DR_TRAP_BITS) == 0) | 325 | if ((dr6 & DR_TRAP_BITS) == 0) |
@@ -352,6 +356,11 @@ int __kprobes hw_breakpoint_handler(struct die_args *args) | |||
352 | rc = NOTIFY_DONE; | 356 | rc = NOTIFY_DONE; |
353 | } | 357 | } |
354 | /* | 358 | /* |
359 | * Reset the 'i'th TRAP bit in dr6 to denote completion of | ||
360 | * exception handling | ||
361 | */ | ||
362 | (*dr6_p) &= ~(DR_TRAP0 << i); | ||
363 | /* | ||
355 | * bp can be NULL due to lazy debug register switching | 364 | * bp can be NULL due to lazy debug register switching |
356 | * or due to the delay between updates of hbp_kernel_pos | 365 | * or due to the delay between updates of hbp_kernel_pos |
357 | * and this_hbp_kernel. | 366 | * and this_hbp_kernel. |