Merge tag 'ntb-4.13' of git://github.com/jonmason/ntb
[sfrench/cifs-2.6.git] / arch / powerpc / kernel / entry_64.S
index bfbad08a120788b5ead7531f664865ff0b86a924..49d8422767b4de686ec0ee64fbf69ac415f05003 100644 (file)
@@ -57,7 +57,7 @@ system_call_common:
 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
 BEGIN_FTR_SECTION
        extrdi. r10, r12, 1, (63-MSR_TS_T_LG) /* transaction active? */
-       bne     tabort_syscall
+       bne     .Ltabort_syscall
 END_FTR_SECTION_IFSET(CPU_FTR_TM)
 #endif
        andi.   r10,r12,MSR_PR
@@ -143,6 +143,7 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR)
        mtmsrd  r11,1
 #endif /* CONFIG_PPC_BOOK3E */
 
+system_call:                   /* label this so stack traces look sane */
        /* We do need to set SOFTE in the stack frame or the return
         * from interrupt will be painful
         */
@@ -152,11 +153,11 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR)
        CURRENT_THREAD_INFO(r11, r1)
        ld      r10,TI_FLAGS(r11)
        andi.   r11,r10,_TIF_SYSCALL_DOTRACE
-       bne     syscall_dotrace         /* does not return */
+       bne     .Lsyscall_dotrace               /* does not return */
        cmpldi  0,r0,NR_syscalls
-       bge-    syscall_enosys
+       bge-    .Lsyscall_enosys
 
-system_call:                   /* label this so stack traces look sane */
+.Lsyscall:
 /*
  * Need to vector to 32 Bit or default sys_call_table here,
  * based on caller's run-mode / personality.
@@ -185,8 +186,20 @@ system_call:                       /* label this so stack traces look sane */
 #ifdef CONFIG_PPC_BOOK3S
        /* No MSR:RI on BookE */
        andi.   r10,r8,MSR_RI
-       beq-    unrecov_restore
+       beq-    .Lunrecov_restore
 #endif
+
+/*
+ * This is a few instructions into the actual syscall exit path (which actually
+ * starts at .Lsyscall_exit) to cater to kprobe blacklisting and to reduce the
+ * number of visible symbols for profiling purposes.
+ *
+ * We can probe from system_call until this point as MSR_RI is set. But once it
+ * is cleared below, we won't be able to take a trap.
+ *
+ * This is blacklisted from kprobes further below with _ASM_NOKPROBE_SYMBOL().
+ */
+system_call_exit:
        /*
         * Disable interrupts so current_thread_info()->flags can't change,
         * and so that we don't get interrupted after loading SRR0/1.
@@ -208,31 +221,21 @@ system_call:                      /* label this so stack traces look sane */
        ld      r9,TI_FLAGS(r12)
        li      r11,-MAX_ERRNO
        andi.   r0,r9,(_TIF_SYSCALL_DOTRACE|_TIF_SINGLESTEP|_TIF_USER_WORK_MASK|_TIF_PERSYSCALL_MASK)
-       bne-    syscall_exit_work
+       bne-    .Lsyscall_exit_work
 
-       andi.   r0,r8,MSR_FP
-       beq 2f
+       /* If MSR_FP and MSR_VEC are set in user msr, then no need to restore */
+       li      r7,MSR_FP
 #ifdef CONFIG_ALTIVEC
-       andis.  r0,r8,MSR_VEC@h
-       bne     3f
-#endif
-2:     addi    r3,r1,STACK_FRAME_OVERHEAD
-#ifdef CONFIG_PPC_BOOK3S
-       li      r10,MSR_RI
-       mtmsrd  r10,1           /* Restore RI */
-#endif
-       bl      restore_math
-#ifdef CONFIG_PPC_BOOK3S
-       li      r11,0
-       mtmsrd  r11,1
+       oris    r7,r7,MSR_VEC@h
 #endif
