1161304Snetchild/*- 2161304Snetchild * Copyright (c) 2006 Roman Divacky 3161304Snetchild * All rights reserved. 4161304Snetchild * 5161304Snetchild * Redistribution and use in source and binary forms, with or without 6161304Snetchild * modification, are permitted provided that the following conditions 7161304Snetchild * are met: 8161304Snetchild * 1. Redistributions of source code must retain the above copyright 9161304Snetchild * notice, this list of conditions and the following disclaimer 10161304Snetchild * in this position and unchanged. 11161304Snetchild * 2. Redistributions in binary form must reproduce the above copyright 12161304Snetchild * notice, this list of conditions and the following disclaimer in the 13161304Snetchild * documentation and/or other materials provided with the distribution. 14161304Snetchild * 3. The name of the author may not be used to endorse or promote products 15161304Snetchild * derived from this software without specific prior written permission 16161304Snetchild * 17161304Snetchild * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18161304Snetchild * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19161304Snetchild * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20161304Snetchild * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21161304Snetchild * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22161304Snetchild * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23161304Snetchild * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24161304Snetchild * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25161304Snetchild * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26161304Snetchild * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27161304Snetchild */ 28161304Snetchild 29161304Snetchild#include <sys/cdefs.h> 30161304Snetchild__FBSDID("$FreeBSD$"); 31161304Snetchild 32161304Snetchild#include "opt_compat.h" 33246290Sdchagin#include "opt_kdtrace.h" 34161304Snetchild 35161304Snetchild#include <sys/param.h> 36161304Snetchild#include <sys/systm.h> 37161304Snetchild#include <sys/imgact.h> 38166420Skib#include <sys/kernel.h> 39161304Snetchild#include <sys/lock.h> 40161304Snetchild#include <sys/malloc.h> 41161304Snetchild#include <sys/mutex.h> 42246290Sdchagin#include <sys/sdt.h> 43161304Snetchild#include <sys/sx.h> 44161304Snetchild#include <sys/proc.h> 45161304Snetchild#include <sys/syscallsubr.h> 46215706Sdim#include <sys/sysent.h> 47161304Snetchild#include <sys/sysproto.h> 48161304Snetchild#include <sys/unistd.h> 49161304Snetchild 50161304Snetchild#ifdef COMPAT_LINUX32 51161304Snetchild#include <machine/../linux32/linux.h> 52161304Snetchild#include <machine/../linux32/linux32_proto.h> 53161304Snetchild#else 54161304Snetchild#include <machine/../linux/linux.h> 55161304Snetchild#include <machine/../linux/linux_proto.h> 56161304Snetchild#endif 57161304Snetchild 58246290Sdchagin#include <compat/linux/linux_dtrace.h> 59178976Srdivacky#include <compat/linux/linux_emul.h> 60178976Srdivacky#include <compat/linux/linux_futex.h> 61178976Srdivacky 62246290Sdchagin/** 63246290Sdchagin * Special DTrace provider for the linuxulator. 64246290Sdchagin * 65246290Sdchagin * In this file we define the provider for the entire linuxulator. All 66246290Sdchagin * modules (= files of the linuxulator) use it. 67246290Sdchagin * 68246290Sdchagin * We define a different name depending on the emulated bitsize, see 69246290Sdchagin * ../../<ARCH>/linux{,32}/linux.h, e.g.: 70246290Sdchagin * native bitsize = linuxulator 71246290Sdchagin * amd64, 32bit emulation = linuxulator32 72246290Sdchagin */ 73246290SdchaginLIN_SDT_PROVIDER_DEFINE(LINUX_DTRACE); 74246290Sdchagin 75246290Sdchagin/** 76246290Sdchagin * Special DTrace module "locks", it covers some linuxulator internal 77246290Sdchagin * locks. 78246290Sdchagin */ 79246290SdchaginLIN_SDT_PROBE_DEFINE1(locks, emul_lock, locked, "struct mtx *"); 80246290SdchaginLIN_SDT_PROBE_DEFINE1(locks, emul_lock, unlock, "struct mtx *"); 81246290SdchaginLIN_SDT_PROBE_DEFINE1(locks, emul_shared_rlock, locked, "struct sx *"); 82246290SdchaginLIN_SDT_PROBE_DEFINE1(locks, emul_shared_rlock, unlock, "struct sx *"); 83246290SdchaginLIN_SDT_PROBE_DEFINE1(locks, emul_shared_wlock, locked, "struct sx *"); 84246290SdchaginLIN_SDT_PROBE_DEFINE1(locks, emul_shared_wlock, unlock, "struct sx *"); 85246290Sdchagin 86246290Sdchagin/** 87246290Sdchagin * DTrace probes in this module. 88246290Sdchagin */ 89246290SdchaginLIN_SDT_PROBE_DEFINE2(emul, em_find, entry, "struct proc *", "int"); 90246290SdchaginLIN_SDT_PROBE_DEFINE0(emul, em_find, return); 91246290SdchaginLIN_SDT_PROBE_DEFINE3(emul, proc_init, entry, "struct thread *", "pid_t", 92246290Sdchagin "int"); 93246290SdchaginLIN_SDT_PROBE_DEFINE0(emul, proc_init, create_thread); 94246290SdchaginLIN_SDT_PROBE_DEFINE0(emul, proc_init, fork); 95246290SdchaginLIN_SDT_PROBE_DEFINE0(emul, proc_init, exec); 96246290SdchaginLIN_SDT_PROBE_DEFINE0(emul, proc_init, return); 97246290SdchaginLIN_SDT_PROBE_DEFINE1(emul, proc_exit, entry, "struct proc *"); 98246290SdchaginLIN_SDT_PROBE_DEFINE0(emul, proc_exit, futex_failed); 99246290SdchaginLIN_SDT_PROBE_DEFINE3(emul, proc_exit, reparent, "pid_t", "pid_t", 100246290Sdchagin "struct proc *"); 101246290SdchaginLIN_SDT_PROBE_DEFINE1(emul, proc_exit, child_clear_tid_error, "int"); 102246290SdchaginLIN_SDT_PROBE_DEFINE0(emul, proc_exit, return); 103246290SdchaginLIN_SDT_PROBE_DEFINE2(emul, proc_exec, entry, "struct proc *", 104246290Sdchagin "struct image_params *"); 105246290SdchaginLIN_SDT_PROBE_DEFINE0(emul, proc_exec, return); 106246290SdchaginLIN_SDT_PROBE_DEFINE0(emul, linux_schedtail, entry); 107246290SdchaginLIN_SDT_PROBE_DEFINE1(emul, linux_schedtail, copyout_error, "int"); 108246290SdchaginLIN_SDT_PROBE_DEFINE0(emul, linux_schedtail, return); 109246290SdchaginLIN_SDT_PROBE_DEFINE1(emul, linux_set_tid_address, entry, "int *"); 110246290SdchaginLIN_SDT_PROBE_DEFINE0(emul, linux_set_tid_address, return); 111246290SdchaginLIN_SDT_PROBE_DEFINE2(emul, linux_kill_threads, entry, "struct thread *", 112246290Sdchagin "int"); 113246290SdchaginLIN_SDT_PROBE_DEFINE1(emul, linux_kill_threads, kill, "pid_t"); 114246290SdchaginLIN_SDT_PROBE_DEFINE0(emul, linux_kill_threads, return); 115246290Sdchagin 116168275Sjkimstruct sx emul_shared_lock; 117168275Sjkimstruct mtx emul_lock; 118161304Snetchild 119161304Snetchild/* this returns locked reference to the emuldata entry (if found) */ 120161304Snetchildstruct linux_emuldata * 121161304Snetchildem_find(struct proc *p, int locked) 122161304Snetchild{ 123161304Snetchild struct linux_emuldata *em; 124161304Snetchild 125246290Sdchagin LIN_SDT_PROBE2(emul, em_find, entry, p, locked); 126246290Sdchagin 127165867Snetchild if (locked == EMUL_DOLOCK) 128165688Snetchild EMUL_LOCK(&emul_lock); 129161304Snetchild 130165688Snetchild em = p->p_emuldata; 131161304Snetchild 132165867Snetchild if (em == NULL && locked == EMUL_DOLOCK) 133165688Snetchild EMUL_UNLOCK(&emul_lock); 134161304Snetchild 135246290Sdchagin LIN_SDT_PROBE1(emul, em_find, return, em); 136161304Snetchild return (em); 137161304Snetchild} 138161304Snetchild 139161304Snetchildint 140161304Snetchildlinux_proc_init(struct thread *td, pid_t child, int flags) 141161304Snetchild{ 142161304Snetchild struct linux_emuldata *em, *p_em; 143161304Snetchild struct proc *p; 144161304Snetchild 145246290Sdchagin LIN_SDT_PROBE3(emul, proc_init, entry, td, child, flags); 146246290Sdchagin 147161304Snetchild if (child != 0) { 148246290Sdchagin /* fork or create a thread */ 149161460Sssouhlal em = malloc(sizeof *em, M_LINUX, M_WAITOK | M_ZERO); 150161304Snetchild em->pid = child; 151163734Snetchild em->pdeath_signal = 0; 152218621Sdchagin em->flags = 0; 153178976Srdivacky em->robust_futexes = NULL; 154167157Sjkim if (flags & LINUX_CLONE_THREAD) { 155165688Snetchild /* handled later in the code */ 156246290Sdchagin LIN_SDT_PROBE0(emul, proc_init, create_thread); 157161304Snetchild } else { 158165688Snetchild struct linux_emuldata_shared *s; 159161304Snetchild 160246290Sdchagin LIN_SDT_PROBE0(emul, proc_init, fork); 161246290Sdchagin 162161460Sssouhlal s = malloc(sizeof *s, M_LINUX, M_WAITOK | M_ZERO); 163161304Snetchild s->refs = 1; 164161304Snetchild s->group_pid = child; 165161304Snetchild 166161304Snetchild LIST_INIT(&s->threads); 167166150Snetchild em->shared = s; 168161304Snetchild } 169161304Snetchild } else { 170246290Sdchagin /* exec */ 171246290Sdchagin LIN_SDT_PROBE0(emul, proc_init, exec); 172246290Sdchagin 173161304Snetchild /* lookup the old one */ 174165867Snetchild em = em_find(td->td_proc, EMUL_DOLOCK); 175161304Snetchild KASSERT(em != NULL, ("proc_init: emuldata not found in exec case.\n")); 176161304Snetchild } 177161304Snetchild 178161304Snetchild em->child_clear_tid = NULL; 179161304Snetchild em->child_set_tid = NULL; 180161304Snetchild 181165688Snetchild /* 182165688Snetchild * allocate the shared struct only in clone()/fork cases in the case 183165688Snetchild * of clone() td = calling proc and child = pid of the newly created 184165688Snetchild * proc 185161304Snetchild */ 186161304Snetchild if (child != 0) { 187167157Sjkim if (flags & LINUX_CLONE_THREAD) { 188165688Snetchild /* lookup the parent */ 189166396Skib /* 190166396Skib * we dont have to lock the p_em because 191166396Skib * its waiting for us in linux_clone so 192166396Skib * there is no chance of it changing the 193166396Skib * p_em->shared address 194166396Skib */ 195166396Skib p_em = em_find(td->td_proc, EMUL_DONTLOCK); 196164297Skib KASSERT(p_em != NULL, ("proc_init: parent emuldata not found for CLONE_THREAD\n")); 197161304Snetchild em->shared = p_em->shared; 198166396Skib EMUL_SHARED_WLOCK(&emul_shared_lock); 199161304Snetchild em->shared->refs++; 200166396Skib EMUL_SHARED_WUNLOCK(&emul_shared_lock); 201161304Snetchild } else { 202165688Snetchild /* 203165688Snetchild * handled earlier to avoid malloc(M_WAITOK) with 204165688Snetchild * rwlock held 205165688Snetchild */ 206161304Snetchild } 207246290Sdchagin 208165688Snetchild EMUL_SHARED_WLOCK(&emul_shared_lock); 209165688Snetchild LIST_INSERT_HEAD(&em->shared->threads, em, threads); 210165688Snetchild EMUL_SHARED_WUNLOCK(&emul_shared_lock); 211161304Snetchild 212161304Snetchild p = pfind(child); 213166150Snetchild KASSERT(p != NULL, ("process not found in proc_init\n")); 214166150Snetchild p->p_emuldata = em; 215162184Snetchild PROC_UNLOCK(p); 216161304Snetchild } else 217165688Snetchild EMUL_UNLOCK(&emul_lock); 218161304Snetchild 219246290Sdchagin LIN_SDT_PROBE0(emul, proc_init, return); 220165688Snetchild return (0); 221161304Snetchild} 222161304Snetchild 223161304Snetchildvoid 224161304Snetchildlinux_proc_exit(void *arg __unused, struct proc *p) 225161304Snetchild{ 226165688Snetchild struct linux_emuldata *em; 227215664Snetchild int error, shared_flags, shared_xstat; 228161304Snetchild struct thread *td = FIRST_THREAD_IN_PROC(p); 229161304Snetchild int *child_clear_tid; 230163734Snetchild struct proc *q, *nq; 231161304Snetchild 232161304Snetchild if (__predict_true(p->p_sysent != &elf_linux_sysvec)) 233165688Snetchild return; 234161304Snetchild 235246290Sdchagin LIN_SDT_PROBE1(emul, proc_exit, entry, p); 236246290Sdchagin 237178976Srdivacky release_futexes(p); 238178976Srdivacky 239161304Snetchild /* find the emuldata */ 240165867Snetchild em = em_find(p, EMUL_DOLOCK); 241161304Snetchild 242161304Snetchild KASSERT(em != NULL, ("proc_exit: emuldata not found.\n")); 243161304Snetchild 244166396Skib /* reparent all procs that are not a thread leader to initproc */ 245166396Skib if (em->shared->group_pid != p->p_pid) { 246246290Sdchagin LIN_SDT_PROBE3(emul, proc_exit, reparent, 247246290Sdchagin em->shared->group_pid, p->p_pid, p); 248246290Sdchagin 249166930Snetchild child_clear_tid = em->child_clear_tid; 250166930Snetchild EMUL_UNLOCK(&emul_lock); 251166930Snetchild sx_xlock(&proctree_lock); 252166930Snetchild wakeup(initproc); 253166396Skib PROC_LOCK(p); 254166396Skib proc_reparent(p, initproc); 255166396Skib p->p_sigparent = SIGCHLD; 256166396Skib PROC_UNLOCK(p); 257166930Snetchild sx_xunlock(&proctree_lock); 258166930Snetchild } else { 259166930Snetchild child_clear_tid = em->child_clear_tid; 260166930Snetchild EMUL_UNLOCK(&emul_lock); 261166396Skib } 262166396Skib 263161304Snetchild EMUL_SHARED_WLOCK(&emul_shared_lock); 264215664Snetchild shared_flags = em->shared->flags; 265215664Snetchild shared_xstat = em->shared->xstat; 266161304Snetchild LIST_REMOVE(em, threads); 267161304Snetchild 268161304Snetchild em->shared->refs--; 269166931Snetchild if (em->shared->refs == 0) { 270166931Snetchild EMUL_SHARED_WUNLOCK(&emul_shared_lock); 271161460Sssouhlal free(em->shared, M_LINUX); 272166931Snetchild } else 273166931Snetchild EMUL_SHARED_WUNLOCK(&emul_shared_lock); 274161304Snetchild 275215675Snetchild if ((shared_flags & EMUL_SHARED_HASXSTAT) != 0) 276215664Snetchild p->p_xstat = shared_xstat; 277215664Snetchild 278161304Snetchild if (child_clear_tid != NULL) { 279165688Snetchild struct linux_sys_futex_args cup; 280161304Snetchild int null = 0; 281161304Snetchild 282161304Snetchild error = copyout(&null, child_clear_tid, sizeof(null)); 283163132Snetchild if (error) { 284246290Sdchagin LIN_SDT_PROBE1(emul, proc_exit, 285246290Sdchagin child_clear_tid_error, error); 286246290Sdchagin 287165688Snetchild free(em, M_LINUX); 288246290Sdchagin 289246290Sdchagin LIN_SDT_PROBE0(emul, proc_exit, return); 290165688Snetchild return; 291163132Snetchild } 292161304Snetchild 293161304Snetchild /* futexes stuff */ 294161304Snetchild cup.uaddr = child_clear_tid; 295161304Snetchild cup.op = LINUX_FUTEX_WAKE; 296165688Snetchild cup.val = 0x7fffffff; /* Awake everyone */ 297161304Snetchild cup.timeout = NULL; 298161304Snetchild cup.uaddr2 = NULL; 299161304Snetchild cup.val3 = 0; 300161304Snetchild error = linux_sys_futex(FIRST_THREAD_IN_PROC(p), &cup); 301165688Snetchild /* 302165688Snetchild * this cannot happen at the moment and if this happens it 303166944Snetchild * probably means there is a user space bug 304161365Snetchild */ 305246290Sdchagin if (error) { 306246290Sdchagin LIN_SDT_PROBE0(emul, proc_exit, futex_failed); 307165688Snetchild printf(LMSG("futex stuff in proc_exit failed.\n")); 308246290Sdchagin } 309161304Snetchild } 310161304Snetchild 311161304Snetchild /* clean the stuff up */ 312161460Sssouhlal free(em, M_LINUX); 313163734Snetchild 314163734Snetchild /* this is a little weird but rewritten from exit1() */ 315163734Snetchild sx_xlock(&proctree_lock); 316163734Snetchild q = LIST_FIRST(&p->p_children); 317163734Snetchild for (; q != NULL; q = nq) { 318165688Snetchild nq = LIST_NEXT(q, p_sibling); 319165688Snetchild if (q->p_flag & P_WEXIT) 320165688Snetchild continue; 321163734Snetchild if (__predict_false(q->p_sysent != &elf_linux_sysvec)) 322165688Snetchild continue; 323165867Snetchild em = em_find(q, EMUL_DOLOCK); 324163734Snetchild KASSERT(em != NULL, ("linux_reparent: emuldata not found: %i\n", q->p_pid)); 325184501Skib PROC_LOCK(q); 326184501Skib if ((q->p_flag & P_WEXIT) == 0 && em->pdeath_signal != 0) { 327225617Skmacy kern_psignal(q, em->pdeath_signal); 328163734Snetchild } 329184501Skib PROC_UNLOCK(q); 330163734Snetchild EMUL_UNLOCK(&emul_lock); 331163734Snetchild } 332163734Snetchild sx_xunlock(&proctree_lock); 333246290Sdchagin 334246290Sdchagin LIN_SDT_PROBE0(emul, proc_exit, return); 335161304Snetchild} 336161304Snetchild 337165688Snetchild/* 338161365Snetchild * This is used in a case of transition from FreeBSD binary execing to linux binary 339161304Snetchild * in this case we create linux emuldata proc entry with the pid of the currently running 340161304Snetchild * process. 341161304Snetchild */ 342165688Snetchildvoid 343165688Snetchildlinux_proc_exec(void *arg __unused, struct proc *p, struct image_params *imgp) 344161304Snetchild{ 345246290Sdchagin if (__predict_false(imgp->sysent == &elf_linux_sysvec)) { 346246290Sdchagin LIN_SDT_PROBE2(emul, proc_exec, entry, p, imgp); 347246290Sdchagin } 348165688Snetchild if (__predict_false(imgp->sysent == &elf_linux_sysvec 349165688Snetchild && p->p_sysent != &elf_linux_sysvec)) 350165688Snetchild linux_proc_init(FIRST_THREAD_IN_PROC(p), p->p_pid, 0); 351215675Snetchild if (__predict_false((p->p_sysent->sv_flags & SV_ABI_MASK) == 352215675Snetchild SV_ABI_LINUX)) 353215664Snetchild /* Kill threads regardless of imgp->sysent value */ 354215664Snetchild linux_kill_threads(FIRST_THREAD_IN_PROC(p), SIGKILL); 355161304Snetchild if (__predict_false(imgp->sysent != &elf_linux_sysvec 356165688Snetchild && p->p_sysent == &elf_linux_sysvec)) { 357165688Snetchild struct linux_emuldata *em; 358161304Snetchild 359166396Skib /* 360166396Skib * XXX:There's a race because here we assign p->p_emuldata NULL 361166396Skib * but the process is still counted as linux one for a short 362166396Skib * time so some other process might reference it and try to 363166396Skib * access its p->p_emuldata and panicing on a NULL reference. 364166396Skib */ 365166396Skib em = em_find(p, EMUL_DONTLOCK); 366161304Snetchild 367161304Snetchild KASSERT(em != NULL, ("proc_exec: emuldata not found.\n")); 368165688Snetchild 369161304Snetchild EMUL_SHARED_WLOCK(&emul_shared_lock); 370161304Snetchild LIST_REMOVE(em, threads); 371161304Snetchild 372161304Snetchild PROC_LOCK(p); 373161304Snetchild p->p_emuldata = NULL; 374161304Snetchild PROC_UNLOCK(p); 375161304Snetchild 376161304Snetchild em->shared->refs--; 377166931Snetchild if (em->shared->refs == 0) { 378166931Snetchild EMUL_SHARED_WUNLOCK(&emul_shared_lock); 379165688Snetchild free(em->shared, M_LINUX); 380166931Snetchild } else 381166931Snetchild EMUL_SHARED_WUNLOCK(&emul_shared_lock); 382161304Snetchild 383161697Sssouhlal free(em, M_LINUX); 384161304Snetchild } 385246290Sdchagin 386246290Sdchagin if (__predict_false(imgp->sysent == &elf_linux_sysvec)) { 387246290Sdchagin LIN_SDT_PROBE0(emul, proc_exec, return); 388246290Sdchagin } 389161304Snetchild} 390161304Snetchild 391161304Snetchildvoid 392219405Sdchaginlinux_schedtail(struct thread *td) 393161304Snetchild{ 394161304Snetchild struct linux_emuldata *em; 395219405Sdchagin struct proc *p; 396161304Snetchild int error = 0; 397161304Snetchild int *child_set_tid; 398161304Snetchild 399219405Sdchagin p = td->td_proc; 400219405Sdchagin 401246290Sdchagin LIN_SDT_PROBE1(emul, linux_schedtail, entry, p); 402246290Sdchagin 403161304Snetchild /* find the emuldata */ 404165867Snetchild em = em_find(p, EMUL_DOLOCK); 405161304Snetchild 406166396Skib KASSERT(em != NULL, ("linux_schedtail: emuldata not found.\n")); 407161304Snetchild child_set_tid = em->child_set_tid; 408161304Snetchild EMUL_UNLOCK(&emul_lock); 409161304Snetchild 410246290Sdchagin if (child_set_tid != NULL) { 411165688Snetchild error = copyout(&p->p_pid, (int *)child_set_tid, 412165688Snetchild sizeof(p->p_pid)); 413161304Snetchild 414246290Sdchagin if (error != 0) { 415246290Sdchagin LIN_SDT_PROBE1(emul, linux_schedtail, copyout_error, 416246290Sdchagin error); 417246290Sdchagin } 418246290Sdchagin } 419246290Sdchagin 420246290Sdchagin LIN_SDT_PROBE0(emul, linux_schedtail, return); 421246290Sdchagin 422161304Snetchild return; 423161304Snetchild} 424161304Snetchild 425161304Snetchildint 426161304Snetchildlinux_set_tid_address(struct thread *td, struct linux_set_tid_address_args *args) 427161304Snetchild{ 428165688Snetchild struct linux_emuldata *em; 429161304Snetchild 430246290Sdchagin LIN_SDT_PROBE1(emul, linux_set_tid_address, entry, args->tidptr); 431161304Snetchild 432165688Snetchild /* find the emuldata */ 433165867Snetchild em = em_find(td->td_proc, EMUL_DOLOCK); 434161304Snetchild 435161304Snetchild KASSERT(em != NULL, ("set_tid_address: emuldata not found.\n")); 436161304Snetchild 437161304Snetchild em->child_clear_tid = args->tidptr; 438161304Snetchild td->td_retval[0] = td->td_proc->p_pid; 439161304Snetchild 440161304Snetchild EMUL_UNLOCK(&emul_lock); 441246290Sdchagin 442246290Sdchagin LIN_SDT_PROBE0(emul, linux_set_tid_address, return); 443161304Snetchild return 0; 444161304Snetchild} 445215664Snetchild 446215664Snetchildvoid 447215664Snetchildlinux_kill_threads(struct thread *td, int sig) 448215664Snetchild{ 449215664Snetchild struct linux_emuldata *em, *td_em, *tmp_em; 450215664Snetchild struct proc *sp; 451215664Snetchild 452246290Sdchagin LIN_SDT_PROBE2(emul, linux_kill_threads, entry, td, sig); 453246290Sdchagin 454215664Snetchild td_em = em_find(td->td_proc, EMUL_DONTLOCK); 455215664Snetchild 456215664Snetchild KASSERT(td_em != NULL, ("linux_kill_threads: emuldata not found.\n")); 457215664Snetchild 458215664Snetchild EMUL_SHARED_RLOCK(&emul_shared_lock); 459215664Snetchild LIST_FOREACH_SAFE(em, &td_em->shared->threads, threads, tmp_em) { 460215664Snetchild if (em->pid == td_em->pid) 461215664Snetchild continue; 462215664Snetchild 463215664Snetchild sp = pfind(em->pid); 464215664Snetchild if ((sp->p_flag & P_WEXIT) == 0) 465225617Skmacy kern_psignal(sp, sig); 466215664Snetchild PROC_UNLOCK(sp); 467246290Sdchagin 468246290Sdchagin LIN_SDT_PROBE1(emul, linux_kill_threads, kill, em->pid); 469215664Snetchild } 470215664Snetchild EMUL_SHARED_RUNLOCK(&emul_shared_lock); 471246290Sdchagin 472246290Sdchagin LIN_SDT_PROBE0(emul, linux_kill_threads, return); 473215664Snetchild} 474