1ad2056f2SAlexander Leidinger /*- 2ad2056f2SAlexander Leidinger * Copyright (c) 2006 Roman Divacky 3ad2056f2SAlexander Leidinger * All rights reserved. 4ad2056f2SAlexander Leidinger * 5ad2056f2SAlexander Leidinger * Redistribution and use in source and binary forms, with or without 6ad2056f2SAlexander Leidinger * modification, are permitted provided that the following conditions 7ad2056f2SAlexander Leidinger * are met: 8ad2056f2SAlexander Leidinger * 1. Redistributions of source code must retain the above copyright 9ad2056f2SAlexander Leidinger * notice, this list of conditions and the following disclaimer 10ad2056f2SAlexander Leidinger * in this position and unchanged. 11ad2056f2SAlexander Leidinger * 2. Redistributions in binary form must reproduce the above copyright 12ad2056f2SAlexander Leidinger * notice, this list of conditions and the following disclaimer in the 13ad2056f2SAlexander Leidinger * documentation and/or other materials provided with the distribution. 14ad2056f2SAlexander Leidinger * 3. The name of the author may not be used to endorse or promote products 15ad2056f2SAlexander Leidinger * derived from this software without specific prior written permission 16ad2056f2SAlexander Leidinger * 17ad2056f2SAlexander Leidinger * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18ad2056f2SAlexander Leidinger * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19ad2056f2SAlexander Leidinger * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20ad2056f2SAlexander Leidinger * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21ad2056f2SAlexander Leidinger * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22ad2056f2SAlexander Leidinger * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23ad2056f2SAlexander Leidinger * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24ad2056f2SAlexander Leidinger * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25ad2056f2SAlexander Leidinger * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26ad2056f2SAlexander Leidinger * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27ad2056f2SAlexander Leidinger */ 28ad2056f2SAlexander Leidinger 29ad2056f2SAlexander Leidinger #include <sys/cdefs.h> 30ad2056f2SAlexander Leidinger __FBSDID("$FreeBSD$"); 31ad2056f2SAlexander Leidinger 32ad2056f2SAlexander Leidinger #include "opt_compat.h" 33ad2056f2SAlexander Leidinger 34ad2056f2SAlexander Leidinger #include <sys/param.h> 35ad2056f2SAlexander Leidinger #include <sys/systm.h> 36ad2056f2SAlexander Leidinger #include <sys/imgact.h> 37b4bb5154SKonstantin Belousov #include <sys/kernel.h> 38ad2056f2SAlexander Leidinger #include <sys/lock.h> 39ad2056f2SAlexander Leidinger #include <sys/malloc.h> 40ad2056f2SAlexander Leidinger #include <sys/mutex.h> 41ad2056f2SAlexander Leidinger #include <sys/sx.h> 42ad2056f2SAlexander Leidinger #include <sys/proc.h> 43ad2056f2SAlexander Leidinger #include <sys/syscallsubr.h> 44ad2056f2SAlexander Leidinger #include <sys/sysproto.h> 45ad2056f2SAlexander Leidinger #include <sys/unistd.h> 46ad2056f2SAlexander Leidinger 47ad2056f2SAlexander Leidinger #ifdef COMPAT_LINUX32 48ad2056f2SAlexander Leidinger #include <machine/../linux32/linux.h> 49ad2056f2SAlexander Leidinger #include <machine/../linux32/linux32_proto.h> 50ad2056f2SAlexander Leidinger #else 51ad2056f2SAlexander Leidinger #include <machine/../linux/linux.h> 52ad2056f2SAlexander Leidinger #include <machine/../linux/linux_proto.h> 53ad2056f2SAlexander Leidinger #endif 54ad2056f2SAlexander Leidinger 554732e446SRoman Divacky #include <compat/linux/linux_emul.h> 564732e446SRoman Divacky #include <compat/linux/linux_futex.h> 574732e446SRoman Divacky 58ad2056f2SAlexander Leidinger struct sx emul_shared_lock; 59357afa71SJung-uk Kim struct mtx emul_lock; 60ad2056f2SAlexander Leidinger 61ad2056f2SAlexander Leidinger /* this returns locked reference to the emuldata entry (if found) */ 62ad2056f2SAlexander Leidinger struct linux_emuldata * 63ad2056f2SAlexander Leidinger em_find(struct proc *p, int locked) 64ad2056f2SAlexander Leidinger { 65ad2056f2SAlexander Leidinger struct linux_emuldata *em; 66ad2056f2SAlexander Leidinger 671c65504cSAlexander Leidinger if (locked == EMUL_DOLOCK) 68ad2056f2SAlexander Leidinger EMUL_LOCK(&emul_lock); 69ad2056f2SAlexander Leidinger 70ad2056f2SAlexander Leidinger em = p->p_emuldata; 71ad2056f2SAlexander Leidinger 721c65504cSAlexander Leidinger if (em == NULL && locked == EMUL_DOLOCK) 73ad2056f2SAlexander Leidinger EMUL_UNLOCK(&emul_lock); 74ad2056f2SAlexander Leidinger 75ad2056f2SAlexander Leidinger return (em); 76ad2056f2SAlexander Leidinger } 77ad2056f2SAlexander Leidinger 78ad2056f2SAlexander Leidinger int 79ad2056f2SAlexander Leidinger linux_proc_init(struct thread *td, pid_t child, int flags) 80ad2056f2SAlexander Leidinger { 81ad2056f2SAlexander Leidinger struct linux_emuldata *em, *p_em; 82ad2056f2SAlexander Leidinger struct proc *p; 83ad2056f2SAlexander Leidinger 84ad2056f2SAlexander Leidinger if (child != 0) { 85ad2056f2SAlexander Leidinger /* non-exec call */ 865342db08SSuleiman Souhlal em = malloc(sizeof *em, M_LINUX, M_WAITOK | M_ZERO); 87ad2056f2SAlexander Leidinger em->pid = child; 88955d762aSAlexander Leidinger em->pdeath_signal = 0; 89b1121623SDmitry Chagin em->used_requeue = 0; 904732e446SRoman Divacky em->robust_futexes = NULL; 91a4e3bad7SJung-uk Kim if (flags & LINUX_CLONE_THREAD) { 92ad2056f2SAlexander Leidinger /* handled later in the code */ 93ad2056f2SAlexander Leidinger } else { 94ad2056f2SAlexander Leidinger struct linux_emuldata_shared *s; 95ad2056f2SAlexander Leidinger 965342db08SSuleiman Souhlal s = malloc(sizeof *s, M_LINUX, M_WAITOK | M_ZERO); 97ad2056f2SAlexander Leidinger s->refs = 1; 98ad2056f2SAlexander Leidinger s->group_pid = child; 99ad2056f2SAlexander Leidinger 100ad2056f2SAlexander Leidinger LIST_INIT(&s->threads); 101d071f504SAlexander Leidinger em->shared = s; 102ad2056f2SAlexander Leidinger } 103ad2056f2SAlexander Leidinger } else { 104ad2056f2SAlexander Leidinger /* lookup the old one */ 1051c65504cSAlexander Leidinger em = em_find(td->td_proc, EMUL_DOLOCK); 106ad2056f2SAlexander Leidinger KASSERT(em != NULL, ("proc_init: emuldata not found in exec case.\n")); 107ad2056f2SAlexander Leidinger } 108ad2056f2SAlexander Leidinger 109ad2056f2SAlexander Leidinger em->child_clear_tid = NULL; 110ad2056f2SAlexander Leidinger em->child_set_tid = NULL; 111ad2056f2SAlexander Leidinger 1120eef2f8aSAlexander Leidinger /* 113a628609eSAlexander Leidinger * allocate the shared struct only in clone()/fork cases in the case 114a628609eSAlexander Leidinger * of clone() td = calling proc and child = pid of the newly created 115a628609eSAlexander Leidinger * proc 116ad2056f2SAlexander Leidinger */ 117ad2056f2SAlexander Leidinger if (child != 0) { 118a4e3bad7SJung-uk Kim if (flags & LINUX_CLONE_THREAD) { 119ad2056f2SAlexander Leidinger /* lookup the parent */ 12025954d74SKonstantin Belousov /* 12125954d74SKonstantin Belousov * we dont have to lock the p_em because 12225954d74SKonstantin Belousov * its waiting for us in linux_clone so 12325954d74SKonstantin Belousov * there is no chance of it changing the 12425954d74SKonstantin Belousov * p_em->shared address 12525954d74SKonstantin Belousov */ 12625954d74SKonstantin Belousov p_em = em_find(td->td_proc, EMUL_DONTLOCK); 127292a85f4SKonstantin Belousov KASSERT(p_em != NULL, ("proc_init: parent emuldata not found for CLONE_THREAD\n")); 128ad2056f2SAlexander Leidinger em->shared = p_em->shared; 12925954d74SKonstantin Belousov EMUL_SHARED_WLOCK(&emul_shared_lock); 130ad2056f2SAlexander Leidinger em->shared->refs++; 131291081ceSAlexander Leidinger EMUL_SHARED_WUNLOCK(&emul_shared_lock); 132ad2056f2SAlexander Leidinger } else { 133a628609eSAlexander Leidinger /* 134a628609eSAlexander Leidinger * handled earlier to avoid malloc(M_WAITOK) with 135a628609eSAlexander Leidinger * rwlock held 136a628609eSAlexander Leidinger */ 137ad2056f2SAlexander Leidinger } 138ad2056f2SAlexander Leidinger } 139ad2056f2SAlexander Leidinger if (child != 0) { 140ad2056f2SAlexander Leidinger EMUL_SHARED_WLOCK(&emul_shared_lock); 141ad2056f2SAlexander Leidinger LIST_INSERT_HEAD(&em->shared->threads, em, threads); 142ad2056f2SAlexander Leidinger EMUL_SHARED_WUNLOCK(&emul_shared_lock); 143ad2056f2SAlexander Leidinger 144ad2056f2SAlexander Leidinger p = pfind(child); 145d071f504SAlexander Leidinger KASSERT(p != NULL, ("process not found in proc_init\n")); 146d071f504SAlexander Leidinger p->p_emuldata = em; 1478618fd85SAlexander Leidinger PROC_UNLOCK(p); 148ad2056f2SAlexander Leidinger } else 149ad2056f2SAlexander Leidinger EMUL_UNLOCK(&emul_lock); 150ad2056f2SAlexander Leidinger 151ad2056f2SAlexander Leidinger return (0); 152ad2056f2SAlexander Leidinger } 153ad2056f2SAlexander Leidinger 154ad2056f2SAlexander Leidinger void 155ad2056f2SAlexander Leidinger linux_proc_exit(void *arg __unused, struct proc *p) 156ad2056f2SAlexander Leidinger { 157ad2056f2SAlexander Leidinger struct linux_emuldata *em; 158*bb63fddeSAlexander Leidinger int error, shared_flags, shared_xstat; 159ad2056f2SAlexander Leidinger struct thread *td = FIRST_THREAD_IN_PROC(p); 160ad2056f2SAlexander Leidinger int *child_clear_tid; 161955d762aSAlexander Leidinger struct proc *q, *nq; 162ad2056f2SAlexander Leidinger 163ad2056f2SAlexander Leidinger if (__predict_true(p->p_sysent != &elf_linux_sysvec)) 164ad2056f2SAlexander Leidinger return; 165ad2056f2SAlexander Leidinger 1664732e446SRoman Divacky release_futexes(p); 1674732e446SRoman Divacky 168ad2056f2SAlexander Leidinger /* find the emuldata */ 1691c65504cSAlexander Leidinger em = em_find(p, EMUL_DOLOCK); 170ad2056f2SAlexander Leidinger 171ad2056f2SAlexander Leidinger KASSERT(em != NULL, ("proc_exit: emuldata not found.\n")); 172ad2056f2SAlexander Leidinger 17325954d74SKonstantin Belousov /* reparent all procs that are not a thread leader to initproc */ 17425954d74SKonstantin Belousov if (em->shared->group_pid != p->p_pid) { 175e8b8b834SAlexander Leidinger child_clear_tid = em->child_clear_tid; 176e8b8b834SAlexander Leidinger EMUL_UNLOCK(&emul_lock); 17725954d74SKonstantin Belousov sx_xlock(&proctree_lock); 17825954d74SKonstantin Belousov wakeup(initproc); 17925954d74SKonstantin Belousov PROC_LOCK(p); 18025954d74SKonstantin Belousov proc_reparent(p, initproc); 18125954d74SKonstantin Belousov p->p_sigparent = SIGCHLD; 18225954d74SKonstantin Belousov PROC_UNLOCK(p); 18325954d74SKonstantin Belousov sx_xunlock(&proctree_lock); 184e8b8b834SAlexander Leidinger } else { 185ad2056f2SAlexander Leidinger child_clear_tid = em->child_clear_tid; 186ad2056f2SAlexander Leidinger EMUL_UNLOCK(&emul_lock); 187e8b8b834SAlexander Leidinger } 188ad2056f2SAlexander Leidinger 189ad2056f2SAlexander Leidinger EMUL_SHARED_WLOCK(&emul_shared_lock); 190*bb63fddeSAlexander Leidinger shared_flags = em->shared->flags; 191*bb63fddeSAlexander Leidinger shared_xstat = em->shared->xstat; 192ad2056f2SAlexander Leidinger LIST_REMOVE(em, threads); 193ad2056f2SAlexander Leidinger 194ad2056f2SAlexander Leidinger em->shared->refs--; 1951a26db0aSAlexander Leidinger if (em->shared->refs == 0) { 1961a26db0aSAlexander Leidinger EMUL_SHARED_WUNLOCK(&emul_shared_lock); 1975342db08SSuleiman Souhlal free(em->shared, M_LINUX); 1981a26db0aSAlexander Leidinger } else 199ad2056f2SAlexander Leidinger EMUL_SHARED_WUNLOCK(&emul_shared_lock); 200ad2056f2SAlexander Leidinger 201*bb63fddeSAlexander Leidinger if ((shared_flags & EMUL_SHARED_HASXSTAT) != 0) { 202*bb63fddeSAlexander Leidinger PROC_LOCK(p); 203*bb63fddeSAlexander Leidinger p->p_xstat = shared_xstat; 204*bb63fddeSAlexander Leidinger PROC_UNLOCK(p); 205*bb63fddeSAlexander Leidinger } 206*bb63fddeSAlexander Leidinger 207ad2056f2SAlexander Leidinger if (child_clear_tid != NULL) { 208ad2056f2SAlexander Leidinger struct linux_sys_futex_args cup; 209ad2056f2SAlexander Leidinger int null = 0; 210ad2056f2SAlexander Leidinger 211ad2056f2SAlexander Leidinger error = copyout(&null, child_clear_tid, sizeof(null)); 21228638377SAlexander Leidinger if (error) { 21328638377SAlexander Leidinger free(em, M_LINUX); 214ad2056f2SAlexander Leidinger return; 21528638377SAlexander Leidinger } 216ad2056f2SAlexander Leidinger 217ad2056f2SAlexander Leidinger /* futexes stuff */ 218ad2056f2SAlexander Leidinger cup.uaddr = child_clear_tid; 219ad2056f2SAlexander Leidinger cup.op = LINUX_FUTEX_WAKE; 220ad2056f2SAlexander Leidinger cup.val = 0x7fffffff; /* Awake everyone */ 221ad2056f2SAlexander Leidinger cup.timeout = NULL; 222ad2056f2SAlexander Leidinger cup.uaddr2 = NULL; 223ad2056f2SAlexander Leidinger cup.val3 = 0; 224ad2056f2SAlexander Leidinger error = linux_sys_futex(FIRST_THREAD_IN_PROC(p), &cup); 2250eef2f8aSAlexander Leidinger /* 226a628609eSAlexander Leidinger * this cannot happen at the moment and if this happens it 227802e08a3SAlexander Leidinger * probably means there is a user space bug 228ad2056f2SAlexander Leidinger */ 229ad2056f2SAlexander Leidinger if (error) 230ad2056f2SAlexander Leidinger printf(LMSG("futex stuff in proc_exit failed.\n")); 231ad2056f2SAlexander Leidinger } 232ad2056f2SAlexander Leidinger 233ad2056f2SAlexander Leidinger /* clean the stuff up */ 2345342db08SSuleiman Souhlal free(em, M_LINUX); 235955d762aSAlexander Leidinger 236955d762aSAlexander Leidinger /* this is a little weird but rewritten from exit1() */ 237955d762aSAlexander Leidinger sx_xlock(&proctree_lock); 238955d762aSAlexander Leidinger q = LIST_FIRST(&p->p_children); 239955d762aSAlexander Leidinger for (; q != NULL; q = nq) { 240955d762aSAlexander Leidinger nq = LIST_NEXT(q, p_sibling); 241955d762aSAlexander Leidinger if (q->p_flag & P_WEXIT) 242955d762aSAlexander Leidinger continue; 243955d762aSAlexander Leidinger if (__predict_false(q->p_sysent != &elf_linux_sysvec)) 244955d762aSAlexander Leidinger continue; 2451c65504cSAlexander Leidinger em = em_find(q, EMUL_DOLOCK); 246955d762aSAlexander Leidinger KASSERT(em != NULL, ("linux_reparent: emuldata not found: %i\n", q->p_pid)); 247955d762aSAlexander Leidinger PROC_LOCK(q); 24817b9edd3SKonstantin Belousov if ((q->p_flag & P_WEXIT) == 0 && em->pdeath_signal != 0) { 249955d762aSAlexander Leidinger psignal(q, em->pdeath_signal); 250955d762aSAlexander Leidinger } 25117b9edd3SKonstantin Belousov PROC_UNLOCK(q); 252955d762aSAlexander Leidinger EMUL_UNLOCK(&emul_lock); 253955d762aSAlexander Leidinger } 254955d762aSAlexander Leidinger sx_xunlock(&proctree_lock); 255ad2056f2SAlexander Leidinger } 256ad2056f2SAlexander Leidinger 2570eef2f8aSAlexander Leidinger /* 2580eef2f8aSAlexander Leidinger * This is used in a case of transition from FreeBSD binary execing to linux binary 259ad2056f2SAlexander Leidinger * in this case we create linux emuldata proc entry with the pid of the currently running 260ad2056f2SAlexander Leidinger * process. 261ad2056f2SAlexander Leidinger */ 262a628609eSAlexander Leidinger void 263a628609eSAlexander Leidinger linux_proc_exec(void *arg __unused, struct proc *p, struct image_params *imgp) 264ad2056f2SAlexander Leidinger { 265ad2056f2SAlexander Leidinger if (__predict_false(imgp->sysent == &elf_linux_sysvec 266ad2056f2SAlexander Leidinger && p->p_sysent != &elf_linux_sysvec)) 267ad2056f2SAlexander Leidinger linux_proc_init(FIRST_THREAD_IN_PROC(p), p->p_pid, 0); 268*bb63fddeSAlexander Leidinger if (__predict_false(p->p_sysent == &elf_linux_sysvec)) 269*bb63fddeSAlexander Leidinger /* Kill threads regardless of imgp->sysent value */ 270*bb63fddeSAlexander Leidinger linux_kill_threads(FIRST_THREAD_IN_PROC(p), SIGKILL); 271ad2056f2SAlexander Leidinger if (__predict_false(imgp->sysent != &elf_linux_sysvec 272ad2056f2SAlexander Leidinger && p->p_sysent == &elf_linux_sysvec)) { 273ad2056f2SAlexander Leidinger struct linux_emuldata *em; 274ad2056f2SAlexander Leidinger 27525954d74SKonstantin Belousov /* 27625954d74SKonstantin Belousov * XXX:There's a race because here we assign p->p_emuldata NULL 27725954d74SKonstantin Belousov * but the process is still counted as linux one for a short 27825954d74SKonstantin Belousov * time so some other process might reference it and try to 27925954d74SKonstantin Belousov * access its p->p_emuldata and panicing on a NULL reference. 28025954d74SKonstantin Belousov */ 28125954d74SKonstantin Belousov em = em_find(p, EMUL_DONTLOCK); 282ad2056f2SAlexander Leidinger 283ad2056f2SAlexander Leidinger KASSERT(em != NULL, ("proc_exec: emuldata not found.\n")); 284ad2056f2SAlexander Leidinger 285ad2056f2SAlexander Leidinger EMUL_SHARED_WLOCK(&emul_shared_lock); 286ad2056f2SAlexander Leidinger LIST_REMOVE(em, threads); 287ad2056f2SAlexander Leidinger 288ad2056f2SAlexander Leidinger PROC_LOCK(p); 289ad2056f2SAlexander Leidinger p->p_emuldata = NULL; 290ad2056f2SAlexander Leidinger PROC_UNLOCK(p); 291ad2056f2SAlexander Leidinger 292ad2056f2SAlexander Leidinger em->shared->refs--; 2931a26db0aSAlexander Leidinger if (em->shared->refs == 0) { 2941a26db0aSAlexander Leidinger EMUL_SHARED_WUNLOCK(&emul_shared_lock); 295c67e0cc9SSuleiman Souhlal free(em->shared, M_LINUX); 2961a26db0aSAlexander Leidinger } else 297ad2056f2SAlexander Leidinger EMUL_SHARED_WUNLOCK(&emul_shared_lock); 298ad2056f2SAlexander Leidinger 299c67e0cc9SSuleiman Souhlal free(em, M_LINUX); 300ad2056f2SAlexander Leidinger } 301ad2056f2SAlexander Leidinger } 302ad2056f2SAlexander Leidinger 303ad2056f2SAlexander Leidinger void 304ad2056f2SAlexander Leidinger linux_schedtail(void *arg __unused, struct proc *p) 305ad2056f2SAlexander Leidinger { 306ad2056f2SAlexander Leidinger struct linux_emuldata *em; 307ad2056f2SAlexander Leidinger int error = 0; 308ad2056f2SAlexander Leidinger int *child_set_tid; 309ad2056f2SAlexander Leidinger 310955d762aSAlexander Leidinger if (__predict_true(p->p_sysent != &elf_linux_sysvec)) 311ad2056f2SAlexander Leidinger return; 312ad2056f2SAlexander Leidinger 313ad2056f2SAlexander Leidinger /* find the emuldata */ 3141c65504cSAlexander Leidinger em = em_find(p, EMUL_DOLOCK); 315ad2056f2SAlexander Leidinger 31625954d74SKonstantin Belousov KASSERT(em != NULL, ("linux_schedtail: emuldata not found.\n")); 317ad2056f2SAlexander Leidinger child_set_tid = em->child_set_tid; 318ad2056f2SAlexander Leidinger EMUL_UNLOCK(&emul_lock); 319ad2056f2SAlexander Leidinger 320ad2056f2SAlexander Leidinger if (child_set_tid != NULL) 321a628609eSAlexander Leidinger error = copyout(&p->p_pid, (int *)child_set_tid, 322a628609eSAlexander Leidinger sizeof(p->p_pid)); 323ad2056f2SAlexander Leidinger 324ad2056f2SAlexander Leidinger return; 325ad2056f2SAlexander Leidinger } 326ad2056f2SAlexander Leidinger 327ad2056f2SAlexander Leidinger int 328ad2056f2SAlexander Leidinger linux_set_tid_address(struct thread *td, struct linux_set_tid_address_args *args) 329ad2056f2SAlexander Leidinger { 330ad2056f2SAlexander Leidinger struct linux_emuldata *em; 331ad2056f2SAlexander Leidinger 332ad2056f2SAlexander Leidinger #ifdef DEBUG 333ad2056f2SAlexander Leidinger if (ldebug(set_tid_address)) 334ad2056f2SAlexander Leidinger printf(ARGS(set_tid_address, "%p"), args->tidptr); 335ad2056f2SAlexander Leidinger #endif 336ad2056f2SAlexander Leidinger 337ad2056f2SAlexander Leidinger /* find the emuldata */ 3381c65504cSAlexander Leidinger em = em_find(td->td_proc, EMUL_DOLOCK); 339ad2056f2SAlexander Leidinger 340ad2056f2SAlexander Leidinger KASSERT(em != NULL, ("set_tid_address: emuldata not found.\n")); 341ad2056f2SAlexander Leidinger 342ad2056f2SAlexander Leidinger em->child_clear_tid = args->tidptr; 343ad2056f2SAlexander Leidinger td->td_retval[0] = td->td_proc->p_pid; 344ad2056f2SAlexander Leidinger 345ad2056f2SAlexander Leidinger EMUL_UNLOCK(&emul_lock); 346ad2056f2SAlexander Leidinger return 0; 347ad2056f2SAlexander Leidinger } 348*bb63fddeSAlexander Leidinger 349*bb63fddeSAlexander Leidinger void 350*bb63fddeSAlexander Leidinger linux_kill_threads(struct thread *td, int sig) 351*bb63fddeSAlexander Leidinger { 352*bb63fddeSAlexander Leidinger struct linux_emuldata *em, *td_em, *tmp_em; 353*bb63fddeSAlexander Leidinger struct proc *sp; 354*bb63fddeSAlexander Leidinger 355*bb63fddeSAlexander Leidinger td_em = em_find(td->td_proc, EMUL_DONTLOCK); 356*bb63fddeSAlexander Leidinger 357*bb63fddeSAlexander Leidinger KASSERT(td_em != NULL, ("linux_kill_threads: emuldata not found.\n")); 358*bb63fddeSAlexander Leidinger 359*bb63fddeSAlexander Leidinger EMUL_SHARED_RLOCK(&emul_shared_lock); 360*bb63fddeSAlexander Leidinger LIST_FOREACH_SAFE(em, &td_em->shared->threads, threads, tmp_em) { 361*bb63fddeSAlexander Leidinger if (em->pid == td_em->pid) 362*bb63fddeSAlexander Leidinger continue; 363*bb63fddeSAlexander Leidinger 364*bb63fddeSAlexander Leidinger sp = pfind(em->pid); 365*bb63fddeSAlexander Leidinger if ((sp->p_flag & P_WEXIT) == 0) 366*bb63fddeSAlexander Leidinger psignal(sp, sig); 367*bb63fddeSAlexander Leidinger PROC_UNLOCK(sp); 368*bb63fddeSAlexander Leidinger #ifdef DEBUG 369*bb63fddeSAlexander Leidinger printf(LMSG("linux_kill_threads: kill PID %d\n"), em->pid); 370*bb63fddeSAlexander Leidinger #endif 371*bb63fddeSAlexander Leidinger } 372*bb63fddeSAlexander Leidinger EMUL_SHARED_RUNLOCK(&emul_shared_lock); 373*bb63fddeSAlexander Leidinger } 374