1*83762a71Sderaadt/* $OpenBSD: tfork_thread.S,v 1.12 2023/12/10 16:45:51 deraadt Exp $ */ 2c6f64c6fSguenther/*- 3c6f64c6fSguenther * Copyright (c) 2000 Peter Wemm <peter@FreeBSD.org> 4c6f64c6fSguenther * Copyright (c) 2003 Alan L. Cox <alc@cs.rice.edu> 5c6f64c6fSguenther * All rights reserved. 6c6f64c6fSguenther * 7c6f64c6fSguenther * Redistribution and use in source and binary forms, with or without 8c6f64c6fSguenther * modification, are permitted provided that the following conditions 9c6f64c6fSguenther * are met: 10c6f64c6fSguenther * 1. Redistributions of source code must retain the above copyright 11c6f64c6fSguenther * notice, this list of conditions and the following disclaimer. 12c6f64c6fSguenther * 2. Redistributions in binary form must reproduce the above copyright 13c6f64c6fSguenther * notice, this list of conditions and the following disclaimer in the 14c6f64c6fSguenther * documentation and/or other materials provided with the distribution. 15c6f64c6fSguenther * 16c6f64c6fSguenther * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17c6f64c6fSguenther * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18c6f64c6fSguenther * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19c6f64c6fSguenther * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20c6f64c6fSguenther * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21c6f64c6fSguenther * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22c6f64c6fSguenther * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23c6f64c6fSguenther * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24c6f64c6fSguenther * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25c6f64c6fSguenther * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26c6f64c6fSguenther * SUCH DAMAGE. 27c6f64c6fSguenther */ 28c6f64c6fSguenther 29c6f64c6fSguenther#include <machine/asm.h> 30c6f64c6fSguenther 31c6f64c6fSguenther/* 32c6f64c6fSguenther * With thanks to John Dyson for the original version of this. 33c6f64c6fSguenther */ 34c6f64c6fSguenther 35c6f64c6fSguenther#include "SYS.h" 36c6f64c6fSguenther 37c6f64c6fSguenther/* 38c6f64c6fSguenther * %rdi %rsi %rdx %rcx 3916b62b6aSguenther * __tfork_thread(param, psize, start_fnc, start_arg); 40c6f64c6fSguenther * 41c6f64c6fSguenther * param: Argument to pass to the actual kernel call. 4216b62b6aSguenther * psize: Other argument to pass to the actual kernel call. 43c6f64c6fSguenther * start_fnc: Address of thread function to call in child. 44c6f64c6fSguenther * start_arg: Argument to pass to the thread function in child. 45c6f64c6fSguenther */ 46c6f64c6fSguenther 47c6f64c6fSguentherENTRY(__tfork_thread) 487e6b5442Sguenther .cfi_startproc 4939b8558cSmortimer RETGUARD_SETUP(__tfork_thread, r11); 5039b8558cSmortimer RETGUARD_PUSH(r11); 51c6f64c6fSguenther movq %rdx, %r8 52c6f64c6fSguenther movq %rcx, %r9 53c6f64c6fSguenther 54c6f64c6fSguenther /* 55c6f64c6fSguenther * Prepare and execute the thread creation syscall 56c6f64c6fSguenther */ 57c6f64c6fSguenther movl $SYS___tfork, %eax 587e6b5442Sguenther .cfi_endproc 59*83762a71Sderaadt99: syscall 60*83762a71Sderaadt PINSYSCALL(SYS___tfork, 99b) 61c6f64c6fSguenther jb 2f 62c6f64c6fSguenther 63c6f64c6fSguenther /* 64c6f64c6fSguenther * Check to see if we are in the parent or child 65c6f64c6fSguenther */ 6611225f07Sguenther cmpl $0, %eax 6711225f07Sguenther jz 1f 6839b8558cSmortimer jmp 3f 69c6f64c6fSguenther 7050634ea5Sguenther /* the retpoline we'll use to call the child's main */ 7150634ea5Sguenther _ALIGN_TRAPS 727e6b5442Sguenther .cfi_startproc 7350634ea5Sguenther0: JMP_RETPOLINE(r8) 7450634ea5Sguenther 75c6f64c6fSguenther /* 76c6f64c6fSguenther * If we are in the child (new thread), then 77c6f64c6fSguenther * set-up the call to the internal subroutine. If it 78c6f64c6fSguenther * returns, then call __threxit. 79c6f64c6fSguenther */ 8050634ea5Sguenther _ALIGN_TRAPS 81c6f64c6fSguenther1: 827e6b5442Sguenther /* Mark top frame of new thread in CFI and with zero FP */ 837e6b5442Sguenther .cfi_undefined rip 847e6b5442Sguenther .cfi_undefined rsp 857e6b5442Sguenther xorl %ebp, %ebp 86c6f64c6fSguenther movq %r9, %rdi 8750634ea5Sguenther call 0b 88c6f64c6fSguenther 89c6f64c6fSguenther /* 90c6f64c6fSguenther * Thread exit system call 91c6f64c6fSguenther */ 92c6f64c6fSguenther movl $SYS___threxit, %eax 93c6f64c6fSguenther xorl %edi, %edi 94*83762a71Sderaadt98: syscall 95*83762a71Sderaadt PINSYSCALL(SYS___threxit, 98b) 9613df6982Sderaadt int3 97c6f64c6fSguenther 98c6f64c6fSguenther /* 99c6f64c6fSguenther * Branch here if the thread creation fails: 100c6f64c6fSguenther */ 101c6f64c6fSguenther2: 102fe38b55cSguenther SET_ERRNO 10339b8558cSmortimer3: 10439b8558cSmortimer RETGUARD_POP(r11); 10539b8558cSmortimer RETGUARD_CHECK(__tfork_thread, r11); 106fe38b55cSguenther ret 1077e6b5442Sguenther .cfi_endproc 108fdc9f3d7SuebayasiEND(__tfork_thread) 109