Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86/entry/64: Stop using int_ret_from_sys_call in ret_from_fork

ret_from_fork is now open-coded and is no longer tangled up with
the syscall code. This isn't so bad -- this adds very little
code, and IMO the result is much easier to understand.

Signed-off-by: Andy Lutomirski <luto@kernel.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/a0747e2a5e47084655a1e96351c545b755c41fa7.1454022279.git.luto@kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>

authored by

Andy Lutomirski and committed by
Ingo Molnar
24d978b7 46eabf06

+21 -18
+21 -18
arch/x86/entry/entry_64.S
··· 390 390 * rdi: prev task we switched from 391 391 */ 392 392 ENTRY(ret_from_fork) 393 - 394 393 LOCK ; btr $TIF_FORK, TI_flags(%r8) 395 394 396 395 pushq $0x0002 ··· 397 398 398 399 call schedule_tail /* rdi: 'prev' task parameter */ 399 400 400 - RESTORE_EXTRA_REGS 401 - 402 401 testb $3, CS(%rsp) /* from kernel_thread? */ 402 + jnz 1f 403 403 404 404 /* 405 - * By the time we get here, we have no idea whether our pt_regs, 406 - * ti flags, and ti status came from the 64-bit SYSCALL fast path, 407 - * the slow path, or one of the 32-bit compat paths. 408 - * Use IRET code path to return, since it can safely handle 409 - * all of the above. 405 + * We came from kernel_thread. This code path is quite twisted, and 406 + * someone should clean it up. 407 + * 408 + * copy_thread_tls stashes the function pointer in RBX and the 409 + * parameter to be passed in RBP. The called function is permitted 410 + * to call do_execve and thereby jump to user mode. 410 411 */ 411 - jnz int_ret_from_sys_call 412 - 413 - /* 414 - * We came from kernel_thread 415 - * nb: we depend on RESTORE_EXTRA_REGS above 416 - */ 417 - movq %rbp, %rdi 418 - call *%rbx 412 + movq RBP(%rsp), %rdi 413 + call *RBX(%rsp) 419 414 movl $0, RAX(%rsp) 420 - RESTORE_EXTRA_REGS 421 - jmp int_ret_from_sys_call 415 + 416 + /* 417 + * Fall through as though we're exiting a syscall. This makes a 418 + * twisted sort of sense if we just called do_execve. 419 + */ 420 + 421 + 1: 422 + movq %rsp, %rdi 423 + call syscall_return_slowpath /* returns with IRQs disabled */ 424 + TRACE_IRQS_ON /* user mode is traced as IRQS on */ 425 + SWAPGS 426 + jmp restore_regs_and_iret 422 427 END(ret_from_fork) 423 428 424 429 /*