-       ld      r8,_MSR(r1)
-       ld      r3,RESULT(r1)
-       li      r11,-MAX_ERRNO
+       and     r0,r8,r7
+       cmpd    r0,r7
+       bne     .Lsyscall_restore_math
+.Lsyscall_restore_math_cont:
 
-3:     cmpld   r3,r11
+       cmpld   r3,r11
        ld      r5,_CCR(r1)
-       bge-    syscall_error
+       bge-    .Lsyscall_error
 .Lsyscall_error_cont:
        ld      r7,_NIP(r1)
 BEGIN_FTR_SECTION
@@ -258,14 +261,48 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
        RFI
        b       .       /* prevent speculative execution */
 
-syscall_error: 
+.Lsyscall_error:
        oris    r5,r5,0x1000    /* Set SO bit in CR */
        neg     r3,r3
        std     r5,_CCR(r1)
        b       .Lsyscall_error_cont
-       
+
+.Lsyscall_restore_math:
+       /*
+        * Some initial tests from restore_math to avoid the heavyweight
+        * C code entry and MSR manipulations.
+        */
+       LOAD_REG_IMMEDIATE(r0, MSR_TS_MASK)
+       and.    r0,r0,r8
+       bne     1f
+
+       ld      r7,PACACURRENT(r13)
+       lbz     r0,THREAD+THREAD_LOAD_FP(r7)
+#ifdef CONFIG_ALTIVEC
+       lbz     r6,THREAD+THREAD_LOAD_VEC(r7)
+       add     r0,r0,r6
+#endif
+       cmpdi   r0,0
+       beq     .Lsyscall_restore_math_cont
+
+1:     addi    r3,r1,STACK_FRAME_OVERHEAD
+#ifdef CONFIG_PPC_BOOK3S
+       li      r10,MSR_RI
+       mtmsrd  r10,1           /* Restore RI */
+#endif
+       bl      restore_math
+#ifdef CONFIG_PPC_BOOK3S
+       li      r11,0
+       mtmsrd  r11,1
+#endif
+       /* Restore volatiles, reload MSR from updated one */
+       ld      r8,_MSR(r1)
+       ld      r3,RESULT(r1)
+       li      r11,-MAX_ERRNO
+       b       .Lsyscall_restore_math_cont
+
 /* Traced system call support */
-syscall_dotrace:
+.Lsyscall_dotrace:
        bl      save_nvgprs
        addi    r3,r1,STACK_FRAME_OVERHEAD
        bl      do_syscall_trace_enter
@@ -286,23 +323,23 @@ syscall_dotrace:
        ld      r7,GPR7(r1)
        ld      r8,GPR8(r1)
 
-       /* Repopulate r9 and r10 for the system_call path */
+       /* Repopulate r9 and r10 for the syscall path */
        addi    r9,r1,STACK_FRAME_OVERHEAD
        CURRENT_THREAD_INFO(r10, r1)
        ld      r10,TI_FLAGS(r10)
 
        cmpldi  r0,NR_syscalls
-       blt+    system_call
+       blt+    .Lsyscall
 
        /* Return code is already in r3 thanks to do_syscall_trace_enter() */
        b       .Lsyscall_exit
 
 
-syscall_enosys:
+.Lsyscall_enosys:
        li      r3,-ENOSYS
        b       .Lsyscall_exit
        
-syscall_exit_work:
+.Lsyscall_exit_work:
 #ifdef CONFIG_PPC_BOOK3S
        li      r10,MSR_RI
        mtmsrd  r10,1           /* Restore RI */
@@ -362,7 +399,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
        b       ret_from_except
 
 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
-tabort_syscall:
+.Ltabort_syscall:
        /* Firstly we need to enable TM in the kernel */
        mfmsr   r10
        li      r9, 1
@@ -388,6 +425,8 @@ tabort_syscall:
        rfid
        b       .       /* prevent speculative execution */
 #endif
+_ASM_NOKPROBE_SYMBOL(system_call_common);
+_ASM_NOKPROBE_SYMBOL(system_call_exit);
 
 /* Save non-volatile GPRs, if not already saved. */
 _GLOBAL(save_nvgprs)
