X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=kernel%2Farch%2Fpowerpc%2Fkernel%2Fentry_64.S;h=1aae3fdb0c2a5ef224f72335c46ff31e9cff72f6;hb=52f993b8e89487ec9ee15a7fb4979e0f09a45b27;hp=5e2d2645d1e00649408a4f6fe0d3a93af8507283;hpb=9ca8dbcc65cfc63d6f5ef3312a33184e1d726e00;p=kvmfornfv.git diff --git a/kernel/arch/powerpc/kernel/entry_64.S b/kernel/arch/powerpc/kernel/entry_64.S index 5e2d2645d..1aae3fdb0 100644 --- a/kernel/arch/powerpc/kernel/entry_64.S +++ b/kernel/arch/powerpc/kernel/entry_64.S @@ -19,6 +19,7 @@ */ #include +#include #include #include #include @@ -34,6 +35,7 @@ #include #include #include +#include /* * 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 r9, 1 + rldimi r10, r9, MSR_TM_LG, 63-MSR_TM_LG + mtmsrd r10, 0 + + /* tabort, this dooms the transaction, nothing else */ + li r9, (TM_CAUSE_SYSCALL|TM_CAUSE_PERSISTENT) + TABORT(R9) + + /* + * 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 r9, MSR_RI + andc r10, r10, r9 + 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