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 6ad2056f2SAlexander Leidinger * All rights reserved. 71ca6b15bSDmitry Chagin * Copyright (c) 2013 Dmitry Chagin <dchagin@FreeBSD.org> 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 1181c34dcb5SEdward Tomasz Napierala /* 1191c34dcb5SEdward Tomasz Napierala * The default stack size limit in Linux is 8MB. 1201c34dcb5SEdward Tomasz Napierala */ 1211c34dcb5SEdward Tomasz Napierala static void 1221c34dcb5SEdward Tomasz Napierala linux_set_default_stacksize(struct thread *td, struct proc *p) 1231c34dcb5SEdward Tomasz Napierala { 1241c34dcb5SEdward Tomasz Napierala struct rlimit rlim; 1251c34dcb5SEdward Tomasz Napierala int error; 1261c34dcb5SEdward Tomasz Napierala 1271c34dcb5SEdward Tomasz Napierala if (linux_default_stacksize < 0) 1281c34dcb5SEdward Tomasz Napierala return; 1291c34dcb5SEdward Tomasz Napierala 1301c34dcb5SEdward Tomasz Napierala PROC_LOCK(p); 1311c34dcb5SEdward Tomasz Napierala lim_rlimit_proc(p, RLIMIT_STACK, &rlim); 1321c34dcb5SEdward Tomasz Napierala PROC_UNLOCK(p); 1331c34dcb5SEdward Tomasz Napierala if (rlim.rlim_cur != rlim.rlim_max || 1341c34dcb5SEdward Tomasz Napierala rlim.rlim_cur <= linux_default_stacksize) 1351c34dcb5SEdward Tomasz Napierala return; 1361c34dcb5SEdward Tomasz Napierala rlim.rlim_cur = linux_default_stacksize; 1371c34dcb5SEdward Tomasz Napierala error = kern_proc_setrlimit(td, p, RLIMIT_STACK, &rlim); 1381c34dcb5SEdward Tomasz Napierala KASSERT(error == 0, ("kern_proc_setrlimit failed")); 1391c34dcb5SEdward Tomasz Napierala } 1401c34dcb5SEdward Tomasz Napierala 14181338031SDmitry Chagin void 1420a4b664aSDmitry Chagin linux_proc_init(struct thread *td, struct thread *newtd, bool init_thread) 143ad2056f2SAlexander Leidinger { 14481338031SDmitry Chagin struct linux_emuldata *em; 145bc273677SDmitry Chagin struct linux_pemuldata *pem; 14668cf0367SDmitry Chagin struct proc *p; 14719e252baSAlexander Leidinger 14881338031SDmitry Chagin if (newtd != NULL) { 14968cf0367SDmitry Chagin p = newtd->td_proc; 15068cf0367SDmitry Chagin 15181338031SDmitry Chagin /* non-exec call */ 15281338031SDmitry Chagin em = malloc(sizeof(*em), M_TEMP, M_WAITOK | M_ZERO); 1530a4b664aSDmitry Chagin if (init_thread) { 154e16fe1c7SDmitry Chagin LINUX_CTR1(proc_init, "thread newtd(%d)", 155e16fe1c7SDmitry Chagin newtd->td_tid); 156e16fe1c7SDmitry Chagin 15781338031SDmitry Chagin em->em_tid = newtd->td_tid; 15881338031SDmitry Chagin } else { 15968cf0367SDmitry Chagin LINUX_CTR1(proc_init, "fork newtd(%d)", p->p_pid); 16019e252baSAlexander Leidinger 16168cf0367SDmitry Chagin em->em_tid = p->p_pid; 162bc273677SDmitry Chagin 163e0d3ea8cSDmitry Chagin pem = malloc(sizeof(*pem), M_LINUX, M_WAITOK | M_ZERO); 164bc273677SDmitry Chagin sx_init(&pem->pem_sx, "lpemlk"); 16568cf0367SDmitry Chagin p->p_emuldata = pem; 166ad2056f2SAlexander Leidinger } 16781338031SDmitry Chagin newtd->td_emuldata = em; 1688c5059e9SEdward Tomasz Napierala 1698c5059e9SEdward Tomasz Napierala linux_set_default_openfiles(td, p); 1701c34dcb5SEdward Tomasz Napierala linux_set_default_stacksize(td, p); 171ad2056f2SAlexander Leidinger } else { 17268cf0367SDmitry Chagin p = td->td_proc; 17368cf0367SDmitry Chagin 17419e252baSAlexander Leidinger /* exec */ 17568cf0367SDmitry Chagin LINUX_CTR1(proc_init, "exec newtd(%d)", p->p_pid); 17619e252baSAlexander Leidinger 177ad2056f2SAlexander Leidinger /* lookup the old one */ 17881338031SDmitry Chagin em = em_find(td); 179ad2056f2SAlexander Leidinger KASSERT(em != NULL, ("proc_init: emuldata not found in exec case.\n")); 18081338031SDmitry Chagin 18168cf0367SDmitry Chagin em->em_tid = p->p_pid; 18297cfa5c8SDmitry Chagin em->flags = 0; 18397cfa5c8SDmitry Chagin em->robust_futexes = NULL; 18497cfa5c8SDmitry Chagin em->child_clear_tid = NULL; 18597cfa5c8SDmitry Chagin em->child_set_tid = NULL; 186e16fe1c7SDmitry Chagin 18768cf0367SDmitry Chagin pem = pem_find(p); 188e16fe1c7SDmitry Chagin KASSERT(pem != NULL, ("proc_exit: proc emuldata not found.\n")); 18923e8912cSDmitry Chagin pem->persona = 0; 190ad2056f2SAlexander Leidinger } 191ad2056f2SAlexander Leidinger 192ad2056f2SAlexander Leidinger } 193ad2056f2SAlexander Leidinger 194ad2056f2SAlexander Leidinger void 1954815f175SKonstantin Belousov linux_on_exit(struct proc *p) 196ad2056f2SAlexander Leidinger { 197bc273677SDmitry Chagin struct linux_pemuldata *pem; 19881338031SDmitry Chagin struct thread *td = curthread; 199ad2056f2SAlexander Leidinger 2004815f175SKonstantin Belousov MPASS(SV_CURPROC_ABI() == SV_ABI_LINUX); 201bc273677SDmitry Chagin 2027d96520bSDmitry Chagin LINUX_CTR3(proc_exit, "thread(%d) proc(%d) p %p", 2037d96520bSDmitry Chagin td->td_tid, p->p_pid, p); 2047d96520bSDmitry Chagin 205bc273677SDmitry Chagin pem = pem_find(p); 206bc273677SDmitry Chagin if (pem == NULL) 207bc273677SDmitry Chagin return; 20881338031SDmitry Chagin (p->p_sysent->sv_thread_detach)(td); 209bc273677SDmitry Chagin 210bc273677SDmitry Chagin p->p_emuldata = NULL; 211bc273677SDmitry Chagin 212bc273677SDmitry Chagin sx_destroy(&pem->pem_sx); 213e0d3ea8cSDmitry Chagin free(pem, M_LINUX); 214e8b8b834SAlexander Leidinger } 215ad2056f2SAlexander Leidinger 216b267239dSEd Maste /* 217b267239dSEd Maste * If a Linux binary is exec'ing something, try this image activator 218b267239dSEd Maste * first. We override standard shell script execution in order to 219b267239dSEd Maste * be able to modify the interpreter path. We only do this if a Linux 220b267239dSEd Maste * binary is doing the exec, so we do not create an EXEC module for it. 221b267239dSEd Maste */ 222b267239dSEd Maste int 223b267239dSEd Maste linux_exec_imgact_try(struct image_params *imgp) 224b267239dSEd Maste { 225b267239dSEd Maste const char *head = (const char *)imgp->image_header; 226b267239dSEd Maste char *rpath; 227b267239dSEd Maste int error = -1; 228b267239dSEd Maste 229b267239dSEd Maste /* 230b267239dSEd Maste * The interpreter for shell scripts run from a Linux binary needs 231b267239dSEd Maste * to be located in /compat/linux if possible in order to recursively 232b267239dSEd Maste * maintain Linux path emulation. 233b267239dSEd Maste */ 234b267239dSEd Maste if (((const short *)head)[0] == SHELLMAGIC) { 235b267239dSEd Maste /* 236b267239dSEd Maste * Run our normal shell image activator. If it succeeds attempt 237b267239dSEd Maste * to use the alternate path for the interpreter. If an 238b267239dSEd Maste * alternate path is found, use our stringspace to store it. 239b267239dSEd Maste */ 240b267239dSEd Maste if ((error = exec_shell_imgact(imgp)) == 0) { 241b267239dSEd Maste linux_emul_convpath(FIRST_THREAD_IN_PROC(imgp->proc), 242b267239dSEd Maste imgp->interpreter_name, UIO_SYSSPACE, &rpath, 0, 243b267239dSEd Maste AT_FDCWD); 244b267239dSEd Maste if (rpath != NULL) 245b267239dSEd Maste imgp->args->fname_buf = 246b267239dSEd Maste imgp->interpreter_name = rpath; 247b267239dSEd Maste } 248b267239dSEd Maste } 249b267239dSEd Maste return (error); 250b267239dSEd Maste } 251b267239dSEd Maste 25281338031SDmitry Chagin int 25381338031SDmitry Chagin linux_common_execve(struct thread *td, struct image_args *eargs) 25481338031SDmitry Chagin { 255bc273677SDmitry Chagin struct linux_pemuldata *pem; 256d707582fSDmitry Chagin struct vmspace *oldvmspace; 25781338031SDmitry Chagin struct linux_emuldata *em; 25881338031SDmitry Chagin struct proc *p; 25981338031SDmitry Chagin int error; 260ad2056f2SAlexander Leidinger 26181338031SDmitry Chagin p = td->td_proc; 262ad2056f2SAlexander Leidinger 263d707582fSDmitry Chagin error = pre_execve(td, &oldvmspace); 264d707582fSDmitry Chagin if (error != 0) 265d707582fSDmitry Chagin return (error); 26681338031SDmitry Chagin 267aaf78c16SKonstantin Belousov error = kern_execve(td, eargs, NULL, oldvmspace); 268d707582fSDmitry Chagin post_execve(td, error, oldvmspace); 269814629ddSEd Schouten if (error != EJUSTRETURN) 27081338031SDmitry Chagin return (error); 27181338031SDmitry Chagin 27281338031SDmitry Chagin /* 27381338031SDmitry Chagin * In a case of transition from Linux binary execing to 274eae594f7SEd Maste * FreeBSD binary we destroy Linux emuldata thread & proc entries. 27581338031SDmitry Chagin */ 27681338031SDmitry Chagin if (SV_CURPROC_ABI() != SV_ABI_LINUX) { 27781338031SDmitry Chagin PROC_LOCK(p); 27881338031SDmitry Chagin em = em_find(td); 279bc273677SDmitry Chagin KASSERT(em != NULL, ("proc_exec: thread emuldata not found.\n")); 28081338031SDmitry Chagin td->td_emuldata = NULL; 281bc273677SDmitry Chagin 282bc273677SDmitry Chagin pem = pem_find(p); 283bc273677SDmitry Chagin KASSERT(pem != NULL, ("proc_exec: proc pemuldata not found.\n")); 284bc273677SDmitry Chagin p->p_emuldata = NULL; 28581338031SDmitry Chagin PROC_UNLOCK(p); 28681338031SDmitry Chagin 28781338031SDmitry Chagin free(em, M_TEMP); 288e0d3ea8cSDmitry Chagin free(pem, M_LINUX); 28981338031SDmitry Chagin } 290814629ddSEd Schouten return (EJUSTRETURN); 29181338031SDmitry Chagin } 29281338031SDmitry Chagin 29381338031SDmitry Chagin void 2944815f175SKonstantin Belousov linux_on_exec(struct proc *p, struct image_params *imgp) 29581338031SDmitry Chagin { 2968a15ac83SKonstantin Belousov struct thread *td; 29732ba368bSDmitry Chagin struct thread *othertd; 29823e8912cSDmitry Chagin #if defined(__amd64__) 29923e8912cSDmitry Chagin struct linux_pemuldata *pem; 30023e8912cSDmitry Chagin #endif 30132ba368bSDmitry Chagin 3028a15ac83SKonstantin Belousov td = curthread; 3034815f175SKonstantin Belousov MPASS((imgp->sysent->sv_flags & SV_ABI_MASK) == SV_ABI_LINUX); 30481338031SDmitry Chagin 30581338031SDmitry Chagin /* 3064815f175SKonstantin Belousov * When execing to Linux binary, we create Linux emuldata 3074815f175SKonstantin Belousov * thread entry. 30881338031SDmitry Chagin */ 3098a15ac83SKonstantin Belousov if (SV_PROC_ABI(p) == SV_ABI_LINUX) { 3108a15ac83SKonstantin Belousov /* 3118a15ac83SKonstantin Belousov * Process already was under Linuxolator 3128a15ac83SKonstantin Belousov * before exec. Update emuldata to reflect 3138a15ac83SKonstantin Belousov * single-threaded cleaned state after exec. 3148a15ac83SKonstantin Belousov */ 3150a4b664aSDmitry Chagin linux_proc_init(td, NULL, false); 3168a15ac83SKonstantin Belousov } else { 3178a15ac83SKonstantin Belousov /* 3188a15ac83SKonstantin Belousov * We are switching the process to Linux emulator. 3198a15ac83SKonstantin Belousov */ 3200a4b664aSDmitry Chagin linux_proc_init(td, td, false); 3218a15ac83SKonstantin Belousov 3228a15ac83SKonstantin Belousov /* 3238a15ac83SKonstantin Belousov * Create a transient td_emuldata for all suspended 3248a15ac83SKonstantin Belousov * threads, so that p->p_sysent->sv_thread_detach() == 3258a15ac83SKonstantin Belousov * linux_thread_detach() can find expected but unused 3268a15ac83SKonstantin Belousov * emuldata. 3278a15ac83SKonstantin Belousov */ 3288a15ac83SKonstantin Belousov FOREACH_THREAD_IN_PROC(td->td_proc, othertd) { 3294815f175SKonstantin Belousov if (othertd == td) 3304815f175SKonstantin Belousov continue; 3310a4b664aSDmitry Chagin linux_proc_init(td, othertd, true); 3328a15ac83SKonstantin Belousov } 3338a15ac83SKonstantin 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 void 3484815f175SKonstantin Belousov linux_thread_dtor(struct thread *td) 349ad2056f2SAlexander Leidinger { 350ad2056f2SAlexander Leidinger struct linux_emuldata *em; 351ad2056f2SAlexander Leidinger 35281338031SDmitry Chagin em = em_find(td); 35381338031SDmitry Chagin if (em == NULL) 35481338031SDmitry Chagin return; 35581338031SDmitry Chagin td->td_emuldata = NULL; 356ad2056f2SAlexander Leidinger 3577d96520bSDmitry Chagin LINUX_CTR1(thread_dtor, "thread(%d)", em->em_tid); 358ad2056f2SAlexander Leidinger 35981338031SDmitry Chagin free(em, M_TEMP); 360ad2056f2SAlexander Leidinger } 361ad2056f2SAlexander Leidinger 362ad2056f2SAlexander Leidinger void 363e5d81ef1SDmitry Chagin linux_schedtail(struct thread *td) 364ad2056f2SAlexander Leidinger { 365ad2056f2SAlexander Leidinger struct linux_emuldata *em; 366*74a0e24fSMateusz Guzik #ifdef KTR 367*74a0e24fSMateusz Guzik int error; 368*74a0e24fSMateusz Guzik #else 369*74a0e24fSMateusz Guzik int error __unused; 370*74a0e24fSMateusz Guzik #endif 371ad2056f2SAlexander Leidinger int *child_set_tid; 372ad2056f2SAlexander Leidinger 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