On 05/10/2012 11:50 AM, Benjamin Herrenschmidt wrote:
> On Thu, 2011-12-15 at 19:00 +0800, Tiejun Chen wrote:
>> We can't emulate stwu since that may corrupt current exception stack.
>> So we will have to do real store operation in the exception return code.
>>
>> Firstly we'll allocate a trampoline exception frame below the kprobed
>> function stack and copy the current exception frame to the trampoline.
>> Then we can do this real store operation to implement 'stwu', and reroute
>> the trampoline frame to r1 to complete this exception migration.
>>
>> Signed-off-by: Tiejun Chen <tiejun.c...@windriver.com>
>> ---
>>  arch/powerpc/kernel/entry_32.S |   35 +++++++++++++++++++++++++++++++++++
>>  1 files changed, 35 insertions(+), 0 deletions(-)
>>
>> diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
>> index 56212bc..0cdd27d 100644
>> --- a/arch/powerpc/kernel/entry_32.S
>> +++ b/arch/powerpc/kernel/entry_32.S
>> @@ -850,6 +850,41 @@ resume_kernel:
>>  
>>      /* interrupts are hard-disabled at this point */
>>  restore:
>> +    lwz     r3,_MSR(r1)     /* Returning to user mode? */
>> +    andi.   r0,r3,MSR_PR
>> +    bne     1f      
> 
>  .../...
> 

Sorry for this delay response since I can't take time to do this last week :(

> Wouldn't it be better to use resume_kernel here ?

Agreed :)

> 
> IE. We already have restore_user vs. resume_kernel labels, including
> the PR test. In the !PREEMPT case, resume_kernel is empty but it's
> there, so you can just "populate" it, ie, something like:
> 
> restore_user:
>       ... existing dbcr0 stuff ...
>       b restore
> 
> resume_kernel: <-- removed the ifdef CONFIG_PREEMPT
> 
>       ... Do the stack store business here...
> 
> #ifdef CONFIG_PREEMPT
>       ... move the preempt code here...
> #endif
> 
> restore:
>       ... existing stuff ...
> 
> Also, the added advantage is that the code to calc
> the thread info pointer and load the TI_FLAG can be
> shared now between your stuff and preempt, ie:
> 
> resume_kernel:
>       rlwinm  r9,r1,0,0,(31-THREAD_SHIFT)
>       lwz     r0,TI_FLAGS(r9)
>       andis.  r0,r0,_TIF_EMULATE_STACK_STORE@h
>       bne-    emulate_stack_store
> #ifdef CONFIG_PREEMPT
>       lwz     r8,TI_PREEMPT(r9) <-- note use of r8 instead of r0,
>                                       I -think- r8 can be clobbered
>                                       here but pls dbl check

Its should be safe.

>       cmpwi   0,r8,0
>       bne     restore
>       andi.   r0,r0,_TIF_NEED_RESCHED
>       etc...

Please check if next, v3, is fine.

>       
>> +    /* check current_thread_info, _TIF_EMULATE_STACK_STORE */
>> +    rlwinm  r9,r1,0,0,(31-THREAD_SHIFT)
>> +    lwz     r0,TI_FLAGS(r9)
>> +    andis.  r0,r0,_TIF_EMULATE_STACK_STORE@h
>> +    beq+    1f      
>> +
>> +    addi    r9,r1,INT_FRAME_SIZE    /* Get the kprobed function entry */
>> +
>> +    lwz     r3,GPR1(r1)
>> +    subi    r3,r3,INT_FRAME_SIZE    /* dst: Allocate a trampoline exception 
>> frame */
>> +    mr      r4,r1                   /* src:  current exception frame */
>> +    li      r5,INT_FRAME_SIZE       /* size: INT_FRAME_SIZE */
>> +    mr      r1,r3                   /* Reroute the trampoline frame to r1 */
>> +    bl      memcpy                  /* Copy from the original to the 
>> trampoline */
>> +
>> +    /* Do real store operation to complete stwu */
>> +    lwz     r5,GPR1(r1)
>> +    stw     r9,0(r5)
> 
> Ok, I think I -finally- understand your trick of using r1 +
> INT_FRAME_SIZE as the value to store :-) It makes sense and it's
> actually a nice hack :-)
> 
> I would recommend that in the C code part of the emulation, you
> add some sanity checking to make sure we don't overflow the
> kernel stack etc... it should come in generally handy especially
> if what's your trying to debug with kprobes is a kernel stack
> overflow :-)

Added.

> 
>> +    /* Clear _TIF_EMULATE_STACK_STORE flag */
>> +    rlwinm  r9,r1,0,0,(31-THREAD_SHIFT)
>> +    lis     r11,_TIF_EMULATE_STACK_STORE@h
>> +    addi    r9,r9,TI_FLAGS
>> +0:  lwarx   r8,0,r9
>> +    andc    r8,r8,r11
>> +#ifdef CONFIG_IBM405_ERR77
>> +    dcbt    0,r9
>> +#endif
>> +    stwcx.  r8,0,r9
>> +    bne-    0b
>> +1:
>> +
>>  #ifdef CONFIG_44x
>>  BEGIN_MMU_FTR_SECTION
>>      b       1f
> 
> BTW. Are you going to do a ppc64 variant of that patch ?

I'd like to go ppc64 ASAP once we did on ppc32 is good enough :)

Tiejun

> 
> Cheers,
> Ben.
> 
> 
> 
> 

_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Reply via email to