1*74a2bf1bSKonstantin Belousov/*- 2*74a2bf1bSKonstantin Belousov * SPDX-License-Identifier: BSD-2-Clause 3*74a2bf1bSKonstantin Belousov * 4*74a2bf1bSKonstantin Belousov * Copyright 2000 Peter Wemm <peter@FreeBSD.org> 5*74a2bf1bSKonstantin Belousov * Copyright 2003 Alan L. Cox <alc@cs.rice.edu> 6*74a2bf1bSKonstantin Belousov * Copyright 2026 The FreeBSD Foundation 7*74a2bf1bSKonstantin Belousov * All rights reserved. 8*74a2bf1bSKonstantin Belousov * 9*74a2bf1bSKonstantin Belousov * Portions of this software were developed by 10*74a2bf1bSKonstantin Belousov * Konstantin Belousov <kib@FreeBSD.org> under sponsorship from 11*74a2bf1bSKonstantin Belousov * the FreeBSD Foundation. 12*74a2bf1bSKonstantin Belousov */ 13*74a2bf1bSKonstantin Belousov 14*74a2bf1bSKonstantin Belousov#include <machine/asm.h> 15*74a2bf1bSKonstantin Belousov/* 16*74a2bf1bSKonstantin Belousov * With thanks to John Dyson for the original version of this. 17*74a2bf1bSKonstantin Belousov */ 18*74a2bf1bSKonstantin Belousov 19*74a2bf1bSKonstantin Belousov#include <SYS.h> 20*74a2bf1bSKonstantin Belousov 21*74a2bf1bSKonstantin Belousov/* 22*74a2bf1bSKonstantin Belousov * %rdi %esi %rdx %rcx %r8 %r9 23*74a2bf1bSKonstantin Belousov * pdrfork_thread(fdp, pdflags, rfflags, stack_addr, start_fnc, start_arg); 24*74a2bf1bSKonstantin Belousov * 25*74a2bf1bSKonstantin Belousov * fdp Pointer for the resulting fd location 26*74a2bf1bSKonstantin Belousov * pdflags Flags as to pdfork. 27*74a2bf1bSKonstantin Belousov * rfflags: Flags as to rfork. 28*74a2bf1bSKonstantin Belousov * stack_addr: Top of stack for thread. 29*74a2bf1bSKonstantin Belousov * start_fnc: Address of thread function to call in child. 30*74a2bf1bSKonstantin Belousov * start_arg: Argument to pass to the thread function in child. 31*74a2bf1bSKonstantin Belousov */ 32*74a2bf1bSKonstantin Belousov 33*74a2bf1bSKonstantin BelousovENTRY(pdrfork_thread) 34*74a2bf1bSKonstantin Belousov pushq %rbx 35*74a2bf1bSKonstantin Belousov pushq %r12 36*74a2bf1bSKonstantin Belousov pushq %r13 37*74a2bf1bSKonstantin Belousov movq %r8, %rbx 38*74a2bf1bSKonstantin Belousov movq %r9, %r12 39*74a2bf1bSKonstantin Belousov movq %rcx, %r13 40*74a2bf1bSKonstantin Belousov 41*74a2bf1bSKonstantin Belousov /* 42*74a2bf1bSKonstantin Belousov * Prepare and execute the thread creation syscall 43*74a2bf1bSKonstantin Belousov */ 44*74a2bf1bSKonstantin Belousov _SYSCALL(pdrfork) 45*74a2bf1bSKonstantin Belousov jb 2f 46*74a2bf1bSKonstantin Belousov 47*74a2bf1bSKonstantin Belousov /* 48*74a2bf1bSKonstantin Belousov * Check to see if we are in the parent or child 49*74a2bf1bSKonstantin Belousov */ 50*74a2bf1bSKonstantin Belousov cmpl $0, %edx 51*74a2bf1bSKonstantin Belousov jnz 1f 52*74a2bf1bSKonstantin Belousov popq %r13 53*74a2bf1bSKonstantin Belousov popq %r12 54*74a2bf1bSKonstantin Belousov popq %rbx 55*74a2bf1bSKonstantin Belousov ret 56*74a2bf1bSKonstantin Belousov 57*74a2bf1bSKonstantin Belousov /* 58*74a2bf1bSKonstantin Belousov * If we are in the child (new thread), then 59*74a2bf1bSKonstantin Belousov * set-up the call to the internal subroutine. If it 60*74a2bf1bSKonstantin Belousov * returns, then call __exit. 61*74a2bf1bSKonstantin Belousov */ 62*74a2bf1bSKonstantin Belousov1: 63*74a2bf1bSKonstantin Belousov movq %r13, %rsp 64*74a2bf1bSKonstantin Belousov movq %r12, %rdi 65*74a2bf1bSKonstantin Belousov call *%rbx 66*74a2bf1bSKonstantin Belousov movl %eax, %edi 67*74a2bf1bSKonstantin Belousov 68*74a2bf1bSKonstantin Belousov /* 69*74a2bf1bSKonstantin Belousov * Exit system call 70*74a2bf1bSKonstantin Belousov */ 71*74a2bf1bSKonstantin Belousov _SYSCALL(exit) 72*74a2bf1bSKonstantin Belousov 73*74a2bf1bSKonstantin Belousov /* 74*74a2bf1bSKonstantin Belousov * Branch here if the thread creation fails: 75*74a2bf1bSKonstantin Belousov */ 76*74a2bf1bSKonstantin Belousov2: 77*74a2bf1bSKonstantin Belousov popq %r13 78*74a2bf1bSKonstantin Belousov popq %r12 79*74a2bf1bSKonstantin Belousov popq %rbx 80*74a2bf1bSKonstantin Belousov jmp HIDENAME(cerror) 81*74a2bf1bSKonstantin BelousovEND(pdrfork_thread) 82*74a2bf1bSKonstantin Belousov 83*74a2bf1bSKonstantin Belousov .section .note.GNU-stack,"",%progbits 84