* caller list:
  *  - handle_exception
  *  - ret_from_fork
- *  - ret_from_kernel_thread
  */
 SYM_CODE_START_NOALIGN(ret_from_exception)
        REG_L s0, PT_STATUS(sp)
 
 SYM_CODE_START(ret_from_fork)
        call schedule_tail
-       move a0, sp /* pt_regs */
-       la ra, ret_from_exception
-       tail syscall_exit_to_user_mode
-SYM_CODE_END(ret_from_fork)
-
-SYM_CODE_START(ret_from_kernel_thread)
-       call schedule_tail
+       beqz s0, 1f     /* not from kernel thread */
        /* Call fn(arg) */
        move a0, s1
        jalr s0
+1:
        move a0, sp /* pt_regs */
        la ra, ret_from_exception
        tail syscall_exit_to_user_mode
-SYM_CODE_END(ret_from_kernel_thread)
+SYM_CODE_END(ret_from_fork)
 
 /*
  * Integer register context switch
 
 #endif
 
 extern asmlinkage void ret_from_fork(void);
-extern asmlinkage void ret_from_kernel_thread(void);
 
 void arch_cpu_idle(void)
 {
                /* Supervisor/Machine, irqs on: */
                childregs->status = SR_PP | SR_PIE;
 
-               p->thread.ra = (unsigned long)ret_from_kernel_thread;
                p->thread.s[0] = (unsigned long)args->fn;
                p->thread.s[1] = (unsigned long)args->fn_arg;
        } else {
                if (clone_flags & CLONE_SETTLS)
                        childregs->tp = tls;
                childregs->a0 = 0; /* Return value of fork() */
-               p->thread.ra = (unsigned long)ret_from_fork;
+               p->thread.s[0] = 0;
        }
+       p->thread.ra = (unsigned long)ret_from_fork;
        p->thread.sp = (unsigned long)childregs; /* kernel sp */
        return 0;
 }