diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2012-09-10 16:44:54 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-09-30 22:53:31 -0400 |
commit | 7076aada1040de4ed79a5977dbabdb5e5ea5e249 (patch) | |
tree | dfcf480d21cd714a1cc42f38417c427d06526f5a /arch/x86/kernel/entry_64.S | |
parent | 44f4b56b54d2ab5d06c1726f2cde8ca15c8fac47 (diff) |
x86: split ret_from_fork
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'arch/x86/kernel/entry_64.S')
-rw-r--r-- | arch/x86/kernel/entry_64.S | 27 |
1 files changed, 11 insertions, 16 deletions
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 69babd8c834f..5526d17db676 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S | |||
@@ -450,7 +450,7 @@ ENTRY(ret_from_fork) | |||
450 | RESTORE_REST | 450 | RESTORE_REST |
451 | 451 | ||
452 | testl $3, CS-ARGOFFSET(%rsp) # from kernel_thread? | 452 | testl $3, CS-ARGOFFSET(%rsp) # from kernel_thread? |
453 | jz retint_restore_args | 453 | jz 1f |
454 | 454 | ||
455 | testl $_TIF_IA32, TI_flags(%rcx) # 32-bit compat task needs IRET | 455 | testl $_TIF_IA32, TI_flags(%rcx) # 32-bit compat task needs IRET |
456 | jnz int_ret_from_sys_call | 456 | jnz int_ret_from_sys_call |
@@ -458,6 +458,16 @@ ENTRY(ret_from_fork) | |||
458 | RESTORE_TOP_OF_STACK %rdi, -ARGOFFSET | 458 | RESTORE_TOP_OF_STACK %rdi, -ARGOFFSET |
459 | jmp ret_from_sys_call # go to the SYSRET fastpath | 459 | jmp ret_from_sys_call # go to the SYSRET fastpath |
460 | 460 | ||
461 | 1: | ||
462 | subq $REST_SKIP, %rsp # move the stack pointer back | ||
463 | CFI_ADJUST_CFA_OFFSET REST_SKIP | ||
464 | movq %rbp, %rdi | ||
465 | call *%rbx | ||
466 | # exit | ||
467 | mov %eax, %edi | ||
468 | call do_exit | ||
469 | ud2 # padding for call trace | ||
470 | |||
461 | CFI_ENDPROC | 471 | CFI_ENDPROC |
462 | END(ret_from_fork) | 472 | END(ret_from_fork) |
463 | 473 | ||
@@ -1206,21 +1216,6 @@ bad_gs: | |||
1206 | jmp 2b | 1216 | jmp 2b |
1207 | .previous | 1217 | .previous |
1208 | 1218 | ||
1209 | ENTRY(kernel_thread_helper) | ||
1210 | pushq $0 # fake return address | ||
1211 | CFI_STARTPROC | ||
1212 | /* | ||
1213 | * Here we are in the child and the registers are set as they were | ||
1214 | * at kernel_thread() invocation in the parent. | ||
1215 | */ | ||
1216 | call *%rsi | ||
1217 | # exit | ||
1218 | mov %eax, %edi | ||
1219 | call do_exit | ||
1220 | ud2 # padding for call trace | ||
1221 | CFI_ENDPROC | ||
1222 | END(kernel_thread_helper) | ||
1223 | |||
1224 | /* | 1219 | /* |
1225 | * execve(). This function needs to use IRET, not SYSRET, to set up all state properly. | 1220 | * execve(). This function needs to use IRET, not SYSRET, to set up all state properly. |
1226 | * | 1221 | * |