@@ -398,6 +437,7 @@ _GLOBAL(save_nvgprs)
        clrrdi  r0,r11,1
        std     r0,_TRAP(r1)
        blr
+_ASM_NOKPROBE_SYMBOL(save_nvgprs);
 
        
 /*
@@ -488,33 +528,30 @@ _GLOBAL(_switch)
        std     r23,_CCR(r1)
        std     r1,KSP(r3)      /* Set old stack pointer */
 
-#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
-        * stores it has performed on this one.
+       /*
+        * On SMP kernels, care must be taken because a task may be
+        * scheduled off CPUx and on to CPUy. Memory ordering must be
+        * considered.
+        *
+        * Cacheable stores on CPUx will be visible when the task is
+        * scheduled on CPUy by virtue of the core scheduler barriers
+        * (see "Notes on Program-Order guarantees on SMP systems." in
+        * kernel/sched/core.c).
+        *
+        * Uncacheable stores in the case of involuntary preemption must
+        * be taken care of. The smp_mb__before_spin_lock() in __schedule()
+        * is implemented as hwsync on powerpc, which orders MMIO too. So
+        * long as there is an hwsync in the context switch path, it will
+        * be executed on the source CPU after the task has performed
+        * all MMIO ops on that CPU, and on the destination CPU before the
+        * task performs any MMIO ops there.
         */
-       sync
-#endif /* CONFIG_SMP */
 
        /*
-        * If we optimise away the clear of the reservation in system
-        * calls because we know the CPU tracks the address of the
-        * reservation, then we need to clear it here to cover the
-        * case that the kernel context switch path has no larx
-        * instructions.
+        * The kernel context switch path must contain a spin_lock,
+        * which contains larx/stcx, which will clear any reservation
+        * of the task being switched.
         */
-BEGIN_FTR_SECTION
-       ldarx   r6,0,r1
-END_FTR_SECTION_IFSET(CPU_FTR_STCX_CHECKS_ADDRESS)
-
-BEGIN_FTR_SECTION
-/*
- * A cp_abort (copy paste abort) here ensures that when context switching, a
- * copy from one process can't leak into the paste of another.
- */
-       PPC_CP_ABORT
-END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
-
 #ifdef CONFIG_PPC_BOOK3S
 /* Cancel all explict user streams as they will have no use after context
  * switch and will stop the HW from creating streams itself
@@ -583,6 +620,14 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
           top of the kernel stack. */
        addi    r7,r7,THREAD_SIZE-SWITCH_FRAME_SIZE
 
+       /*
+        * PMU interrupts in radix may come in here. They will use r1, not
+        * PACAKSAVE, so this stack switch will not cause a problem. They
+        * will store to the process stack, which may then be migrated to
+        * another CPU. However the rq lock release on this CPU paired with
+        * the rq lock acquire on the new CPU before the stack becomes
+        * active on the new CPU, will order those stores.
+        */
        mr      r1,r8           /* start using new stack pointer */
        std     r7,PACAKSAVE(r13)
 
@@ -763,11 +808,11 @@ restore:
        ld      r5,SOFTE(r1)
        lbz     r6,PACASOFTIRQEN(r13)
        cmpwi   cr0,r5,0
-       beq     restore_irq_off
+       beq     .Lrestore_irq_off
 
        /* We are enabling, were we already enabled ? Yes, just return */
        cmpwi   cr0,r6,1
-       beq     cr0,do_restore
+       beq     cr0,.Ldo_restore
 
        /*
         * We are about to soft-enable interrupts (we are hard disabled
@@ -776,14 +821,14 @@ restore:
         */
        lbz     r0,PACAIRQHAPPENED(r13)
        cmpwi   cr0,r0,0
-       bne-    restore_check_irq_replay
+       bne-    .Lrestore_check_irq_replay
 
        /*
         * Get here when nothing happened while soft-disabled, just
         * soft-enable and move-on. We will hard-enable as a side
         * effect of rfi
         */
