ret_from_fork is a mix of assembly code and calls to C functions. Re-implement ret_from_fork so that it calls a single C function.
Signed-off-by: Alexandre Chartre <alexandre.char...@oracle.com> --- arch/x86/entry/common.c | 18 ++++++++++++++++++ arch/x86/entry/entry_64.S | 28 +++++----------------------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c index d222212908ad..7ee15a12c115 100644 --- a/arch/x86/entry/common.c +++ b/arch/x86/entry/common.c @@ -35,6 +35,24 @@ #include <asm/syscall.h> #include <asm/irq_stack.h> +__visible noinstr void return_from_fork(struct pt_regs *regs, + struct task_struct *prev, + void (*kfunc)(void *), void *kargs) +{ + schedule_tail(prev); + if (kfunc) { + /* kernel thread */ + kfunc(kargs); + /* + * A kernel thread is allowed to return here after + * successfully calling kernel_execve(). Exit to + * userspace to complete the execve() syscall. + */ + regs->ax = 0; + } + syscall_exit_to_user_mode(regs); +} + static __always_inline void run_syscall(sys_call_ptr_t sysfunc, struct pt_regs *regs) { diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S index 274384644b5e..73e9cd47dc83 100644 --- a/arch/x86/entry/entry_64.S +++ b/arch/x86/entry/entry_64.S @@ -276,31 +276,13 @@ SYM_FUNC_END(__switch_to_asm) */ .pushsection .text, "ax" SYM_CODE_START(ret_from_fork) - UNWIND_HINT_EMPTY - movq %rax, %rdi - call schedule_tail /* rdi: 'prev' task parameter */ - - testq %rbx, %rbx /* from kernel_thread? */ - jnz 1f /* kernel threads are uncommon */ - -2: UNWIND_HINT_REGS - movq %rsp, %rdi - call syscall_exit_to_user_mode /* returns with IRQs disabled */ + movq %rsp, %rdi /* pt_regs */ + movq %rax, %rsi /* 'prev' task parameter */ + movq %rbx, %rdx /* kernel thread func */ + movq %r12, %rcx /* kernel thread arg */ + call return_from_fork /* returns with IRQs disabled */ jmp swapgs_restore_regs_and_return_to_usermode - -1: - /* kernel thread */ - UNWIND_HINT_EMPTY - movq %r12, %rdi - CALL_NOSPEC rbx - /* - * A kernel thread is allowed to return here after successfully - * calling kernel_execve(). Exit to userspace to complete the execve() - * syscall. - */ - movq $0, RAX(%rsp) - jmp 2b SYM_CODE_END(ret_from_fork) .popsection -- 2.18.4