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 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 14281338031SDmitry Chagin linux_proc_init(struct thread *td, struct thread *newtd, int flags) 143ad2056f2SAlexander Leidinger { 14481338031SDmitry Chagin struct linux_emuldata *em; 145bc273677SDmitry Chagin struct linux_pemuldata *pem; 146e16fe1c7SDmitry Chagin struct epoll_emuldata *emd; 14768cf0367SDmitry Chagin struct proc *p; 14819e252baSAlexander Leidinger 14981338031SDmitry Chagin if (newtd != NULL) { 15068cf0367SDmitry Chagin p = newtd->td_proc; 15168cf0367SDmitry Chagin 15281338031SDmitry Chagin /* non-exec call */ 15381338031SDmitry Chagin em = malloc(sizeof(*em), M_TEMP, M_WAITOK | M_ZERO); 154a4e3bad7SJung-uk Kim if (flags & LINUX_CLONE_THREAD) { 155e16fe1c7SDmitry Chagin LINUX_CTR1(proc_init, "thread newtd(%d)", 156e16fe1c7SDmitry Chagin newtd->td_tid); 157e16fe1c7SDmitry Chagin 15881338031SDmitry Chagin em->em_tid = newtd->td_tid; 15981338031SDmitry Chagin } else { 16068cf0367SDmitry Chagin LINUX_CTR1(proc_init, "fork newtd(%d)", p->p_pid); 16119e252baSAlexander Leidinger 16268cf0367SDmitry Chagin em->em_tid = p->p_pid; 163bc273677SDmitry Chagin 164e0d3ea8cSDmitry Chagin pem = malloc(sizeof(*pem), M_LINUX, M_WAITOK | M_ZERO); 165bc273677SDmitry Chagin sx_init(&pem->pem_sx, "lpemlk"); 16668cf0367SDmitry Chagin p->p_emuldata = pem; 167ad2056f2SAlexander Leidinger } 16881338031SDmitry Chagin newtd->td_emuldata = em; 1698c5059e9SEdward Tomasz Napierala 1708c5059e9SEdward Tomasz Napierala linux_set_default_openfiles(td, p); 1711c34dcb5SEdward Tomasz Napierala linux_set_default_stacksize(td, p); 172ad2056f2SAlexander Leidinger } else { 17368cf0367SDmitry Chagin p = td->td_proc; 17468cf0367SDmitry Chagin 17519e252baSAlexander Leidinger /* exec */ 17668cf0367SDmitry Chagin LINUX_CTR1(proc_init, "exec newtd(%d)", p->p_pid); 17719e252baSAlexander Leidinger 178ad2056f2SAlexander Leidinger /* lookup the old one */ 17981338031SDmitry Chagin em = em_find(td); 180ad2056f2SAlexander Leidinger KASSERT(em != NULL, ("proc_init: emuldata not found in exec case.\n")); 18181338031SDmitry Chagin 18268cf0367SDmitry Chagin em->em_tid = p->p_pid; 18397cfa5c8SDmitry Chagin em->flags = 0; 18497cfa5c8SDmitry Chagin em->robust_futexes = NULL; 18597cfa5c8SDmitry Chagin em->child_clear_tid = NULL; 18697cfa5c8SDmitry Chagin em->child_set_tid = NULL; 187e16fe1c7SDmitry Chagin 188e16fe1c7SDmitry Chagin /* epoll should be destroyed in a case of exec. */ 18968cf0367SDmitry Chagin pem = pem_find(p); 190e16fe1c7SDmitry Chagin KASSERT(pem != NULL, ("proc_exit: proc emuldata not found.\n")); 19123e8912cSDmitry Chagin pem->persona = 0; 192e16fe1c7SDmitry Chagin if (pem->epoll != NULL) { 193e16fe1c7SDmitry Chagin emd = pem->epoll; 194e16fe1c7SDmitry Chagin pem->epoll = NULL; 195e16fe1c7SDmitry Chagin free(emd, M_EPOLL); 196e16fe1c7SDmitry Chagin } 197ad2056f2SAlexander Leidinger } 198ad2056f2SAlexander Leidinger 199ad2056f2SAlexander Leidinger } 200ad2056f2SAlexander Leidinger 201ad2056f2SAlexander Leidinger void 202*4815f175SKonstantin Belousov linux_on_exit(struct proc *p) 203ad2056f2SAlexander Leidinger { 204bc273677SDmitry Chagin struct linux_pemuldata *pem; 205e16fe1c7SDmitry Chagin struct epoll_emuldata *emd; 20681338031SDmitry Chagin struct thread *td = curthread; 207ad2056f2SAlexander Leidinger 208*4815f175SKonstantin Belousov MPASS(SV_CURPROC_ABI() == SV_ABI_LINUX); 209bc273677SDmitry Chagin 2107d96520bSDmitry Chagin LINUX_CTR3(proc_exit, "thread(%d) proc(%d) p %p", 2117d96520bSDmitry Chagin td->td_tid, p->p_pid, p); 2127d96520bSDmitry Chagin 213bc273677SDmitry Chagin pem = pem_find(p); 214bc273677SDmitry Chagin if (pem == NULL) 215bc273677SDmitry Chagin return; 21681338031SDmitry Chagin (p->p_sysent->sv_thread_detach)(td); 217bc273677SDmitry Chagin 218bc273677SDmitry Chagin p->p_emuldata = NULL; 219bc273677SDmitry Chagin 220e16fe1c7SDmitry Chagin if (pem->epoll != NULL) { 221e16fe1c7SDmitry Chagin emd = pem->epoll; 222e16fe1c7SDmitry Chagin pem->epoll = NULL; 223e16fe1c7SDmitry Chagin free(emd, M_EPOLL); 224e16fe1c7SDmitry Chagin } 225e16fe1c7SDmitry Chagin 226bc273677SDmitry Chagin sx_destroy(&pem->pem_sx); 227e0d3ea8cSDmitry Chagin free(pem, M_LINUX); 228e8b8b834SAlexander Leidinger } 229ad2056f2SAlexander Leidinger 230b267239dSEd Maste /* 231b267239dSEd Maste * If a Linux binary is exec'ing something, try this image activator 232b267239dSEd Maste * first. We override standard shell script execution in order to 233b267239dSEd Maste * be able to modify the interpreter path. We only do this if a Linux 234b267239dSEd Maste * binary is doing the exec, so we do not create an EXEC module for it. 235b267239dSEd Maste */ 236b267239dSEd Maste int 237b267239dSEd Maste linux_exec_imgact_try(struct image_params *imgp) 238b267239dSEd Maste { 239b267239dSEd Maste const char *head = (const char *)imgp->image_header; 240b267239dSEd Maste char *rpath; 241b267239dSEd Maste int error = -1; 242b267239dSEd Maste 243b267239dSEd Maste /* 244b267239dSEd Maste * The interpreter for shell scripts run from a Linux binary needs 245b267239dSEd Maste * to be located in /compat/linux if possible in order to recursively 246b267239dSEd Maste * maintain Linux path emulation. 247b267239dSEd Maste */ 248b267239dSEd Maste if (((const short *)head)[0] == SHELLMAGIC) { 249b267239dSEd Maste /* 250b267239dSEd Maste * Run our normal shell image activator. If it succeeds attempt 251b267239dSEd Maste * to use the alternate path for the interpreter. If an 252b267239dSEd Maste * alternate path is found, use our stringspace to store it. 253b267239dSEd Maste */ 254b267239dSEd Maste if ((error = exec_shell_imgact(imgp)) == 0) { 255b267239dSEd Maste linux_emul_convpath(FIRST_THREAD_IN_PROC(imgp->proc), 256b267239dSEd Maste imgp->interpreter_name, UIO_SYSSPACE, &rpath, 0, 257b267239dSEd Maste AT_FDCWD); 258b267239dSEd Maste if (rpath != NULL) 259b267239dSEd Maste imgp->args->fname_buf = 260b267239dSEd Maste imgp->interpreter_name = rpath; 261b267239dSEd Maste } 262b267239dSEd Maste } 263b267239dSEd Maste return (error); 264b267239dSEd Maste } 265b267239dSEd Maste 26681338031SDmitry Chagin int 26781338031SDmitry Chagin linux_common_execve(struct thread *td, struct image_args *eargs) 26881338031SDmitry Chagin { 269bc273677SDmitry Chagin struct linux_pemuldata *pem; 270e16fe1c7SDmitry Chagin struct epoll_emuldata *emd; 271d707582fSDmitry Chagin struct vmspace *oldvmspace; 27281338031SDmitry Chagin struct linux_emuldata *em; 27381338031SDmitry Chagin struct proc *p; 27481338031SDmitry Chagin int error; 275ad2056f2SAlexander Leidinger 27681338031SDmitry Chagin p = td->td_proc; 277ad2056f2SAlexander Leidinger 278d707582fSDmitry Chagin error = pre_execve(td, &oldvmspace); 279d707582fSDmitry Chagin if (error != 0) 280d707582fSDmitry Chagin return (error); 28181338031SDmitry Chagin 282aaf78c16SKonstantin Belousov error = kern_execve(td, eargs, NULL, oldvmspace); 283d707582fSDmitry Chagin post_execve(td, error, oldvmspace); 284814629ddSEd Schouten if (error != EJUSTRETURN) 28581338031SDmitry Chagin return (error); 28681338031SDmitry Chagin 28781338031SDmitry Chagin /* 28881338031SDmitry Chagin * In a case of transition from Linux binary execing to 289eae594f7SEd Maste * FreeBSD binary we destroy Linux emuldata thread & proc entries. 29081338031SDmitry Chagin */ 29181338031SDmitry Chagin if (SV_CURPROC_ABI() != SV_ABI_LINUX) { 29281338031SDmitry Chagin PROC_LOCK(p); 29381338031SDmitry Chagin em = em_find(td); 294bc273677SDmitry Chagin KASSERT(em != NULL, ("proc_exec: thread emuldata not found.\n")); 29581338031SDmitry Chagin td->td_emuldata = NULL; 296bc273677SDmitry Chagin 297bc273677SDmitry Chagin pem = pem_find(p); 298bc273677SDmitry Chagin KASSERT(pem != NULL, ("proc_exec: proc pemuldata not found.\n")); 299bc273677SDmitry Chagin p->p_emuldata = NULL; 30081338031SDmitry Chagin PROC_UNLOCK(p); 30181338031SDmitry Chagin 302e16fe1c7SDmitry Chagin if (pem->epoll != NULL) { 303e16fe1c7SDmitry Chagin emd = pem->epoll; 304e16fe1c7SDmitry Chagin pem->epoll = NULL; 305e16fe1c7SDmitry Chagin free(emd, M_EPOLL); 306e16fe1c7SDmitry Chagin } 307e16fe1c7SDmitry Chagin 30881338031SDmitry Chagin free(em, M_TEMP); 309e0d3ea8cSDmitry Chagin free(pem, M_LINUX); 31081338031SDmitry Chagin } 311814629ddSEd Schouten return (EJUSTRETURN); 31281338031SDmitry Chagin } 31381338031SDmitry Chagin 31481338031SDmitry Chagin void 315*4815f175SKonstantin Belousov linux_on_exec(struct proc *p, struct image_params *imgp) 31681338031SDmitry Chagin { 3178a15ac83SKonstantin Belousov struct thread *td; 31832ba368bSDmitry Chagin struct thread *othertd; 31923e8912cSDmitry Chagin #if defined(__amd64__) 32023e8912cSDmitry Chagin struct linux_pemuldata *pem; 32123e8912cSDmitry Chagin #endif 32232ba368bSDmitry Chagin 3238a15ac83SKonstantin Belousov td = curthread; 324*4815f175SKonstantin Belousov MPASS((imgp->sysent->sv_flags & SV_ABI_MASK) == SV_ABI_LINUX); 32581338031SDmitry Chagin 32681338031SDmitry Chagin /* 327*4815f175SKonstantin Belousov * When execing to Linux binary, we create Linux emuldata 328*4815f175SKonstantin Belousov * thread entry. 32981338031SDmitry Chagin */ 3308a15ac83SKonstantin Belousov if (SV_PROC_ABI(p) == SV_ABI_LINUX) { 3318a15ac83SKonstantin Belousov /* 3328a15ac83SKonstantin Belousov * Process already was under Linuxolator 3338a15ac83SKonstantin Belousov * before exec. Update emuldata to reflect 3348a15ac83SKonstantin Belousov * single-threaded cleaned state after exec. 3358a15ac83SKonstantin Belousov */ 33681338031SDmitry Chagin linux_proc_init(td, NULL, 0); 3378a15ac83SKonstantin Belousov } else { 3388a15ac83SKonstantin Belousov /* 3398a15ac83SKonstantin Belousov * We are switching the process to Linux emulator. 3408a15ac83SKonstantin Belousov */ 34181338031SDmitry Chagin linux_proc_init(td, td, 0); 3428a15ac83SKonstantin Belousov 3438a15ac83SKonstantin Belousov /* 3448a15ac83SKonstantin Belousov * Create a transient td_emuldata for all suspended 3458a15ac83SKonstantin Belousov * threads, so that p->p_sysent->sv_thread_detach() == 3468a15ac83SKonstantin Belousov * linux_thread_detach() can find expected but unused 3478a15ac83SKonstantin Belousov * emuldata. 3488a15ac83SKonstantin Belousov */ 3498a15ac83SKonstantin Belousov FOREACH_THREAD_IN_PROC(td->td_proc, othertd) { 350*4815f175SKonstantin Belousov if (othertd == td) 351*4815f175SKonstantin Belousov continue; 352*4815f175SKonstantin Belousov linux_proc_init(td, othertd, LINUX_CLONE_THREAD); 3538a15ac83SKonstantin Belousov } 3548a15ac83SKonstantin Belousov } 35523e8912cSDmitry Chagin #if defined(__amd64__) 35623e8912cSDmitry Chagin /* 35723e8912cSDmitry Chagin * An IA32 executable which has executable stack will have the 35823e8912cSDmitry Chagin * READ_IMPLIES_EXEC personality flag set automatically. 35923e8912cSDmitry Chagin */ 36023e8912cSDmitry Chagin if (SV_PROC_FLAG(td->td_proc, SV_ILP32) && 36123e8912cSDmitry Chagin imgp->stack_prot & VM_PROT_EXECUTE) { 36223e8912cSDmitry Chagin pem = pem_find(p); 36323e8912cSDmitry Chagin pem->persona |= LINUX_READ_IMPLIES_EXEC; 36423e8912cSDmitry Chagin } 36523e8912cSDmitry Chagin #endif 36681338031SDmitry Chagin } 36781338031SDmitry Chagin 36881338031SDmitry Chagin void 369*4815f175SKonstantin Belousov linux_thread_dtor(struct thread *td) 370ad2056f2SAlexander Leidinger { 371ad2056f2SAlexander Leidinger struct linux_emuldata *em; 372ad2056f2SAlexander Leidinger 37381338031SDmitry Chagin em = em_find(td); 37481338031SDmitry Chagin if (em == NULL) 37581338031SDmitry Chagin return; 37681338031SDmitry Chagin td->td_emuldata = NULL; 377ad2056f2SAlexander Leidinger 3787d96520bSDmitry Chagin LINUX_CTR1(thread_dtor, "thread(%d)", em->em_tid); 379ad2056f2SAlexander Leidinger 38081338031SDmitry Chagin free(em, M_TEMP); 381ad2056f2SAlexander Leidinger } 382ad2056f2SAlexander Leidinger 383ad2056f2SAlexander Leidinger void 384e5d81ef1SDmitry Chagin linux_schedtail(struct thread *td) 385ad2056f2SAlexander Leidinger { 386ad2056f2SAlexander Leidinger struct linux_emuldata *em; 387e5d81ef1SDmitry Chagin struct proc *p; 388ad2056f2SAlexander Leidinger int error = 0; 389ad2056f2SAlexander Leidinger int *child_set_tid; 390ad2056f2SAlexander Leidinger 391e5d81ef1SDmitry Chagin p = td->td_proc; 392e5d81ef1SDmitry Chagin 39381338031SDmitry Chagin em = em_find(td); 394bc273677SDmitry Chagin KASSERT(em != NULL, ("linux_schedtail: thread emuldata not found.\n")); 395ad2056f2SAlexander Leidinger child_set_tid = em->child_set_tid; 396ad2056f2SAlexander Leidinger 39719e252baSAlexander Leidinger if (child_set_tid != NULL) { 398e0327ddbSDmitry Chagin error = copyout(&em->em_tid, child_set_tid, 39981338031SDmitry Chagin sizeof(em->em_tid)); 4007d96520bSDmitry Chagin LINUX_CTR4(schedtail, "thread(%d) %p stored %d error %d", 40181338031SDmitry Chagin td->td_tid, child_set_tid, em->em_tid, error); 40281338031SDmitry Chagin } else 4037d96520bSDmitry Chagin LINUX_CTR1(schedtail, "thread(%d)", em->em_tid); 404bb63fddeSAlexander Leidinger } 405