-restore_no_replay:
+.Lrestore_no_replay:
        TRACE_ENABLE_INTS
        li      r0,1
        stb     r0,PACASOFTIRQEN(r13);
@@ -791,7 +836,7 @@ restore_no_replay:
        /*
         * Final return path. BookE is handled in a different file
         */
-do_restore:
+.Ldo_restore:
 #ifdef CONFIG_PPC_BOOK3E
        b       exception_return_book3e
 #else
@@ -825,7 +870,7 @@ fast_exception_return:
        REST_8GPRS(5, r1)
 
        andi.   r0,r3,MSR_RI
-       beq-    unrecov_restore
+       beq-    .Lunrecov_restore
 
        /* Load PPR from thread struct before we clear MSR:RI */
 BEGIN_FTR_SECTION
@@ -883,7 +928,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
         * make sure that in this case, we also clear PACA_IRQ_HARD_DIS
         * or that bit can get out of sync and bad things will happen
         */
-restore_irq_off:
+.Lrestore_irq_off:
        ld      r3,_MSR(r1)
        lbz     r7,PACAIRQHAPPENED(r13)
        andi.   r0,r3,MSR_EE
@@ -893,13 +938,13 @@ restore_irq_off:
 1:     li      r0,0
        stb     r0,PACASOFTIRQEN(r13);
        TRACE_DISABLE_INTS
-       b       do_restore
+       b       .Ldo_restore
 
        /*
         * Something did happen, check if a re-emit is needed
         * (this also clears paca->irq_happened)
         */
-restore_check_irq_replay:
+.Lrestore_check_irq_replay:
        /* XXX: We could implement a fast path here where we check
         * for irq_happened being just 0x01, in which case we can
         * clear it and return. That means that we would potentially
@@ -909,7 +954,7 @@ restore_check_irq_replay:
         */
        bl      __check_irq_replay
        cmpwi   cr0,r3,0
-       beq     restore_no_replay
+       beq     .Lrestore_no_replay
  
        /*
         * We need to re-emit an interrupt. We do so by re-using our
@@ -958,10 +1003,18 @@ restore_check_irq_replay:
 #endif /* CONFIG_PPC_DOORBELL */
 1:     b       ret_from_except /* What else to do here ? */
  
-unrecov_restore:
+.Lunrecov_restore:
        addi    r3,r1,STACK_FRAME_OVERHEAD
        bl      unrecoverable_exception
-       b       unrecov_restore
+       b       .Lunrecov_restore
+
+_ASM_NOKPROBE_SYMBOL(ret_from_except);
+_ASM_NOKPROBE_SYMBOL(ret_from_except_lite);
+_ASM_NOKPROBE_SYMBOL(resume_kernel);
+_ASM_NOKPROBE_SYMBOL(fast_exc_return_irq);
+_ASM_NOKPROBE_SYMBOL(restore);
+_ASM_NOKPROBE_SYMBOL(fast_exception_return);
+
 
 #ifdef CONFIG_PPC_RTAS
 /*
@@ -1038,6 +1091,8 @@ _GLOBAL(enter_rtas)
         rldicr  r9,r9,MSR_SF_LG,(63-MSR_SF_LG)
        ori     r9,r9,MSR_IR|MSR_DR|MSR_FE0|MSR_FE1|MSR_FP|MSR_RI|MSR_LE
        andc    r6,r0,r9
+
+__enter_rtas:
        sync                            /* disable interrupts so SRR0/1 */
        mtmsrd  r0                      /* don't get trashed */
 
@@ -1074,6 +1129,8 @@ rtas_return_loc:
        mtspr   SPRN_SRR1,r4
        rfid
        b       .       /* prevent speculative execution */
+_ASM_NOKPROBE_SYMBOL(__enter_rtas)
+_ASM_NOKPROBE_SYMBOL(rtas_return_loc)
 
        .align  3
 1:     .llong  rtas_restore_regs