aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTiejun Chen <tiejun.chen@windriver.com>2012-09-16 19:54:30 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2012-09-18 01:32:42 -0400
commita9c4e541ea9b22944da356f2a9258b4eddcc953b (patch)
tree3231ff5c12366200c5f5d48e654415e628a231f0
parentf0d1128fcb919a73941a54f80efab04fa3160dfe (diff)
powerpc/kprobe: Complete kprobe and migrate exception frame
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.chen@windriver.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r--arch/powerpc/kernel/entry_32.S47
-rw-r--r--arch/powerpc/kernel/entry_64.S35
2 files changed, 76 insertions, 6 deletions
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index ead5016b02d0..af37528da49f 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -831,19 +831,56 @@ restore_user:
831 bnel- load_dbcr0 831 bnel- load_dbcr0
832#endif 832#endif
833 833
834#ifdef CONFIG_PREEMPT
835 b restore 834 b restore
836 835
837/* N.B. the only way to get here is from the beq following ret_from_except. */ 836/* N.B. the only way to get here is from the beq following ret_from_except. */
838resume_kernel: 837resume_kernel:
839 /* check current_thread_info->preempt_count */ 838 /* check current_thread_info, _TIF_EMULATE_STACK_STORE */
840 CURRENT_THREAD_INFO(r9, r1) 839 CURRENT_THREAD_INFO(r9, r1)
840 lwz r8,TI_FLAGS(r9)
841 andis. r8,r8,_TIF_EMULATE_STACK_STORE@h
842 beq+ 1f
843
844 addi r8,r1,INT_FRAME_SIZE /* Get the kprobed function entry */
845
846 lwz r3,GPR1(r1)
847 subi r3,r3,INT_FRAME_SIZE /* dst: Allocate a trampoline exception frame */
848 mr r4,r1 /* src: current exception frame */
849 mr r1,r3 /* Reroute the trampoline frame to r1 */
850
851 /* Copy from the original to the trampoline. */
852 li r5,INT_FRAME_SIZE/4 /* size: INT_FRAME_SIZE */
853 li r6,0 /* start offset: 0 */
854 mtctr r5
8552: lwzx r0,r6,r4
856 stwx r0,r6,r3
857 addi r6,r6,4
858 bdnz 2b
859
860 /* Do real store operation to complete stwu */
861 lwz r5,GPR1(r1)
862 stw r8,0(r5)
863
864 /* Clear _TIF_EMULATE_STACK_STORE flag */
865 lis r11,_TIF_EMULATE_STACK_STORE@h
866 addi r5,r9,TI_FLAGS
8670: lwarx r8,0,r5
868 andc r8,r8,r11
869#ifdef CONFIG_IBM405_ERR77
870 dcbt 0,r5
871#endif
872 stwcx. r8,0,r5
873 bne- 0b
8741:
875
876#ifdef CONFIG_PREEMPT
877 /* check current_thread_info->preempt_count */
841 lwz r0,TI_PREEMPT(r9) 878 lwz r0,TI_PREEMPT(r9)
842 cmpwi 0,r0,0 /* if non-zero, just restore regs and return */ 879 cmpwi 0,r0,0 /* if non-zero, just restore regs and return */
843 bne restore 880 bne restore
844 lwz r0,TI_FLAGS(r9) 881 andi. r8,r8,_TIF_NEED_RESCHED
845 andi. r0,r0,_TIF_NEED_RESCHED
846 beq+ restore 882 beq+ restore
883 lwz r3,_MSR(r1)
847 andi. r0,r3,MSR_EE /* interrupts off? */ 884 andi. r0,r3,MSR_EE /* interrupts off? */
848 beq restore /* don't schedule if so */ 885 beq restore /* don't schedule if so */
849#ifdef CONFIG_TRACE_IRQFLAGS 886#ifdef CONFIG_TRACE_IRQFLAGS
@@ -864,8 +901,6 @@ resume_kernel:
864 */ 901 */
865 bl trace_hardirqs_on 902 bl trace_hardirqs_on
866#endif 903#endif
867#else
868resume_kernel:
869#endif /* CONFIG_PREEMPT */ 904#endif /* CONFIG_PREEMPT */
870 905
871 /* interrupts are hard-disabled at this point */ 906 /* interrupts are hard-disabled at this point */
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index b40e0b4815b3..0e931aaffca2 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -593,6 +593,41 @@ _GLOBAL(ret_from_except_lite)
593 b .ret_from_except 593 b .ret_from_except
594 594
595resume_kernel: 595resume_kernel:
596 /* check current_thread_info, _TIF_EMULATE_STACK_STORE */
597 CURRENT_THREAD_INFO(r9, r1)
598 ld r8,TI_FLAGS(r9)
599 andis. r8,r8,_TIF_EMULATE_STACK_STORE@h
600 beq+ 1f
601
602 addi r8,r1,INT_FRAME_SIZE /* Get the kprobed function entry */
603
604 lwz r3,GPR1(r1)
605 subi r3,r3,INT_FRAME_SIZE /* dst: Allocate a trampoline exception frame */
606 mr r4,r1 /* src: current exception frame */
607 mr r1,r3 /* Reroute the trampoline frame to r1 */
608
609 /* Copy from the original to the trampoline. */
610 li r5,INT_FRAME_SIZE/8 /* size: INT_FRAME_SIZE */
611 li r6,0 /* start offset: 0 */
612 mtctr r5
6132: ldx r0,r6,r4
614 stdx r0,r6,r3
615 addi r6,r6,8
616 bdnz 2b
617
618 /* Do real store operation to complete stwu */
619 lwz r5,GPR1(r1)
620 std r8,0(r5)
621
622 /* Clear _TIF_EMULATE_STACK_STORE flag */
623 lis r11,_TIF_EMULATE_STACK_STORE@h
624 addi r5,r9,TI_FLAGS
625 ldarx r4,0,r5
626 andc r4,r4,r11
627 stdcx. r4,0,r5
628 bne- 0b
6291:
630
596#ifdef CONFIG_PREEMPT 631#ifdef CONFIG_PREEMPT
597 /* Check if we need to preempt */ 632 /* Check if we need to preempt */
598 andi. r0,r4,_TIF_NEED_RESCHED 633 andi. r0,r4,_TIF_NEED_RESCHED