aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64
diff options
context:
space:
mode:
authorJohn Blackwood <john.blackwood@ccur.com>2006-01-11 16:44:15 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-11 22:04:54 -0500
commit01b8faaef5d239aeabb1e712c5d9619f29e808dd (patch)
tree5f04e7d96c14d4d6c7280abcb2048907079ccbb9 /arch/x86_64
parent4839057cafc9a508ad5906857e9c1d8707c875e3 (diff)
[PATCH] x86_64: Report hardware breakpoints in user space when triggered by the kernel
I would like to throw out a suggestion for a possible change in the way that the debug register traps are handled in do_debug() when the trap occurs in kernel-mode. In the x86_64 version of do_debug(), the code will skip around sending a SIGTRAP to the current task if the trap occurred while in kernel mode. On the i386-side of things, if the access happens to occur in kernel mode (say during a read(2) of user's buffer that matches the address of a debug register trap), then the do_debug() routine for i386 will go ahead and call send_sigtrap() and send the SIGTRAP signal. The send_sigtrap() code will also set the info.si_addr to NULL in this case (even though I don't understand why, since the SIGTRAP siginfo processing doesn't use the si_addr field...). So I would like to suggest that the x86_64 do_debug() routine also follow this type of behavior and have it go ahead and send the SIGTRAP signal to the current task, even if the debug register trap happens to have occurred in kernel mode. I have taken a stab at a patch for this change below. (It includes the i386-ish change for setting si_addr to NULL when the trap occurred in kernel mode.) It seems like a useful feature to be able to 'watch' a user location that might also be modified in the kernel via a system service call, and have the debugger report that information back to the user, rather than to just silently ignore the trap. Additionally, I realize that users that pull in a kernel debugger such as KGDB into their kernel might want to remove this change below when they add in KGDB support. However, they could alternatively look at the current task's thread.debugreg[] values to see if the trap occurred due to KGDB or instead because of a user-space debugger trap, and still honor the user SIGTRAP processing (instead of the KGDB breakpoint processing) if the trap matches up with the thread.debugreg[] registers. Signed-off-by: Andi Kleen <ak@suse.de> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/x86_64')
-rw-r--r--arch/x86_64/kernel/traps.c6
1 files changed, 2 insertions, 4 deletions
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c
index 1a9094dab682..8d21d87b0d77 100644
--- a/arch/x86_64/kernel/traps.c
+++ b/arch/x86_64/kernel/traps.c
@@ -726,11 +726,9 @@ asmlinkage void __kprobes do_debug(struct pt_regs * regs,
726 info.si_signo = SIGTRAP; 726 info.si_signo = SIGTRAP;
727 info.si_errno = 0; 727 info.si_errno = 0;
728 info.si_code = TRAP_BRKPT; 728 info.si_code = TRAP_BRKPT;
729 if (!user_mode(regs)) 729 info.si_addr = user_mode(regs) ? (void __user *)regs->rip : NULL;
730 goto clear_dr7; 730 force_sig_info(SIGTRAP, &info, tsk);
731 731
732 info.si_addr = (void __user *)regs->rip;
733 force_sig_info(SIGTRAP, &info, tsk);
734clear_dr7: 732clear_dr7:
735 set_debugreg(0UL, 7); 733 set_debugreg(0UL, 7);
736 return; 734 return;