1ad2056f2SAlexander Leidinger /*- 2023b850bSEd Maste * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 37f2d13d6SPedro F. Giffuni * 4b267239dSEd Maste * Copyright (c) 1994-1996 Søren Schmidt 5ad2056f2SAlexander Leidinger * Copyright (c) 2006 Roman Divacky 681338031SDmitry Chagin * Copyright (c) 2013 Dmitry Chagin 7ad2056f2SAlexander Leidinger * All rights reserved. 8ad2056f2SAlexander Leidinger * 9ad2056f2SAlexander Leidinger * Redistribution and use in source and binary forms, with or without 10ad2056f2SAlexander Leidinger * modification, are permitted provided that the following conditions 11ad2056f2SAlexander Leidinger * are met: 12ad2056f2SAlexander Leidinger * 1. Redistributions of source code must retain the above copyright 13023b850bSEd Maste * notice, this list of conditions and the following disclaimer. 14ad2056f2SAlexander Leidinger * 2. Redistributions in binary form must reproduce the above copyright 15ad2056f2SAlexander Leidinger * notice, this list of conditions and the following disclaimer in the 16ad2056f2SAlexander Leidinger * documentation and/or other materials provided with the distribution. 17ad2056f2SAlexander Leidinger * 18023b850bSEd Maste * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19023b850bSEd Maste * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20023b850bSEd Maste * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21023b850bSEd Maste * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22023b850bSEd Maste * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23023b850bSEd Maste * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24023b850bSEd Maste * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25023b850bSEd Maste * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26023b850bSEd Maste * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27023b850bSEd Maste * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28023b850bSEd Maste * SUCH DAMAGE. 29ad2056f2SAlexander Leidinger */ 30ad2056f2SAlexander Leidinger 31ad2056f2SAlexander Leidinger #include <sys/cdefs.h> 32ad2056f2SAlexander Leidinger __FBSDID("$FreeBSD$"); 33ad2056f2SAlexander Leidinger 34ad2056f2SAlexander Leidinger #include <sys/param.h> 35ad2056f2SAlexander Leidinger #include <sys/systm.h> 36b267239dSEd Maste #include <sys/fcntl.h> 37ad2056f2SAlexander Leidinger #include <sys/imgact.h> 38b4bb5154SKonstantin Belousov #include <sys/kernel.h> 3981338031SDmitry Chagin #include <sys/ktr.h> 40ad2056f2SAlexander Leidinger #include <sys/lock.h> 41ad2056f2SAlexander Leidinger #include <sys/malloc.h> 42ad2056f2SAlexander Leidinger #include <sys/mutex.h> 43ad2056f2SAlexander Leidinger #include <sys/sx.h> 44ad2056f2SAlexander Leidinger #include <sys/proc.h> 458c5059e9SEdward Tomasz Napierala #include <sys/resourcevar.h> 46ad2056f2SAlexander Leidinger #include <sys/syscallsubr.h> 4795353459SDimitry Andric #include <sys/sysent.h> 48ad2056f2SAlexander Leidinger 494732e446SRoman Divacky #include <compat/linux/linux_emul.h> 508c5059e9SEdward Tomasz Napierala #include <compat/linux/linux_mib.h> 51d825ce0aSJohn Baldwin #include <compat/linux/linux_misc.h> 5223e8912cSDmitry Chagin #include <compat/linux/linux_persona.h> 5381338031SDmitry Chagin #include <compat/linux/linux_util.h> 544732e446SRoman Divacky 55b267239dSEd Maste #if BYTE_ORDER == LITTLE_ENDIAN 56b267239dSEd Maste #define SHELLMAGIC 0x2123 /* #! */ 57b267239dSEd Maste #else 58b267239dSEd Maste #define SHELLMAGIC 0x2321 59b267239dSEd Maste #endif 6019e252baSAlexander Leidinger 6181338031SDmitry Chagin /* 62bc273677SDmitry Chagin * This returns reference to the thread emuldata entry (if found) 6381338031SDmitry Chagin * 6481338031SDmitry Chagin * Hold PROC_LOCK when referencing emuldata from other threads. 6581338031SDmitry Chagin */ 66ad2056f2SAlexander Leidinger struct linux_emuldata * 6781338031SDmitry Chagin em_find(struct thread *td) 68ad2056f2SAlexander Leidinger { 69ad2056f2SAlexander Leidinger struct linux_emuldata *em; 70ad2056f2SAlexander Leidinger 7181338031SDmitry Chagin em = td->td_emuldata; 72ad2056f2SAlexander Leidinger 73ad2056f2SAlexander Leidinger return (em); 74ad2056f2SAlexander Leidinger } 75ad2056f2SAlexander Leidinger 76bc273677SDmitry Chagin /* 77bc273677SDmitry Chagin * This returns reference to the proc pemuldata entry (if found) 78bc273677SDmitry Chagin * 79bc273677SDmitry Chagin * Hold PROC_LOCK when referencing proc pemuldata from other threads. 80bc273677SDmitry Chagin * Hold LINUX_PEM_LOCK wher referencing pemuldata members. 81bc273677SDmitry Chagin */ 82bc273677SDmitry Chagin struct linux_pemuldata * 83bc273677SDmitry Chagin pem_find(struct proc *p) 84bc273677SDmitry Chagin { 85bc273677SDmitry Chagin struct linux_pemuldata *pem; 86bc273677SDmitry Chagin 87bc273677SDmitry Chagin pem = p->p_emuldata; 88bc273677SDmitry Chagin 89bc273677SDmitry Chagin return (pem); 90bc273677SDmitry Chagin } 91bc273677SDmitry Chagin 928c5059e9SEdward Tomasz Napierala /* 938c5059e9SEdward Tomasz Napierala * Linux apps generally expect the soft open file limit to be set 948c5059e9SEdward Tomasz Napierala * to 1024, often iterating over all the file descriptors up to that 958c5059e9SEdward Tomasz Napierala * limit instead of using closefrom(2). Give them what they want, 968c5059e9SEdward Tomasz Napierala * unless there already is a resource limit in place. 978c5059e9SEdward Tomasz Napierala */ 988c5059e9SEdward Tomasz Napierala static void 998c5059e9SEdward Tomasz Napierala linux_set_default_openfiles(struct thread *td, struct proc *p) 1008c5059e9SEdward Tomasz Napierala { 1018c5059e9SEdward Tomasz Napierala struct rlimit rlim; 1028c5059e9SEdward Tomasz Napierala int error; 1038c5059e9SEdward Tomasz Napierala 1048c5059e9SEdward Tomasz Napierala if (linux_default_openfiles < 0) 1058c5059e9SEdward Tomasz Napierala return; 1068c5059e9SEdward Tomasz Napierala 1078c5059e9SEdward Tomasz Napierala PROC_LOCK(p); 1088c5059e9SEdward Tomasz Napierala lim_rlimit_proc(p, RLIMIT_NOFILE, &rlim); 1098c5059e9SEdward Tomasz Napierala PROC_UNLOCK(p); 1108c5059e9SEdward Tomasz Napierala if (rlim.rlim_cur != rlim.rlim_max || 1118c5059e9SEdward Tomasz Napierala rlim.rlim_cur <= linux_default_openfiles) 1128c5059e9SEdward Tomasz Napierala return; 1138c5059e9SEdward Tomasz Napierala rlim.rlim_cur = linux_default_openfiles; 1148c5059e9SEdward Tomasz Napierala error = kern_proc_setrlimit(td, p, RLIMIT_NOFILE, &rlim); 1158c5059e9SEdward Tomasz Napierala KASSERT(error == 0, ("kern_proc_setrlimit failed")); 1168c5059e9SEdward Tomasz Napierala } 1178c5059e9SEdward Tomasz Napierala 11881338031SDmitry Chagin void 11981338031SDmitry Chagin linux_proc_init(struct thread *td, struct thread *newtd, int flags) 120ad2056f2SAlexander Leidinger { 12181338031SDmitry Chagin struct linux_emuldata *em; 122bc273677SDmitry Chagin struct linux_pemuldata *pem; 123e16fe1c7SDmitry Chagin struct epoll_emuldata *emd; 12468cf0367SDmitry Chagin struct proc *p; 12519e252baSAlexander Leidinger 12681338031SDmitry Chagin if (newtd != NULL) { 12768cf0367SDmitry Chagin p = newtd->td_proc; 12868cf0367SDmitry Chagin 12981338031SDmitry Chagin /* non-exec call */ 13081338031SDmitry Chagin em = malloc(sizeof(*em), M_TEMP, M_WAITOK | M_ZERO); 131a4e3bad7SJung-uk Kim if (flags & LINUX_CLONE_THREAD) { 132e16fe1c7SDmitry Chagin LINUX_CTR1(proc_init, "thread newtd(%d)", 133e16fe1c7SDmitry Chagin newtd->td_tid); 134e16fe1c7SDmitry Chagin 13581338031SDmitry Chagin em->em_tid = newtd->td_tid; 13681338031SDmitry Chagin } else { 13768cf0367SDmitry Chagin LINUX_CTR1(proc_init, "fork newtd(%d)", p->p_pid); 13819e252baSAlexander Leidinger 13968cf0367SDmitry Chagin em->em_tid = p->p_pid; 140bc273677SDmitry Chagin 141e0d3ea8cSDmitry Chagin pem = malloc(sizeof(*pem), M_LINUX, M_WAITOK | M_ZERO); 142bc273677SDmitry Chagin sx_init(&pem->pem_sx, "lpemlk"); 14368cf0367SDmitry Chagin p->p_emuldata = pem; 144ad2056f2SAlexander Leidinger } 14581338031SDmitry Chagin newtd->td_emuldata = em; 1468c5059e9SEdward Tomasz Napierala 1478c5059e9SEdward Tomasz Napierala linux_set_default_openfiles(td, p); 148ad2056f2SAlexander Leidinger } else { 14968cf0367SDmitry Chagin p = td->td_proc; 15068cf0367SDmitry Chagin 15119e252baSAlexander Leidinger /* exec */ 15268cf0367SDmitry Chagin LINUX_CTR1(proc_init, "exec newtd(%d)", p->p_pid); 15319e252baSAlexander Leidinger 154ad2056f2SAlexander Leidinger /* lookup the old one */ 15581338031SDmitry Chagin em = em_find(td); 156ad2056f2SAlexander Leidinger KASSERT(em != NULL, ("proc_init: emuldata not found in exec case.\n")); 15781338031SDmitry Chagin 15868cf0367SDmitry Chagin em->em_tid = p->p_pid; 15997cfa5c8SDmitry Chagin em->flags = 0; 16097cfa5c8SDmitry Chagin em->robust_futexes = NULL; 16197cfa5c8SDmitry Chagin em->child_clear_tid = NULL; 16297cfa5c8SDmitry Chagin em->child_set_tid = NULL; 163e16fe1c7SDmitry Chagin 164e16fe1c7SDmitry Chagin /* epoll should be destroyed in a case of exec. */ 16568cf0367SDmitry Chagin pem = pem_find(p); 166e16fe1c7SDmitry Chagin KASSERT(pem != NULL, ("proc_exit: proc emuldata not found.\n")); 16723e8912cSDmitry Chagin pem->persona = 0; 168e16fe1c7SDmitry Chagin if (pem->epoll != NULL) { 169e16fe1c7SDmitry Chagin emd = pem->epoll; 170e16fe1c7SDmitry Chagin pem->epoll = NULL; 171e16fe1c7SDmitry Chagin free(emd, M_EPOLL); 172e16fe1c7SDmitry Chagin } 173ad2056f2SAlexander Leidinger } 174ad2056f2SAlexander Leidinger 175ad2056f2SAlexander Leidinger } 176ad2056f2SAlexander Leidinger 177ad2056f2SAlexander Leidinger void 178ad2056f2SAlexander Leidinger linux_proc_exit(void *arg __unused, struct proc *p) 179ad2056f2SAlexander Leidinger { 180bc273677SDmitry Chagin struct linux_pemuldata *pem; 181e16fe1c7SDmitry Chagin struct epoll_emuldata *emd; 18281338031SDmitry Chagin struct thread *td = curthread; 183ad2056f2SAlexander Leidinger 184bc273677SDmitry Chagin if (__predict_false(SV_CURPROC_ABI() != SV_ABI_LINUX)) 185bc273677SDmitry Chagin return; 186bc273677SDmitry Chagin 1877d96520bSDmitry Chagin LINUX_CTR3(proc_exit, "thread(%d) proc(%d) p %p", 1887d96520bSDmitry Chagin td->td_tid, p->p_pid, p); 1897d96520bSDmitry Chagin 190bc273677SDmitry Chagin pem = pem_find(p); 191bc273677SDmitry Chagin if (pem == NULL) 192bc273677SDmitry Chagin return; 19381338031SDmitry Chagin (p->p_sysent->sv_thread_detach)(td); 194bc273677SDmitry Chagin 195bc273677SDmitry Chagin p->p_emuldata = NULL; 196bc273677SDmitry Chagin 197e16fe1c7SDmitry Chagin if (pem->epoll != NULL) { 198e16fe1c7SDmitry Chagin emd = pem->epoll; 199e16fe1c7SDmitry Chagin pem->epoll = NULL; 200e16fe1c7SDmitry Chagin free(emd, M_EPOLL); 201e16fe1c7SDmitry Chagin } 202e16fe1c7SDmitry Chagin 203bc273677SDmitry Chagin sx_destroy(&pem->pem_sx); 204e0d3ea8cSDmitry Chagin free(pem, M_LINUX); 205e8b8b834SAlexander Leidinger } 206ad2056f2SAlexander Leidinger 207b267239dSEd Maste /* 208b267239dSEd Maste * If a Linux binary is exec'ing something, try this image activator 209b267239dSEd Maste * first. We override standard shell script execution in order to 210b267239dSEd Maste * be able to modify the interpreter path. We only do this if a Linux 211b267239dSEd Maste * binary is doing the exec, so we do not create an EXEC module for it. 212b267239dSEd Maste */ 213b267239dSEd Maste int 214b267239dSEd Maste linux_exec_imgact_try(struct image_params *imgp) 215b267239dSEd Maste { 216b267239dSEd Maste const char *head = (const char *)imgp->image_header; 217b267239dSEd Maste char *rpath; 218b267239dSEd Maste int error = -1; 219b267239dSEd Maste 220b267239dSEd Maste /* 221b267239dSEd Maste * The interpreter for shell scripts run from a Linux binary needs 222b267239dSEd Maste * to be located in /compat/linux if possible in order to recursively 223b267239dSEd Maste * maintain Linux path emulation. 224b267239dSEd Maste */ 225b267239dSEd Maste if (((const short *)head)[0] == SHELLMAGIC) { 226b267239dSEd Maste /* 227b267239dSEd Maste * Run our normal shell image activator. If it succeeds attempt 228b267239dSEd Maste * to use the alternate path for the interpreter. If an 229b267239dSEd Maste * alternate path is found, use our stringspace to store it. 230b267239dSEd Maste */ 231b267239dSEd Maste if ((error = exec_shell_imgact(imgp)) == 0) { 232b267239dSEd Maste linux_emul_convpath(FIRST_THREAD_IN_PROC(imgp->proc), 233b267239dSEd Maste imgp->interpreter_name, UIO_SYSSPACE, &rpath, 0, 234b267239dSEd Maste AT_FDCWD); 235b267239dSEd Maste if (rpath != NULL) 236b267239dSEd Maste imgp->args->fname_buf = 237b267239dSEd Maste imgp->interpreter_name = rpath; 238b267239dSEd Maste } 239b267239dSEd Maste } 240b267239dSEd Maste return (error); 241b267239dSEd Maste } 242b267239dSEd Maste 24381338031SDmitry Chagin int 24481338031SDmitry Chagin linux_common_execve(struct thread *td, struct image_args *eargs) 24581338031SDmitry Chagin { 246bc273677SDmitry Chagin struct linux_pemuldata *pem; 247e16fe1c7SDmitry Chagin struct epoll_emuldata *emd; 248d707582fSDmitry Chagin struct vmspace *oldvmspace; 24981338031SDmitry Chagin struct linux_emuldata *em; 25081338031SDmitry Chagin struct proc *p; 25181338031SDmitry Chagin int error; 252ad2056f2SAlexander Leidinger 25381338031SDmitry Chagin p = td->td_proc; 254ad2056f2SAlexander Leidinger 255d707582fSDmitry Chagin error = pre_execve(td, &oldvmspace); 256d707582fSDmitry Chagin if (error != 0) 257d707582fSDmitry Chagin return (error); 25881338031SDmitry Chagin 25981338031SDmitry Chagin error = kern_execve(td, eargs, NULL); 260d707582fSDmitry Chagin post_execve(td, error, oldvmspace); 261814629ddSEd Schouten if (error != EJUSTRETURN) 26281338031SDmitry Chagin return (error); 26381338031SDmitry Chagin 26481338031SDmitry Chagin /* 26581338031SDmitry Chagin * In a case of transition from Linux binary execing to 266eae594f7SEd Maste * FreeBSD binary we destroy Linux emuldata thread & proc entries. 26781338031SDmitry Chagin */ 26881338031SDmitry Chagin if (SV_CURPROC_ABI() != SV_ABI_LINUX) { 26981338031SDmitry Chagin PROC_LOCK(p); 27081338031SDmitry Chagin em = em_find(td); 271bc273677SDmitry Chagin KASSERT(em != NULL, ("proc_exec: thread emuldata not found.\n")); 27281338031SDmitry Chagin td->td_emuldata = NULL; 273bc273677SDmitry Chagin 274bc273677SDmitry Chagin pem = pem_find(p); 275bc273677SDmitry Chagin KASSERT(pem != NULL, ("proc_exec: proc pemuldata not found.\n")); 276bc273677SDmitry Chagin p->p_emuldata = NULL; 27781338031SDmitry Chagin PROC_UNLOCK(p); 27881338031SDmitry Chagin 279e16fe1c7SDmitry Chagin if (pem->epoll != NULL) { 280e16fe1c7SDmitry Chagin emd = pem->epoll; 281e16fe1c7SDmitry Chagin pem->epoll = NULL; 282e16fe1c7SDmitry Chagin free(emd, M_EPOLL); 283e16fe1c7SDmitry Chagin } 284e16fe1c7SDmitry Chagin 28581338031SDmitry Chagin free(em, M_TEMP); 286e0d3ea8cSDmitry Chagin free(pem, M_LINUX); 28781338031SDmitry Chagin } 288814629ddSEd Schouten return (EJUSTRETURN); 28981338031SDmitry Chagin } 29081338031SDmitry Chagin 29181338031SDmitry Chagin void 29281338031SDmitry Chagin linux_proc_exec(void *arg __unused, struct proc *p, struct image_params *imgp) 29381338031SDmitry Chagin { 294*8a15ac83SKonstantin Belousov struct thread *td; 29532ba368bSDmitry Chagin struct thread *othertd; 29623e8912cSDmitry Chagin #if defined(__amd64__) 29723e8912cSDmitry Chagin struct linux_pemuldata *pem; 29823e8912cSDmitry Chagin #endif 29932ba368bSDmitry Chagin 300*8a15ac83SKonstantin Belousov td = curthread; 30181338031SDmitry Chagin 30281338031SDmitry Chagin /* 303eae594f7SEd Maste * In a case of execing to Linux binary we create Linux 30481338031SDmitry Chagin * emuldata thread entry. 30581338031SDmitry Chagin */ 30681338031SDmitry Chagin if (__predict_false((imgp->sysent->sv_flags & SV_ABI_MASK) == 30781338031SDmitry Chagin SV_ABI_LINUX)) { 308*8a15ac83SKonstantin Belousov if (SV_PROC_ABI(p) == SV_ABI_LINUX) { 309*8a15ac83SKonstantin Belousov /* 310*8a15ac83SKonstantin Belousov * Process already was under Linuxolator 311*8a15ac83SKonstantin Belousov * before exec. Update emuldata to reflect 312*8a15ac83SKonstantin Belousov * single-threaded cleaned state after exec. 313*8a15ac83SKonstantin Belousov */ 31481338031SDmitry Chagin linux_proc_init(td, NULL, 0); 315*8a15ac83SKonstantin Belousov } else { 316*8a15ac83SKonstantin Belousov /* 317*8a15ac83SKonstantin Belousov * We are switching the process to Linux emulator. 318*8a15ac83SKonstantin Belousov */ 31981338031SDmitry Chagin linux_proc_init(td, td, 0); 320*8a15ac83SKonstantin Belousov 321*8a15ac83SKonstantin Belousov /* 322*8a15ac83SKonstantin Belousov * Create a transient td_emuldata for all suspended 323*8a15ac83SKonstantin Belousov * threads, so that p->p_sysent->sv_thread_detach() == 324*8a15ac83SKonstantin Belousov * linux_thread_detach() can find expected but unused 325*8a15ac83SKonstantin Belousov * emuldata. 326*8a15ac83SKonstantin Belousov */ 327*8a15ac83SKonstantin Belousov FOREACH_THREAD_IN_PROC(td->td_proc, othertd) { 328*8a15ac83SKonstantin Belousov if (othertd != td) { 329*8a15ac83SKonstantin Belousov linux_proc_init(td, othertd, 330*8a15ac83SKonstantin Belousov LINUX_CLONE_THREAD); 331*8a15ac83SKonstantin Belousov } 332*8a15ac83SKonstantin Belousov } 333*8a15ac83SKonstantin Belousov } 33423e8912cSDmitry Chagin #if defined(__amd64__) 33523e8912cSDmitry Chagin /* 33623e8912cSDmitry Chagin * An IA32 executable which has executable stack will have the 33723e8912cSDmitry Chagin * READ_IMPLIES_EXEC personality flag set automatically. 33823e8912cSDmitry Chagin */ 33923e8912cSDmitry Chagin if (SV_PROC_FLAG(td->td_proc, SV_ILP32) && 34023e8912cSDmitry Chagin imgp->stack_prot & VM_PROT_EXECUTE) { 34123e8912cSDmitry Chagin pem = pem_find(p); 34223e8912cSDmitry Chagin pem->persona |= LINUX_READ_IMPLIES_EXEC; 34323e8912cSDmitry Chagin } 34423e8912cSDmitry Chagin #endif 34581338031SDmitry Chagin } 34681338031SDmitry Chagin } 34781338031SDmitry Chagin 34881338031SDmitry Chagin void 34981338031SDmitry Chagin linux_thread_dtor(void *arg __unused, struct thread *td) 350ad2056f2SAlexander Leidinger { 351ad2056f2SAlexander Leidinger struct linux_emuldata *em; 352ad2056f2SAlexander Leidinger 35381338031SDmitry Chagin em = em_find(td); 35481338031SDmitry Chagin if (em == NULL) 35581338031SDmitry Chagin return; 35681338031SDmitry Chagin td->td_emuldata = NULL; 357ad2056f2SAlexander Leidinger 3587d96520bSDmitry Chagin LINUX_CTR1(thread_dtor, "thread(%d)", em->em_tid); 359ad2056f2SAlexander Leidinger 36081338031SDmitry Chagin free(em, M_TEMP); 361ad2056f2SAlexander Leidinger } 362ad2056f2SAlexander Leidinger 363ad2056f2SAlexander Leidinger void 364e5d81ef1SDmitry Chagin linux_schedtail(struct thread *td) 365ad2056f2SAlexander Leidinger { 366ad2056f2SAlexander Leidinger struct linux_emuldata *em; 367e5d81ef1SDmitry Chagin struct proc *p; 368ad2056f2SAlexander Leidinger int error = 0; 369ad2056f2SAlexander Leidinger int *child_set_tid; 370ad2056f2SAlexander Leidinger 371e5d81ef1SDmitry Chagin p = td->td_proc; 372e5d81ef1SDmitry Chagin 37381338031SDmitry Chagin em = em_find(td); 374bc273677SDmitry Chagin KASSERT(em != NULL, ("linux_schedtail: thread emuldata not found.\n")); 375ad2056f2SAlexander Leidinger child_set_tid = em->child_set_tid; 376ad2056f2SAlexander Leidinger 37719e252baSAlexander Leidinger if (child_set_tid != NULL) { 378e0327ddbSDmitry Chagin error = copyout(&em->em_tid, child_set_tid, 37981338031SDmitry Chagin sizeof(em->em_tid)); 3807d96520bSDmitry Chagin LINUX_CTR4(schedtail, "thread(%d) %p stored %d error %d", 38181338031SDmitry Chagin td->td_tid, child_set_tid, em->em_tid, error); 38281338031SDmitry Chagin } else 3837d96520bSDmitry Chagin LINUX_CTR1(schedtail, "thread(%d)", em->em_tid); 384bb63fddeSAlexander Leidinger } 385