Sergei Shtylyov wrote:
Hm... yet the kernel I was booting was UP. The same happened with SMP kernel I've just tried. Now I'm confused. :-/

something was broken WRT handling of the h/w breask as being per-CPU resource but not seeing anything obvious...

The piece that clears DR7 is called _cpu_init(). It seems that we'll have to patch this to contain the state of the hw registers from KGDB. Part of this is due to the lazy way the kernel handles the breakpoints today. My thoughts are that other debuggers or tools besides kgdb should be able to make use of this so it should be done in a platform independent way and the initialization values should perhaps be globals, or that there should be a kernel space version of the registers. Doing this would be useful to in that you could check it on the task swap and set it on the jump from user to kernel space if you really wanted to have complete control.

An initial work around might be the attached patch. And of course you will want to make sure your cvs tree is up todate as this is against the 2.6.21 branch.

Jason.

---
 arch/i386/kernel/cpu/common.c |   14 ++++++++------
 arch/i386/kernel/kgdb.c       |   14 ++++++++++----
 include/asm-i386/cpu.h        |    2 ++
 3 files changed, 20 insertions(+), 10 deletions(-)

Index: linux-2.6.21-standard/arch/i386/kernel/cpu/common.c
===================================================================
--- linux-2.6.21-standard.orig/arch/i386/kernel/cpu/common.c
+++ linux-2.6.21-standard/arch/i386/kernel/cpu/common.c
@@ -721,6 +721,8 @@ void __cpuinit cpu_set_gdt(int cpu)
        set_kernel_fs();
 }
 
+unsigned long kernel_debugreg[8];
+
 /* Common CPU init for both boot and secondary CPUs */
 static void __cpuinit _cpu_init(int cpu, struct task_struct *curr)
 {
@@ -768,12 +770,12 @@ static void __cpuinit _cpu_init(int cpu,
        asm volatile ("mov %0, %%gs" : : "r" (0));
 
        /* Clear all 6 debug registers: */
-       set_debugreg(0, 0);
-       set_debugreg(0, 1);
-       set_debugreg(0, 2);
-       set_debugreg(0, 3);
-       set_debugreg(0, 6);
-       set_debugreg(0, 7);
+       set_debugreg(kernel_debugreg[0], 0);
+       set_debugreg(kernel_debugreg[1], 1);
+       set_debugreg(kernel_debugreg[2], 2);
+       set_debugreg(kernel_debugreg[3], 3);
+       set_debugreg(kernel_debugreg[6], 6);
+       set_debugreg(kernel_debugreg[7], 7);
 
        /*
         * Force FPU initialization:
Index: linux-2.6.21-standard/arch/i386/kernel/kgdb.c
===================================================================
--- linux-2.6.21-standard.orig/arch/i386/kernel/kgdb.c
+++ linux-2.6.21-standard/arch/i386/kernel/kgdb.c
@@ -43,6 +43,7 @@
 #include <asm/apicdef.h>
 #include <asm/desc.h>
 #include <asm/kdebug.h>
+#include <asm/cpu.h>
 
 #include "mach_ipi.h"
 
@@ -129,6 +130,11 @@ static struct hw_breakpoint {
        { .enabled = 0 },
 };
 
+#define kgdb_set_debugreg(val, num) { \
+               kernel_debugreg[num] = val; \
+               set_debugreg(val, num); \
+}
+
 static void kgdb_correct_hw_break(void)
 {
        int breakno;
@@ -148,19 +154,19 @@ static void kgdb_correct_hw_break(void)
                               ((breakno << 2) + 16);
                        switch (breakno) {
                        case 0:
-                               set_debugreg(breakinfo[0].addr, 0);
+                               kgdb_set_debugreg(breakinfo[0].addr, 0);
                                break;
 
                        case 1:
-                               set_debugreg(breakinfo[1].addr, 1);
+                               kgdb_set_debugreg(breakinfo[1].addr, 1);
                                break;
 
                        case 2:
-                               set_debugreg(breakinfo[2].addr, 2);
+                               kgdb_set_debugreg(breakinfo[2].addr, 2);
                                break;
 
                        case 3:
-                               set_debugreg(breakinfo[3].addr, 3);
+                               kgdb_set_debugreg(breakinfo[3].addr, 3);
                                break;
                        }
                } else if ((dr7 & breakbit) && !breakinfo[breakno].enabled) {
Index: linux-2.6.21-standard/include/asm-i386/cpu.h
===================================================================
--- linux-2.6.21-standard.orig/include/asm-i386/cpu.h
+++ linux-2.6.21-standard/include/asm-i386/cpu.h
@@ -18,5 +18,7 @@ extern int enable_cpu_hotplug;
 #define enable_cpu_hotplug     0
 #endif
 
+extern unsigned long *kernel_debugreg;
+
 DECLARE_PER_CPU(int, cpu_state);
 #endif /* _ASM_I386_CPU_H_ */
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/
_______________________________________________
Kgdb-bugreport mailing list
Kgdb-bugreport@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kgdb-bugreport

Reply via email to