[haiku-commits] r35951 - in haiku/trunk: headers/private/kernel/arch/x86 src/system/kernel/arch/x86

Author: bonefish
Date: 2010-03-26 01:03:53 +0100 (Fri, 26 Mar 2010)
New Revision: 35951
Changeset: http://dev.haiku-os.org/changeset/35951/haiku

Modified:
   haiku/trunk/headers/private/kernel/arch/x86/arch_cpu.h
   haiku/trunk/src/system/kernel/arch/x86/arch_user_debugger.cpp
Log:
x86:
Added fields for temporary storage of the debug registers dr6 and dr7 to the
arch_cpu_info structure. The actual registers are stored at the beginning of
x86_exit_user_debug_at_kernel_entry() and read in
x86_handle_debug_exception().
The problem was that x86_exit_user_debug_at_kernel_entry() itself overwrote
dr7 and, if kernel breakpoints were enabled, dr6 could be overwritten anytime
after. So x86_handle_debug_exception() would find incorrect values in the
registers (definitely in dr7) and thus interpret the detected debug condition
incorrectly. Usually watchpoints were recognized as breakpoints.


Modified: haiku/trunk/headers/private/kernel/arch/x86/arch_cpu.h
===================================================================
--- haiku/trunk/headers/private/kernel/arch/x86/arch_cpu.h      2010-03-25 
21:08:05 UTC (rev 35950)
+++ haiku/trunk/headers/private/kernel/arch/x86/arch_cpu.h      2010-03-26 
00:03:53 UTC (rev 35951)
@@ -250,6 +250,9 @@
 
        struct vm_translation_map_arch_info* active_translation_map;
 
+       uint32                          dr6;    // temporary storage for debug 
registers (cf.
+       uint32                          dr7;    // 
x86_exit_user_debug_at_kernel_entry())
+
        // local TSS for this cpu
        struct tss                      tss;
        struct tss                      double_fault_tss;

Modified: haiku/trunk/src/system/kernel/arch/x86/arch_user_debugger.cpp
===================================================================
--- haiku/trunk/src/system/kernel/arch/x86/arch_user_debugger.cpp       
2010-03-25 21:08:05 UTC (rev 35950)
+++ haiku/trunk/src/system/kernel/arch/x86/arch_user_debugger.cpp       
2010-03-26 00:03:53 UTC (rev 35951)
@@ -806,6 +806,12 @@
        if (!(thread->flags & THREAD_FLAGS_BREAKPOINTS_INSTALLED))
                return;
 
+       // We need to save the current values of dr6 and dr7 in the CPU 
structure,
+       // since in case of a debug exception we might overwrite them before
+       // x86_handle_debug_exception() is called.
+       asm("movl %%dr6, %0" : "=r"(thread->cpu->arch.dr6));
+       asm("movl %%dr7, %0" : "=r"(thread->cpu->arch.dr7));
+
        GRAB_THREAD_LOCK();
 
        // disable user breakpoints
@@ -829,10 +835,11 @@
 void
 x86_handle_debug_exception(struct iframe *frame)
 {
-       // get debug status and control registers
-       uint32 dr6, dr7;
-       asm("movl %%dr6, %0" : "=r"(dr6));
-       asm("movl %%dr7, %0" : "=r"(dr7));
+       // get debug status and control registers (saved earlier in
+       // x86_exit_user_debug_at_kernel_entry())
+       struct thread* thread = thread_get_current_thread();
+       uint32 dr6 = thread->cpu->arch.dr6;
+       uint32 dr7 = thread->cpu->arch.dr7;
 
        TRACE(("i386_handle_debug_exception(): DR6: %lx, DR7: %lx\n", dr6, 
dr7));
 
@@ -889,7 +896,6 @@
                        // Determine whether the exception occurred at a 
syscall/trap
                        // kernel entry or whether this is genuine kernel 
single-stepping.
                        bool inKernel = true;
-                       struct thread* thread = thread_get_current_thread();
                        if (thread->team != team_get_kernel_team()
                                && i386_get_user_iframe() == NULL) {
                                // TODO: This is not yet fully correct, since a 
newly created


Other related posts:

  • » [haiku-commits] r35951 - in haiku/trunk: headers/private/kernel/arch/x86 src/system/kernel/arch/x86 - ingo_weinhold