Hello,

Here:

+       /*
+        * On Book E and perhaps other processsors, singlestep is handled on
+        * the critical exception stack.  This causes current_thread_info()
+        * to fail, since it it locates the thread_info by masking off
+        * the low bits of the current stack pointer.  We work around
+        * this issue by copying the thread_info from the kernel stack
+        * before calling kgdb_handle_exception, and copying it back
+        * afterwards.  On most processors the copy is avoided since
+        * exception_thread_info == thread_info.
+        */
+       thread_info = (struct thread_info *)(regs->gpr[1] & ~(THREAD_SIZE-1));
+       exception_thread_info = current_thread_info();

- calling current_thread_info() is incorrect, as it assumes 8K stack, but for 
Book E
and ppc4xx the critical exception stack is 4K and is 4K-aligned
(see head_4xx.S, head_44x.S and head_fsl_booke.S in arch/ppc/kernel/).
So depending on the actual kernel layout/configuration exception_thread_info
could point 4K below the critical exception stack. Even if
(exception_stack_bottom & ~(THREAD_SIZE-1)) != 0 (i.e. the stack is NOT 8K 
aligned)
everything seems to work OK in most cases (the overwritten data are not so 
critical?).
But we did encountered one case when trying to single step from the default 
breakpoint
made the kernel to hang.

There are several possible ways to fix that:

- make the critical exception stack to be 8K aligned:

=====================================================================================
diff -upr a/arch/ppc/kernel/head_4xx.S b/arch/ppc/kernel/head_4xx.S
--- a/arch/ppc/kernel/head_4xx.S        2006-07-05 20:23:51.000000000 +0400
+++ b/arch/ppc/kernel/head_4xx.S        2006-07-05 19:54:51.000000000 +0400
@@ -1001,7 +1001,7 @@ swapper_pg_dir:

  /* Stack for handling critical exceptions from kernel mode */
         .section .bss
-        .align 12
+        .align 13
  exception_stack_bottom:
         .space  4096
  critical_stack_top:
=====================================================================================

- replace call to current_thread_info() with:

=====================================================================================
diff -upr a/arch/ppc/kernel/kgdb.c b/arch/ppc/kernel/kgdb.c
--- a/arch/ppc/kernel/kgdb.c    2006-07-05 19:53:29.000000000 +0400
+++ b/arch/ppc/kernel/kgdb.c    2006-07-05 20:18:06.000000000 +0400
@@ -106,29 +106,32 @@ static int kgdb_breakpoint(struct pt_reg
  static int kgdb_singlestep(struct pt_regs *regs)
  {
         struct thread_info *thread_info, *exception_thread_info;
+       register unsigned long sp asm("r1");

         if (user_mode(regs))
                 return 0;
+
+#if defined(CONFIG_40x) || defined(CONFIG_44x) || defined(CONFIG_E500)
         /*
-       * On Book E and perhaps other processsors, singlestep is handled on
+       * On Book E, ppc40x, and ppc44x, singlestep is handled on
         * the critical exception stack.  This causes current_thread_info()
-       * to fail, since it it locates the thread_info by masking off
+       * to fail, since it locates the thread_info by masking off
         * the low bits of the current stack pointer.  We work around
         * this issue by copying the thread_info from the kernel stack
         * before calling kgdb_handle_exception, and copying it back
-       * afterwards.  On most processors the copy is avoided since
-       * exception_thread_info == thread_info.
+       * afterwards.
         */
+#define CRIT_STACK_SIZE        0x1000  /* 4kB */
         thread_info = (struct thread_info *)(regs->gpr[1] & ~(THREAD_SIZE-1));
-       exception_thread_info = current_thread_info();
-
-       if (thread_info != exception_thread_info)
-               memcpy(exception_thread_info, thread_info, sizeof *thread_info);
+       exception_thread_info = (struct thread_info *)(sp & 
~(CRIT_STACK_SIZE-1));
+       memcpy(exception_thread_info, thread_info, sizeof *thread_info);

         kgdb_handle_exception(0, SIGTRAP, 0, regs);

-       if (thread_info != exception_thread_info)
-               memcpy(thread_info, exception_thread_info, sizeof *thread_info);
+       memcpy(thread_info, exception_thread_info, sizeof *thread_info);
+#else
+       kgdb_handle_exception(0, SIGTRAP, 0, regs);
+#endif

         return 1;
  }
=====================================================================================

   or

=====================================================================================
diff -upr a/arch/ppc/kernel/kgdb.c c/arch/ppc/kernel/kgdb.c
--- a/arch/ppc/kernel/kgdb.c    2006-07-05 19:53:29.000000000 +0400
+++ c/arch/ppc/kernel/kgdb.c    2006-07-05 20:17:51.000000000 +0400
@@ -110,9 +110,9 @@ static int kgdb_singlestep(struct pt_reg
         if (user_mode(regs))
                 return 0;
         /*
-       * On Book E and perhaps other processsors, singlestep is handled on
+       * On Book E and perhaps other processors, singlestep is handled on
         * the critical exception stack.  This causes current_thread_info()
-       * to fail, since it it locates the thread_info by masking off
+       * to fail, since it locates the thread_info by masking off
         * the low bits of the current stack pointer.  We work around
         * this issue by copying the thread_info from the kernel stack
         * before calling kgdb_handle_exception, and copying it back
@@ -122,8 +122,14 @@ static int kgdb_singlestep(struct pt_reg
         thread_info = (struct thread_info *)(regs->gpr[1] & ~(THREAD_SIZE-1));
         exception_thread_info = current_thread_info();

-       if (thread_info != exception_thread_info)
+       if (thread_info != exception_thread_info) {
+               #define CRIT_STACK_SIZE 0x1000
+               register unsigned long sp asm("r1");
+
+               exception_thread_info =
+                       (struct thread_info *)(sp & ~(CRIT_STACK_SIZE-1));
                 memcpy(exception_thread_info, thread_info, sizeof 
*thread_info);
+       }

         kgdb_handle_exception(0, SIGTRAP, 0, regs);

=====================================================================================

To say the true, I don't like all the three (these are just to illustrate the 
idea).
Seems some general cleanup in handling the stack size would make sense.

Suggestions?


Thanks,
Andrei


Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Kgdb-bugreport mailing list
Kgdb-bugreport@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kgdb-bugreport

Reply via email to