/*
* "slow" syscall return path.
*/
-ENTRY(ret_to_user)
+ret_to_user:
disable_irq // disable interrupts
ldr x1, [tsk, #TI_FLAGS]
and x2, x1, #_TIF_WORK_MASK
*/
ENTRY(ret_from_fork)
bl schedule_tail
+ cmp x19, #0
+ movne x0, x20
+ blne x19
get_thread_info tsk
b ret_to_user
ENDPROC(ret_from_fork)
-ENTRY(ret_from_kernel_thread)
- bl schedule_tail
- mov x0, x20
- adr lr, do_exit // kernel threads should not exit
- br x19
-ENDPROC(ret_from_kernel_thread)
-
/*
* SVC handler.
*/
}
asmlinkage void ret_from_fork(void) asm("ret_from_fork");
-asmlinkage void ret_from_kernel_thread(void) asm("ret_from_kernel_thread");
int copy_thread(unsigned long clone_flags, unsigned long stack_start,
unsigned long stk_sz, struct task_struct *p,
*/
if (clone_flags & CLONE_SETTLS)
tls = regs->regs[3];
- p->thread.cpu_context.pc = (unsigned long)ret_from_fork;
} else {
+ memset(childregs, 0, sizeof(struct pt_regs));
childregs->pstate = PSR_MODE_EL1h;
p->thread.cpu_context.x19 = stack_start;
p->thread.cpu_context.x20 = stk_sz;
- p->thread.cpu_context.pc = (unsigned long)ret_from_kernel_thread;
}
+ p->thread.cpu_context.pc = (unsigned long)ret_from_fork;
p->thread.cpu_context.sp = (unsigned long)childregs;
p->thread.tp_value = tls;
return error;
}
-int kernel_execve(const char *filename,
- const char *const argv[],
- const char *const envp[])
-{
- struct pt_regs regs;
- int ret;
-
- memset(®s, 0, sizeof(struct pt_regs));
- ret = do_execve(filename,
- (const char __user *const __user *)argv,
- (const char __user *const __user *)envp, ®s);
- if (ret < 0)
- goto out;
-
- /*
- * Save argc to the register structure for userspace.
- */
- regs.regs[0] = ret;
-
- /*
- * We were successful. We won't be returning to our caller, but
- * instead to user space by manipulating the kernel stack.
- */
- asm( "add x0, %0, %1\n\t"
- "mov x1, %2\n\t"
- "mov x2, %3\n\t"
- "bl memmove\n\t" /* copy regs to top of stack */
- "mov x27, #0\n\t" /* not a syscall */
- "mov x28, %0\n\t" /* thread structure */
- "mov sp, x0\n\t" /* reposition stack pointer */
- "b ret_to_user"
- :
- : "r" (current_thread_info()),
- "Ir" (THREAD_START_SP - sizeof(regs)),
- "r" (®s),
- "Ir" (sizeof(regs))
- : "x0", "x1", "x2", "x27", "x28", "x30", "memory");
-
- out:
- return ret;
-}
-EXPORT_SYMBOL(kernel_execve);
-
asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags,
unsigned long fd, off_t off)