diff options
Diffstat (limited to 'arch/powerpc/kernel/entry_32.S')
-rw-r--r-- | arch/powerpc/kernel/entry_32.S | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index 0713daa651d9..ad000cbb5252 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S @@ -575,6 +575,33 @@ 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 r9, SPRN_SRR0 + mfspr r10, SPRN_SRR1 +#if !defined(CONFIG_4xx) && !defined(CONFIG_BOOKE) + LOAD_REG_IMMEDIATE(r11, MSR_KERNEL & ~(MSR_IR|MSR_DR)) + mtmsr r11 +#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_SRR0, r9 + mtspr SPRN_SRR1, r10 + 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 |