Messages in this thread Patch in this message |  | | From | Christophe Leroy <> | Subject | [PATCH] powerpc/32: warn and return error on syscalls from kernel | Date | Tue, 7 Jan 2020 07:30:39 +0000 (UTC) |
| |
Since commit b86fb88855ea ("powerpc/32: implement fast entry for syscalls on non BOOKE") and commit 1a4b739bbb4f ("powerpc/32: implement fast entry for syscalls on BOOKE"), syscalls from kernel are unexpected and can have catastrophic consequences as it will destroy the kernel stack.
Test MSR_PR on syscall entry. In case syscall is from kernel, emit a warning and return ENOSYS error.
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr> --- arch/powerpc/kernel/entry_32.S | 26 ++++++++++++++++++++++++++ arch/powerpc/kernel/head_32.h | 9 ++++++--- arch/powerpc/kernel/head_booke.h | 5 ++++- 3 files changed, 36 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index d60908ea37fb..4a7cd22a8aaf 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S @@ -568,6 +568,32 @@ syscall_exit_work: bl do_syscall_trace_leave b ret_from_except_full + /* + * System call was called from kernel. We get here with SRR1 in r9. + * Mark the exception as recoverable once we have retrieved SRR0, + * trap a warning and return ENOSYS with CR[SO] set. + */ + .globl ret_from_kernel_syscall +ret_from_kernel_syscall: + mfspr r11, SPRN_SRR0 +#if !defined(CONFIG_4xx) && !defined(CONFIG_BOOKE) + LOAD_REG_IMMEDIATE(r12, MSR_KERNEL & ~(MSR_IR|MSR_DR)) + MTMSRD(r12) +#endif + +0: trap + EMIT_BUG_ENTRY 0b,__FILE__,__LINE__, BUGFLAG_WARNING + + li r3, ENOSYS + crset so +#if defined(CONFIG_PPC_8xx) && defined(CONFIG_PERF_EVENTS) + mtspr SPRN_NRI, r0 +#endif + mtspr SPRN_SRR1, r9 + mtspr SPRN_SRR0, r11 + SYNC + RFI + /* * The fork/clone functions need to copy the full register set into * the child process. Therefore we need to save all the nonvolatile diff --git a/arch/powerpc/kernel/head_32.h b/arch/powerpc/kernel/head_32.h index 8abc7783dbe5..07524be96ca7 100644 --- a/arch/powerpc/kernel/head_32.h +++ b/arch/powerpc/kernel/head_32.h @@ -62,16 +62,18 @@ .macro SYSCALL_ENTRY trapno mfspr r12,SPRN_SPRG_THREAD + mfspr r9, SPRN_SRR1 mfcr r10 + andi. r11, r9, MSR_PR lwz r11,TASK_STACK-THREAD(r12) - mflr r9 + beq- 99f addi r11,r11,THREAD_SIZE - INT_FRAME_SIZE rlwinm r10,r10,0,4,2 /* Clear SO bit in CR */ tophys(r11,r11) stw r10,_CCR(r11) /* save registers */ + mflr r10 + stw r10, _LINK(r11) mfspr r10,SPRN_SRR0 - stw r9,_LINK(r11) - mfspr r9,SPRN_SRR1 stw r1,GPR1(r11) stw r1,0(r11) tovirt(r1,r11) /* set new kernel sp */ @@ -139,6 +141,7 @@ mtspr SPRN_SRR0,r11 SYNC RFI /* jump to handler, enable MMU */ +99: b ret_from_kernel_syscall .endm /* diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h index 2ae635df9026..f2d11cb8102f 100644 --- a/arch/powerpc/kernel/head_booke.h +++ b/arch/powerpc/kernel/head_booke.h @@ -104,16 +104,18 @@ FTR_SECTION_ELSE #ifdef CONFIG_KVM_BOOKE_HV ALT_FTR_SECTION_END_IFSET(CPU_FTR_EMB_HV) #endif + mfspr r9, SPRN_SRR1 BOOKE_CLEAR_BTB(r11) + andi. r11, r9, MSR_PR lwz r11, TASK_STACK - THREAD(r10) rlwinm r12,r12,0,4,2 /* Clear SO bit in CR */ + beq- 99f ALLOC_STACK_FRAME(r11, THREAD_SIZE - INT_FRAME_SIZE) stw r12, _CCR(r11) /* save various registers */ mflr r12 stw r12,_LINK(r11) mfspr r12,SPRN_SRR0 stw r1, GPR1(r11) - mfspr r9,SPRN_SRR1 stw r1, 0(r11) mr r1, r11 stw r12,_NIP(r11) @@ -176,6 +178,7 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_EMB_HV) mtspr SPRN_SRR0,r11 SYNC RFI /* jump to handler, enable MMU */ +99: b ret_from_kernel_syscall .endm /* To handle the additional exception priority levels on 40x and Book-E -- 2.13.3
|  |