Hi Andrei,

Thanks for these patches. Your point about the need for a general cleanup of 
current thread info pointer fetch is exellent. We definitely need to add some 
ifdefs around stack size.

I would also like to add more code to kernel entry points to save thread info 
pointer. It would be too intrusive though, since with such a code in place, 
acceptance into mainline kernel becomes difficult. We could add it to a 
non-lite patch.

Suggestions?
-Amit


On Wednesday 05 July 2006 21:58, Andrei Konovalov wrote:
> 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


-------------------------------------------------------------------------
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