aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBharat Bhushan <r65777@freescale.com>2013-05-22 00:20:59 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2013-06-20 03:04:19 -0400
commit13d543cd79963133cd26748547552c99df8d23a7 (patch)
tree57706ff1223fd56e8544236e77df7658f833bb0d
parentd8899bb2be91b3a19ebf82b138232919ffcf833a (diff)
powerpc: Restore dbcr0 on user space exit
On BookE (Branch taken + Single Step) is as same as Branch Taken on BookS and in Linux we simulate BookS behavior for BookE as well. When doing so, in Branch taken handling we want to set DBCR0_IC but we update the current->thread->dbcr0 and not DBCR0. Now on 64bit the current->thread.dbcr0 (and other debug registers) is synchronized ONLY on context switch flow. But after handling Branch taken in debug exception if we return back to user space without context switch then single stepping change (DBCR0_ICMP) does not get written in h/w DBCR0 and Instruction Complete exception does not happen. This fixes using ptrace reliably on BookE-PowerPC lmbench latency test (lat_syscall) Results are (they varies a little on each run) 1) ./lat_syscall <action> /dev/shm/uImage action: Open read write stat fstat null Before: 3.8618 0.2017 0.2851 1.6789 0.2256 0.0856 After: 3.8580 0.2017 0.2851 1.6955 0.2255 0.0856 1) ./lat_syscall -P 2 -N 10 <action> /dev/shm/uImage action: Open read write stat fstat null Before: 4.1388 0.2238 0.3066 1.7106 0.2256 0.0856 After: 4.1413 0.2236 0.3062 1.7107 0.2256 0.0856 [ Slightly modified to avoid extra branch in the fast path on Book3S and fix build on all non-BookE 64-bit -- BenH ] Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r--arch/powerpc/kernel/asm-offsets.c6
-rw-r--r--arch/powerpc/kernel/entry_64.S30
2 files changed, 29 insertions, 7 deletions
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 6f16ffafa6f0..dc684b1af1c4 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -105,9 +105,6 @@ int main(void)
105 DEFINE(KSP_VSID, offsetof(struct thread_struct, ksp_vsid)); 105 DEFINE(KSP_VSID, offsetof(struct thread_struct, ksp_vsid));
106#else /* CONFIG_PPC64 */ 106#else /* CONFIG_PPC64 */
107 DEFINE(PGDIR, offsetof(struct thread_struct, pgdir)); 107 DEFINE(PGDIR, offsetof(struct thread_struct, pgdir));
108#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
109 DEFINE(THREAD_DBCR0, offsetof(struct thread_struct, dbcr0));
110#endif
111#ifdef CONFIG_SPE 108#ifdef CONFIG_SPE
112 DEFINE(THREAD_EVR0, offsetof(struct thread_struct, evr[0])); 109 DEFINE(THREAD_EVR0, offsetof(struct thread_struct, evr[0]));
113 DEFINE(THREAD_ACC, offsetof(struct thread_struct, acc)); 110 DEFINE(THREAD_ACC, offsetof(struct thread_struct, acc));
@@ -115,6 +112,9 @@ int main(void)
115 DEFINE(THREAD_USED_SPE, offsetof(struct thread_struct, used_spe)); 112 DEFINE(THREAD_USED_SPE, offsetof(struct thread_struct, used_spe));
116#endif /* CONFIG_SPE */ 113#endif /* CONFIG_SPE */
117#endif /* CONFIG_PPC64 */ 114#endif /* CONFIG_PPC64 */
115#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
116 DEFINE(THREAD_DBCR0, offsetof(struct thread_struct, dbcr0));
117#endif
118#ifdef CONFIG_KVM_BOOK3S_32_HANDLER 118#ifdef CONFIG_KVM_BOOK3S_32_HANDLER
119 DEFINE(THREAD_KVM_SVCPU, offsetof(struct thread_struct, kvm_shadow_vcpu)); 119 DEFINE(THREAD_KVM_SVCPU, offsetof(struct thread_struct, kvm_shadow_vcpu));
120#endif 120#endif
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 8741c854e03d..ab15b8d057ad 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -629,21 +629,43 @@ _GLOBAL(ret_from_except_lite)
629 629
630 CURRENT_THREAD_INFO(r9, r1) 630 CURRENT_THREAD_INFO(r9, r1)
631 ld r3,_MSR(r1) 631 ld r3,_MSR(r1)
632#ifdef CONFIG_PPC_BOOK3E
633 ld r10,PACACURRENT(r13)
634#endif /* CONFIG_PPC_BOOK3E */
632 ld r4,TI_FLAGS(r9) 635 ld r4,TI_FLAGS(r9)
633 andi. r3,r3,MSR_PR 636 andi. r3,r3,MSR_PR
634 beq resume_kernel 637 beq resume_kernel
638#ifdef CONFIG_PPC_BOOK3E
639 lwz r3,(THREAD+THREAD_DBCR0)(r10)
640#endif /* CONFIG_PPC_BOOK3E */
635 641
636 /* Check current_thread_info()->flags */ 642 /* Check current_thread_info()->flags */
637 andi. r0,r4,_TIF_USER_WORK_MASK 643 andi. r0,r4,_TIF_USER_WORK_MASK
644#ifdef CONFIG_PPC_BOOK3E
645 bne 1f
646 /*
647 * Check to see if the dbcr0 register is set up to debug.
648 * Use the internal debug mode bit to do this.
649 */
650 andis. r0,r3,DBCR0_IDM@h
638 beq restore 651 beq restore
639 652 mfmsr r0
640 andi. r0,r4,_TIF_NEED_RESCHED 653 rlwinm r0,r0,0,~MSR_DE /* Clear MSR.DE */
641 beq 1f 654 mtmsr r0
655 mtspr SPRN_DBCR0,r3
656 li r10, -1
657 mtspr SPRN_DBSR,r10
658 b restore
659#else
660 beq restore
661#endif
6621: andi. r0,r4,_TIF_NEED_RESCHED
663 beq 2f
642 bl .restore_interrupts 664 bl .restore_interrupts
643 SCHEDULE_USER 665 SCHEDULE_USER
644 b .ret_from_except_lite 666 b .ret_from_except_lite
645 667
6461: bl .save_nvgprs 6682: bl .save_nvgprs
647 bl .restore_interrupts 669 bl .restore_interrupts
648 addi r3,r1,STACK_FRAME_OVERHEAD 670 addi r3,r1,STACK_FRAME_OVERHEAD
649 bl .do_notify_resume 671 bl .do_notify_resume