From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate.crashing.org (gate.crashing.org [63.228.1.57]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 529FA2C0086 for ; Fri, 14 Sep 2012 07:42:10 +1000 (EST) Message-ID: <1347572526.2276.29.camel@pasglop> Subject: Re: [v3][PATCH 2/3] ppc/kprobe: complete kprobe and migrate exception frame From: Benjamin Herrenschmidt To: "tiejun.chen" Date: Fri, 14 Sep 2012 07:42:06 +1000 In-Reply-To: <5051B749.5040606@windriver.com> References: <1347330053-27039-1-git-send-email-tiejun.chen@windriver.com> <1347330053-27039-2-git-send-email-tiejun.chen@windriver.com> <1347342718.2603.38.camel@pasglop> <505049FE.8060204@windriver.com> <1347439382.2603.97.camel@pasglop> <50504DEE.6060903@windriver.com> <1347446296.2276.0.camel@pasglop> <5051B749.5040606@windriver.com> Content-Type: text/plain; charset="UTF-8" Mime-Version: 1.0 Cc: linuxppc-dev@lists.ozlabs.org List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , On Thu, 2012-09-13 at 18:36 +0800, tiejun.chen wrote: > On 09/12/2012 06:38 PM, Benjamin Herrenschmidt wrote: > > On Wed, 2012-09-12 at 16:55 +0800, tiejun.chen wrote: > >>> to worry about nor stack frame to create etc... > >> > >> If you don't like this v4, let me know and then I can go back memcpy > >> for next > >> version. > > > > Just open code the whole copy. It should be easy really. As I said, you > > have the src and dst already in registers and you know they are aligned, > > so just put the size of the frame in a register (divided by 4), do an > > mtctr and do a little load_update/store_update loop to do the copy, all > > in the asm. > > Is the following Okay? Well, why did you bother with the flushes ? One of the main reason I wasn't too happy with hijacking copy_and_flush is that ... you really don't need to bother about flushing the cache :-) The flush in that routine is about copying kernel code around and making sure the I/D caches stay in sync. Cheers, Ben. > --- > arch/powerpc/kernel/entry_32.S | 55 +++++++++++++++++++++++++++++++++++----- > arch/powerpc/kernel/entry_64.S | 45 ++++++++++++++++++++++++++++++++ > 2 files changed, 94 insertions(+), 6 deletions(-) > > diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S > index ead5016..3b56bba 100644 > --- a/arch/powerpc/kernel/entry_32.S > +++ b/arch/powerpc/kernel/entry_32.S > @@ -32,6 +32,7 @@ > #include > #include > #include > +#include > > #undef SHOW_SYSCALLS > #undef SHOW_SYSCALLS_TASK > @@ -831,19 +832,63 @@ restore_user: > bnel- load_dbcr0 > #endif > > -#ifdef CONFIG_PREEMPT > b restore > > /* N.B. the only way to get here is from the beq following ret_from_except. */ > resume_kernel: > - /* check current_thread_info->preempt_count */ > + /* check current_thread_info, _TIF_EMULATE_STACK_STORE */ > CURRENT_THREAD_INFO(r9, r1) > + lwz r8,TI_FLAGS(r9) > + andis. r8,r8,_TIF_EMULATE_STACK_STORE@h > + beq+ 1f > + > + addi r8,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 */ > + li r6,0 /* start offset: 0 */ > + mr r1,r3 /* Reroute the trampoline frame to r1 */ > + > + /* Copy from the original to the trampoline. */ > + addi r5,r5,-4 > + addi r6,r6,-4 > +4: li r0,L1_CACHE_BYTES/4 > + mtctr r0 > +3: addi r6,r6,4 /* copy a cache line */ > + lwzx r0,r6,r4 > + stwx r0,r6,r3 > + bdnz 3b > + dcbst r6,r3 /* write it to memory */ > + sync > + cmplw 0,r6,r5 > + blt 4b > + > + /* Do real store operation to complete stwu */ > + lwz r5,GPR1(r1) > + stw r8,0(r5) > + > + /* Clear _TIF_EMULATE_STACK_STORE flag */ > + lis r11,_TIF_EMULATE_STACK_STORE@h > + addi r5,r9,TI_FLAGS > +0: lwarx r8,0,r5 > + andc r8,r8,r11 > +#ifdef CONFIG_IBM405_ERR77 > + dcbt 0,r5 > +#endif > + stwcx. r8,0,r5 > + bne- 0b > +1: > + > +#ifdef CONFIG_PREEMPT > + /* check current_thread_info->preempt_count */ > lwz r0,TI_PREEMPT(r9) > cmpwi 0,r0,0 /* if non-zero, just restore regs and return */ > bne restore > - lwz r0,TI_FLAGS(r9) > - andi. r0,r0,_TIF_NEED_RESCHED > + andi. r8,r8,_TIF_NEED_RESCHED > beq+ restore > + lwz r3,_MSR(r1) > andi. r0,r3,MSR_EE /* interrupts off? */ > beq restore /* don't schedule if so */ > #ifdef CONFIG_TRACE_IRQFLAGS > @@ -864,8 +909,6 @@ resume_kernel: > */ > bl trace_hardirqs_on > #endif > -#else > -resume_kernel: > #endif /* CONFIG_PREEMPT */ > > /* interrupts are hard-disabled at this point */ > diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S > index b40e0b4..cc43b64 100644 > --- a/arch/powerpc/kernel/entry_64.S > +++ b/arch/powerpc/kernel/entry_64.S > @@ -593,6 +593,51 @@ _GLOBAL(ret_from_except_lite) > b .ret_from_except > > resume_kernel: > + /* check current_thread_info, _TIF_EMULATE_STACK_STORE */ > + CURRENT_THREAD_INFO(r9, r1) > + ld r8,TI_FLAGS(r9) > + andis. r8,r8,_TIF_EMULATE_STACK_STORE@h > + beq+ 1f > + > + addi r8,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 */ > + li r6,0 /* start offset: 0 */ > + mr r1,r3 /* Reroute the trampoline frame to r1 */ > + > + /* Copy from the original to the trampoline. */ > + addi r5,r5,-8 > + addi r6,r6,-8 > +4: li r0,8 > + mtctr r0 > +3: addi r6,r6,8 /* copy a cache line */ > + ldx r0,r6,r4 > + stdx r0,r6,r3 > + bdnz 3b > + dcbst r6,r3 /* write it to memory */ > + sync > + cmpld 0,r6,r5 > + blt 4b > + sync > + > + bl .copy_and_flush > + > + /* Do real store operation to complete stwu */ > + lwz r5,GPR1(r1) > + std r8,0(r5) > + > + /* Clear _TIF_EMULATE_STACK_STORE flag */ > + lis r11,_TIF_EMULATE_STACK_STORE@h > + addi r5,r9,TI_FLAGS > + ldarx r4,0,r5 > + andc r4,r4,r11 > + stdcx. r4,0,r5 > + bne- 0b > +1: > + > #ifdef CONFIG_PREEMPT > /* Check if we need to preempt */ > andi. r0,r4,_TIF_NEED_RESCHED