]> Pileus Git - ~andy/linux/blobdiff - arch/x86/kernel/entry_64.S
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal
[~andy/linux] / arch / x86 / kernel / entry_64.S
index 44531acd9a81e83f932a34a409c028b24cdb9bce..cdc790c78f328ed0d9525c270ed9e4013db28bdb 100644 (file)
@@ -554,7 +554,7 @@ ENTRY(ret_from_fork)
        RESTORE_REST
 
        testl $3, CS-ARGOFFSET(%rsp)            # from kernel_thread?
-       jz   retint_restore_args
+       jz   1f
 
        testl $_TIF_IA32, TI_flags(%rcx)        # 32-bit compat task needs IRET
        jnz  int_ret_from_sys_call
@@ -562,6 +562,16 @@ ENTRY(ret_from_fork)
        RESTORE_TOP_OF_STACK %rdi, -ARGOFFSET
        jmp ret_from_sys_call                   # go to the SYSRET fastpath
 
+1:
+       subq $REST_SKIP, %rsp   # move the stack pointer back
+       CFI_ADJUST_CFA_OFFSET   REST_SKIP
+       movq %rbp, %rdi
+       call *%rbx
+       # exit
+       mov %eax, %edi
+       call do_exit
+       ud2                     # padding for call trace
+
        CFI_ENDPROC
 END(ret_from_fork)
 
@@ -862,7 +872,6 @@ ENTRY(stub_execve)
        PARTIAL_FRAME 0
        SAVE_REST
        FIXUP_TOP_OF_STACK %r11
-       movq %rsp, %rcx
        call sys_execve
        RESTORE_TOP_OF_STACK %r11
        movq %rax,RAX(%rsp)
@@ -912,8 +921,7 @@ ENTRY(stub_x32_execve)
        PARTIAL_FRAME 0
        SAVE_REST
        FIXUP_TOP_OF_STACK %r11
-       movq %rsp, %rcx
-       call sys32_execve
+       call compat_sys_execve
        RESTORE_TOP_OF_STACK %r11
        movq %rax,RAX(%rsp)
        RESTORE_REST
@@ -1318,51 +1326,19 @@ bad_gs:
        jmp  2b
        .previous
 
-ENTRY(kernel_thread_helper)
-       pushq $0                # fake return address
-       CFI_STARTPROC
-       /*
-        * Here we are in the child and the registers are set as they were
-        * at kernel_thread() invocation in the parent.
-        */
-       call *%rsi
-       # exit
-       mov %eax, %edi
-       call do_exit
-       ud2                     # padding for call trace
-       CFI_ENDPROC
-END(kernel_thread_helper)
-
-/*
- * execve(). This function needs to use IRET, not SYSRET, to set up all state properly.
- *
- * C extern interface:
- *      extern long execve(const char *name, char **argv, char **envp)
- *
- * asm input arguments:
- *     rdi: name, rsi: argv, rdx: envp
- *
- * We want to fallback into:
- *     extern long sys_execve(const char *name, char **argv,char **envp, struct pt_regs *regs)
- *
- * do_sys_execve asm fallback arguments:
- *     rdi: name, rsi: argv, rdx: envp, rcx: fake frame on the stack
- */
-ENTRY(kernel_execve)
-       CFI_STARTPROC
-       FAKE_STACK_FRAME $0
-       SAVE_ALL
-       movq %rsp,%rcx
-       call sys_execve
-       movq %rax, RAX(%rsp)
-       RESTORE_REST
-       testq %rax,%rax
-       je int_ret_from_sys_call
-       RESTORE_ARGS
-       UNFAKE_STACK_FRAME
-       ret
-       CFI_ENDPROC
-END(kernel_execve)
+ENTRY(ret_from_kernel_execve)
+       movq %rdi, %rsp
+       movl $0, RAX(%rsp)
+       // RESTORE_REST
+       movq 0*8(%rsp), %r15
+       movq 1*8(%rsp), %r14
+       movq 2*8(%rsp), %r13
+       movq 3*8(%rsp), %r12
+       movq 4*8(%rsp), %rbp
+       movq 5*8(%rsp), %rbx
+       addq $(6*8), %rsp
+       jmp int_ret_from_sys_call
+END(ret_from_kernel_execve)
 
 /* Call softirq on interrupt stack. Interrupts are off. */
 ENTRY(call_softirq)