If there are no objections, I'd like to apply this patch as it fixes a 
critical gap when using source stepping that calls a low level 
singlestep that steps the boundary from the kernel to the user space.  
It is particularly bad when this corner case kills "init" as you get an 
unexpected reboot.

---

This patch is to fix another corner case where kgdb can pass a single
step trap to user space which was intended for the kernel.  Now a
source level "next" which single steps over an iret instruction will
cause KGDB to continue and print an error to the console, vs the
unpredictable consequence of sending a trap to unsuspecting code in
the user space (normally resulting in process termination).

Signed-off-by: Jason Wessel <[EMAIL PROTECTED]>

---
 arch/i386/kernel/kgdb.c   |   31 +++++++++++++++++++------------
 arch/x86_64/kernel/kgdb.c |   17 ++++++++++++-----
 2 files changed, 31 insertions(+), 17 deletions(-)

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
@@ -222,7 +222,7 @@ int kgdb_arch_handle_exception(int e_vec
         if (remcom_in_buffer[0] == 's') {
             linux_regs->eflags |= TF_MASK;
             debugger_step = 1;
-            atomic_set(&cpu_doing_single_step,smp_processor_id());
+            atomic_set(&cpu_doing_single_step,raw_smp_processor_id());
         }
 
         asm volatile ("movl %%db6, %0\n":"=r" (dr6));
@@ -255,22 +255,29 @@ static int kgdb_notify(struct notifier_b
 
     /* Bad memory access? */
     if (cmd == DIE_PAGE_FAULT_NO_CONTEXT && atomic_read(&debugger_active)
-            && kgdb_may_fault) {
+        && kgdb_may_fault) {
         kgdb_fault_longjmp(kgdb_fault_jmp_regs);
         return NOTIFY_STOP;
     } else if (cmd == DIE_PAGE_FAULT)
         /* A normal page fault, ignore. */
         return NOTIFY_DONE;
-       else if ((cmd == DIE_NMI || cmd == DIE_NMI_IPI ||
-               cmd == DIE_NMIWATCHDOG) && atomic_read(&debugger_active)) {
-               /* CPU roundup */
-               kgdb_nmihook(smp_processor_id(), regs);
-               return NOTIFY_STOP;
-       } else if (cmd == DIE_NMI_IPI || cmd == DIE_NMI || 
user_mode(regs) ||
-                       (cmd == DIE_DEBUG && atomic_read(&debugger_active)))
-               /* Normal watchdog event or userspace debugging, or spurious
-                * debug exception, ignore. */
-               return NOTIFY_DONE;
+    else if ((cmd == DIE_NMI || cmd == DIE_NMI_IPI ||
+              cmd == DIE_NMIWATCHDOG) && atomic_read(&debugger_active)) {
+        /* CPU roundup */
+        kgdb_nmihook(raw_smp_processor_id(), regs);
+        return NOTIFY_STOP;
+    } else if (cmd == DIE_DEBUG && atomic_read(&cpu_doing_single_step) 
!= -1
+             && user_mode(regs)) {
+        /* single step exception from kernel space to user space so
+         * eat the exception and continue the process
+         */
+        printk(KERN_ERR "KGDB: trap/step from kernel to user space, 
resuming...\n");
+        return NOTIFY_STOP;
+    } else if (cmd == DIE_NMI_IPI || cmd == DIE_NMI || user_mode(regs) ||
+               (cmd == DIE_DEBUG && atomic_read(&debugger_active)))
+        /* Normal watchdog event or userspace debugging, or spurious
+         * debug exception, ignore. */
+        return NOTIFY_DONE;
 
     kgdb_handle_exception(args->trapnr, args->signr, args->err, regs);
 
Index: linux-2.6.21-standard/arch/x86_64/kernel/kgdb.c
===================================================================
--- linux-2.6.21-standard.orig/arch/x86_64/kernel/kgdb.c
+++ linux-2.6.21-standard/arch/x86_64/kernel/kgdb.c
@@ -183,7 +183,7 @@ int kgdb_arch_handle_exception(int e_vec
             debugger_step = 1;
             if (kgdb_contthread)
                 atomic_set(&cpu_doing_single_step,
-                       smp_processor_id());
+                       raw_smp_processor_id());
 
         }
 
@@ -237,7 +237,7 @@ void kgdb_shadowinfo(struct pt_regs *reg
     static char intr_desc[] = "Stack at interrupt entrypoint";
     static char exc_desc[] = "Stack at exception entrypoint";
     struct pt_regs *stregs;
-    int cpu = smp_processor_id();
+    int cpu = raw_smp_processor_id();
 
     if ((stregs = in_interrupt_stack(regs->rsp, cpu)))
         kgdb_mem2hex(intr_desc, buffer, strlen(intr_desc));
@@ -248,7 +248,7 @@ void kgdb_shadowinfo(struct pt_regs *reg
 struct task_struct *kgdb_get_shadow_thread(struct pt_regs *regs, int 
threadid)
 {
     struct pt_regs *stregs;
-    int cpu = smp_processor_id();
+    int cpu = raw_smp_processor_id();
 
     if ((stregs = in_interrupt_stack(regs->rsp, cpu)))
         return current;
@@ -261,7 +261,7 @@ struct task_struct *kgdb_get_shadow_thre
 struct pt_regs *kgdb_shadow_regs(struct pt_regs *regs, int threadid)
 {
     struct pt_regs *stregs;
-    int cpu = smp_processor_id();
+    int cpu = raw_smp_processor_id();
 
     if ((stregs = in_interrupt_stack(regs->rsp, cpu)))
         return stregs;
@@ -285,9 +285,16 @@ static int kgdb_notify(struct notifier_b
         return NOTIFY_STOP;
     /* CPU roundup? */
     } else if (atomic_read(&debugger_active) && cmd == DIE_NMI_IPI) {
-        kgdb_nmihook(smp_processor_id(), regs);
+        kgdb_nmihook(raw_smp_processor_id(), regs);
         return NOTIFY_STOP;
         /* See if KGDB is interested. */
+    } else if (cmd == DIE_DEBUG && atomic_read(&cpu_doing_single_step) 
!= -1
+             && user_mode(regs)) {
+        /* single step exception from kernel space to user space so
+         * eat the exception and continue the process
+         */
+        printk(KERN_ERR "KGDB: trap/step from kernel to user space, 
resuming...\n");
+        return NOTIFY_STOP;
     } else if (cmd == DIE_PAGE_FAULT || user_mode(regs) ||
            cmd == DIE_NMI_IPI || (cmd == DIE_DEBUG &&
                       atomic_read(&debugger_active)))

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Kgdb-bugreport mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/kgdb-bugreport

Reply via email to