Merge git://git.infradead.org/users/eparis/audit
[firefly-linux-kernel-4.4.55.git] / arch / powerpc / kernel / entry_64.S
index c20d9bf4aa26504276f7ded80a31e4b11156e4c7..915fbb4fc2fe4e7534dbf78eb39317013b03b014 100644 (file)
@@ -62,8 +62,9 @@ system_call_common:
        std     r12,_MSR(r1)
        std     r0,GPR0(r1)
        std     r10,GPR1(r1)
+       beq     2f                      /* if from kernel mode */
        ACCOUNT_CPU_USER_ENTRY(r10, r11)
-       std     r2,GPR2(r1)
+2:     std     r2,GPR2(r1)
        std     r3,GPR3(r1)
        mfcr    r2
        std     r4,GPR4(r1)
@@ -94,7 +95,7 @@ system_call_common:
        addi    r9,r1,STACK_FRAME_OVERHEAD
        ld      r11,exception_marker@toc(r2)
        std     r11,-16(r9)             /* "regshere" marker */
-#if defined(CONFIG_VIRT_CPU_ACCOUNTING) && defined(CONFIG_PPC_SPLPAR)
+#if defined(CONFIG_VIRT_CPU_ACCOUNTING_NATIVE) && defined(CONFIG_PPC_SPLPAR)
 BEGIN_FW_FTR_SECTION
        beq     33f
        /* if from user, see if there are any DTL entries to process */
@@ -110,7 +111,7 @@ BEGIN_FW_FTR_SECTION
        addi    r9,r1,STACK_FRAME_OVERHEAD
 33:
 END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR)
-#endif /* CONFIG_VIRT_CPU_ACCOUNTING && CONFIG_PPC_SPLPAR */
+#endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE && CONFIG_PPC_SPLPAR */
 
        /*
         * A syscall should always be called with interrupts enabled
@@ -226,6 +227,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
 
        beq-    1f
        ACCOUNT_CPU_USER_EXIT(r11, r12)
+       HMT_MEDIUM_LOW_HAS_PPR
        ld      r13,GPR13(r1)   /* only restore r13 if returning to usermode */
 1:     ld      r2,GPR2(r1)
        ld      r1,GPR1(r1)
@@ -302,6 +304,7 @@ syscall_exit_work:
        subi    r12,r12,TI_FLAGS
 
 4:     /* Anything else left to do? */
+       SET_DEFAULT_THREAD_PPR(r3, r10)         /* Set thread.ppr = 3 */
        andi.   r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
        beq     .ret_from_except_lite
 
@@ -445,6 +448,27 @@ END_FTR_SECTION_IFSET(CPU_FTR_DSCR)
        std     r23,_CCR(r1)
        std     r1,KSP(r3)      /* Set old stack pointer */
 
+#ifdef CONFIG_PPC_BOOK3S_64
+BEGIN_FTR_SECTION
+       /*
+        * Back up the TAR across context switches.  Note that the TAR is not
+        * available for use in the kernel.  (To provide this, the TAR should
+        * be backed up/restored on exception entry/exit instead, and be in
+        * pt_regs.  FIXME, this should be in pt_regs anyway (for debug).)
+        */
+       mfspr   r0,SPRN_TAR
+       std     r0,THREAD_TAR(r3)
+
+       /* Event based branch registers */
+       mfspr   r0, SPRN_BESCR
+       std     r0, THREAD_BESCR(r3)
+       mfspr   r0, SPRN_EBBHR
+       std     r0, THREAD_EBBHR(r3)
+       mfspr   r0, SPRN_EBBRR
+       std     r0, THREAD_EBBRR(r3)
+END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
+#endif
+
 #ifdef CONFIG_SMP
        /* We need a sync somewhere here to make sure that if the
         * previous task gets rescheduled on another CPU, it sees all
@@ -527,6 +551,21 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
        mr      r1,r8           /* start using new stack pointer */
        std     r7,PACAKSAVE(r13)
 
+#ifdef CONFIG_PPC_BOOK3S_64
+BEGIN_FTR_SECTION
+       /* Event based branch registers */
+       ld      r0, THREAD_BESCR(r4)
+       mtspr   SPRN_BESCR, r0
+       ld      r0, THREAD_EBBHR(r4)
+       mtspr   SPRN_EBBHR, r0
+       ld      r0, THREAD_EBBRR(r4)
+       mtspr   SPRN_EBBRR, r0
+
+       ld      r0,THREAD_TAR(r4)
+       mtspr   SPRN_TAR,r0
+END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
+#endif
+
 #ifdef CONFIG_ALTIVEC
 BEGIN_FTR_SECTION
        ld      r0,THREAD_VRSAVE(r4)
@@ -634,7 +673,7 @@ resume_kernel:
        /* Clear _TIF_EMULATE_STACK_STORE flag */
        lis     r11,_TIF_EMULATE_STACK_STORE@h
        addi    r5,r9,TI_FLAGS
-       ldarx   r4,0,r5
+0:     ldarx   r4,0,r5
        andc    r4,r4,r11
        stdcx.  r4,0,r5
        bne-    0b
@@ -762,6 +801,10 @@ fast_exception_return:
        andc    r4,r4,r0         /* r0 contains MSR_RI here */
        mtmsrd  r4,1
 
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+       /* TM debug */
+       std     r3, PACATMSCRATCH(r13) /* Stash returned-to MSR */
+#endif
        /*
         * r13 is our per cpu area, only restore it if we are returning to
         * userspace the value stored in the stack frame may belong to
@@ -770,6 +813,7 @@ fast_exception_return:
        andi.   r0,r3,MSR_PR
        beq     1f
        ACCOUNT_CPU_USER_EXIT(r2, r4)
+       RESTORE_PPR(r2, r4)
        REST_GPR(13, r1)
 1:
        mtspr   SPRN_SRR1,r3
@@ -849,13 +893,22 @@ restore_check_irq_replay:
        addi    r3,r1,STACK_FRAME_OVERHEAD;
        bl      .timer_interrupt
        b       .ret_from_except
+#ifdef CONFIG_PPC_DOORBELL
+1:
 #ifdef CONFIG_PPC_BOOK3E
-1:     cmpwi   cr0,r3,0x280
+       cmpwi   cr0,r3,0x280
+#else
+       BEGIN_FTR_SECTION
+               cmpwi   cr0,r3,0xe80
+       FTR_SECTION_ELSE
+               cmpwi   cr0,r3,0xa00
+       ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE)
+#endif /* CONFIG_PPC_BOOK3E */
        bne     1f
        addi    r3,r1,STACK_FRAME_OVERHEAD;
        bl      .doorbell_exception
        b       .ret_from_except
-#endif /* CONFIG_PPC_BOOK3E */
+#endif /* CONFIG_PPC_DOORBELL */
 1:     b       .ret_from_except /* What else to do here ? */
  
 unrecov_restore: