These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / arch / powerpc / kernel / entry_64.S
index 5e2d264..5bb3148 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <linux/errno.h>
+#include <linux/err.h>
 #include <asm/unistd.h>
 #include <asm/processor.h>
 #include <asm/page.h>
@@ -34,6 +35,7 @@
 #include <asm/ftrace.h>
 #include <asm/hw_irq.h>
 #include <asm/context_tracking.h>
+#include <asm/tm.h>
 
 /*
  * System calls.
@@ -51,6 +53,12 @@ exception_marker:
 
        .globl system_call_common
 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
+END_FTR_SECTION_IFSET(CPU_FTR_TM)
+#endif
        andi.   r10,r12,MSR_PR
        mr      r10,r1
        addi    r1,r1,-INT_FRAME_SIZE
@@ -143,8 +151,7 @@ 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
-.Lsyscall_dotrace_cont:
+       bne     syscall_dotrace         /* does not return */
        cmpldi  0,r0,NR_syscalls
        bge-    syscall_enosys
 
@@ -200,7 +207,7 @@ system_call:                        /* label this so stack traces look sane */
 #endif /* CONFIG_PPC_BOOK3E */
 
        ld      r9,TI_FLAGS(r12)
-       li      r11,-_LAST_ERRNO
+       li      r11,-MAX_ERRNO
        andi.   r0,r9,(_TIF_SYSCALL_DOTRACE|_TIF_SINGLESTEP|_TIF_USER_WORK_MASK|_TIF_PERSYSCALL_MASK)
        bne-    syscall_exit_work
        cmpld   r3,r11
@@ -238,22 +245,34 @@ syscall_dotrace:
        bl      save_nvgprs
        addi    r3,r1,STACK_FRAME_OVERHEAD
        bl      do_syscall_trace_enter
+
        /*
-        * Restore argument registers possibly just changed.
-        * We use the return value of do_syscall_trace_enter
-        * for the call number to look up in the table (r0).
+        * We use the return value of do_syscall_trace_enter() as the syscall
+        * number. If the syscall was rejected for any reason do_syscall_trace_enter()
+        * returns an invalid syscall number and the test below against
+        * NR_syscalls will fail.
         */
        mr      r0,r3
+
+       /* Restore argument registers just clobbered and/or possibly changed. */
        ld      r3,GPR3(r1)
        ld      r4,GPR4(r1)
        ld      r5,GPR5(r1)
        ld      r6,GPR6(r1)
        ld      r7,GPR7(r1)
        ld      r8,GPR8(r1)
+
+       /* Repopulate r9 and r10 for the system_call path */
        addi    r9,r1,STACK_FRAME_OVERHEAD
        CURRENT_THREAD_INFO(r10, r1)
        ld      r10,TI_FLAGS(r10)
-       b       .Lsyscall_dotrace_cont
+
+       cmpldi  r0,NR_syscalls
+       blt+    system_call
+
+       /* Return code is already in r3 thanks to do_syscall_trace_enter() */
+       b       .Lsyscall_exit
+
 
 syscall_enosys:
        li      r3,-ENOSYS
@@ -270,7 +289,7 @@ syscall_exit_work:
        beq+    0f
        REST_NVGPRS(r1)
        b       2f
-0:     cmpld   r3,r11          /* r10 is -LAST_ERRNO */
+0:     cmpld   r3,r11          /* r11 is -MAX_ERRNO */
        blt+    1f
        andi.   r0,r9,_TIF_NOERROR
        bne-    1f
@@ -311,6 +330,34 @@ syscall_exit_work:
        bl      do_syscall_trace_leave
        b       ret_from_except
 
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+tabort_syscall:
+       /* Firstly we need to enable TM in the kernel */
+       mfmsr   r10
+       li      r13, 1
+       rldimi  r10, r13, MSR_TM_LG, 63-MSR_TM_LG
+       mtmsrd  r10, 0
+
+       /* tabort, this dooms the transaction, nothing else */
+       li      r13, (TM_CAUSE_SYSCALL|TM_CAUSE_PERSISTENT)
+       TABORT(R13)
+
+       /*
+        * Return directly to userspace. We have corrupted user register state,
+        * but userspace will never see that register state. Execution will
+        * resume after the tbegin of the aborted transaction with the
+        * checkpointed register state.
+        */
+       li      r13, MSR_RI
+       andc    r10, r10, r13
+       mtmsrd  r10, 1
+       mtspr   SPRN_SRR0, r11
+       mtspr   SPRN_SRR1, r12
+
+       rfid
+       b       .       /* prevent speculative execution */
+#endif
+
 /* Save non-volatile GPRs, if not already saved. */
 _GLOBAL(save_nvgprs)
        ld      r11,_TRAP(r1)
@@ -556,7 +603,7 @@ BEGIN_FTR_SECTION
        ld      r0,THREAD_DSCR(r4)
        cmpwi   r6,0
        bne     1f
-       ld      r0,PACA_DSCR(r13)
+       ld      r0,PACA_DSCR_DEFAULT(r13)
 1:
 BEGIN_FTR_SECTION_NESTED(70)
        mfspr   r8, SPRN_FSCR