diff options
Diffstat (limited to 'arch/x86/kernel/entry_64.S')
-rw-r--r-- | arch/x86/kernel/entry_64.S | 49 |
1 files changed, 3 insertions, 46 deletions
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 673f693fb451..0697ff139837 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S | |||
@@ -1166,63 +1166,20 @@ bad_gs: | |||
1166 | jmp 2b | 1166 | jmp 2b |
1167 | .previous | 1167 | .previous |
1168 | 1168 | ||
1169 | /* | 1169 | ENTRY(kernel_thread_helper) |
1170 | * Create a kernel thread. | ||
1171 | * | ||
1172 | * C extern interface: | ||
1173 | * extern long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) | ||
1174 | * | ||
1175 | * asm input arguments: | ||
1176 | * rdi: fn, rsi: arg, rdx: flags | ||
1177 | */ | ||
1178 | ENTRY(kernel_thread) | ||
1179 | CFI_STARTPROC | ||
1180 | FAKE_STACK_FRAME $child_rip | ||
1181 | SAVE_ALL | ||
1182 | |||
1183 | # rdi: flags, rsi: usp, rdx: will be &pt_regs | ||
1184 | movq %rdx,%rdi | ||
1185 | orq kernel_thread_flags(%rip),%rdi | ||
1186 | movq $-1, %rsi | ||
1187 | movq %rsp, %rdx | ||
1188 | |||
1189 | xorl %r8d,%r8d | ||
1190 | xorl %r9d,%r9d | ||
1191 | |||
1192 | # clone now | ||
1193 | call do_fork | ||
1194 | movq %rax,RAX(%rsp) | ||
1195 | xorl %edi,%edi | ||
1196 | |||
1197 | /* | ||
1198 | * It isn't worth to check for reschedule here, | ||
1199 | * so internally to the x86_64 port you can rely on kernel_thread() | ||
1200 | * not to reschedule the child before returning, this avoids the need | ||
1201 | * of hacks for example to fork off the per-CPU idle tasks. | ||
1202 | * [Hopefully no generic code relies on the reschedule -AK] | ||
1203 | */ | ||
1204 | RESTORE_ALL | ||
1205 | UNFAKE_STACK_FRAME | ||
1206 | ret | ||
1207 | CFI_ENDPROC | ||
1208 | END(kernel_thread) | ||
1209 | |||
1210 | ENTRY(child_rip) | ||
1211 | pushq $0 # fake return address | 1170 | pushq $0 # fake return address |
1212 | CFI_STARTPROC | 1171 | CFI_STARTPROC |
1213 | /* | 1172 | /* |
1214 | * Here we are in the child and the registers are set as they were | 1173 | * Here we are in the child and the registers are set as they were |
1215 | * at kernel_thread() invocation in the parent. | 1174 | * at kernel_thread() invocation in the parent. |
1216 | */ | 1175 | */ |
1217 | movq %rdi, %rax | 1176 | call *%rsi |
1218 | movq %rsi, %rdi | ||
1219 | call *%rax | ||
1220 | # exit | 1177 | # exit |
1221 | mov %eax, %edi | 1178 | mov %eax, %edi |
1222 | call do_exit | 1179 | call do_exit |
1223 | ud2 # padding for call trace | 1180 | ud2 # padding for call trace |
1224 | CFI_ENDPROC | 1181 | CFI_ENDPROC |
1225 | END(child_rip) | 1182 | END(kernel_thread_helper) |
1226 | 1183 | ||
1227 | /* | 1184 | /* |
1228 | * execve(). This function needs to use IRET, not SYSRET, to set up all state properly. | 1185 | * execve(). This function needs to use IRET, not SYSRET, to set up all state properly. |