1ad2056f2SAlexander Leidinger /*- 2ad2056f2SAlexander Leidinger * Copyright (c) 2006 Roman Divacky 3*81338031SDmitry Chagin * Copyright (c) 2013 Dmitry Chagin 4ad2056f2SAlexander Leidinger * All rights reserved. 5ad2056f2SAlexander Leidinger * 6ad2056f2SAlexander Leidinger * Redistribution and use in source and binary forms, with or without 7ad2056f2SAlexander Leidinger * modification, are permitted provided that the following conditions 8ad2056f2SAlexander Leidinger * are met: 9ad2056f2SAlexander Leidinger * 1. Redistributions of source code must retain the above copyright 10ad2056f2SAlexander Leidinger * notice, this list of conditions and the following disclaimer 11ad2056f2SAlexander Leidinger * in this position and unchanged. 12ad2056f2SAlexander Leidinger * 2. Redistributions in binary form must reproduce the above copyright 13ad2056f2SAlexander Leidinger * notice, this list of conditions and the following disclaimer in the 14ad2056f2SAlexander Leidinger * documentation and/or other materials provided with the distribution. 15ad2056f2SAlexander Leidinger * 3. The name of the author may not be used to endorse or promote products 16ad2056f2SAlexander Leidinger * derived from this software without specific prior written permission 17ad2056f2SAlexander Leidinger * 18ad2056f2SAlexander Leidinger * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19ad2056f2SAlexander Leidinger * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20ad2056f2SAlexander Leidinger * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21ad2056f2SAlexander Leidinger * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22ad2056f2SAlexander Leidinger * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23ad2056f2SAlexander Leidinger * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24ad2056f2SAlexander Leidinger * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25ad2056f2SAlexander Leidinger * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26ad2056f2SAlexander Leidinger * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27ad2056f2SAlexander Leidinger * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28ad2056f2SAlexander Leidinger */ 29ad2056f2SAlexander Leidinger 30ad2056f2SAlexander Leidinger #include <sys/cdefs.h> 31ad2056f2SAlexander Leidinger __FBSDID("$FreeBSD$"); 32ad2056f2SAlexander Leidinger 33ad2056f2SAlexander Leidinger #include "opt_compat.h" 34ad2056f2SAlexander Leidinger 35ad2056f2SAlexander Leidinger #include <sys/param.h> 36ad2056f2SAlexander Leidinger #include <sys/systm.h> 37ad2056f2SAlexander Leidinger #include <sys/imgact.h> 38b4bb5154SKonstantin Belousov #include <sys/kernel.h> 39*81338031SDmitry Chagin #include <sys/ktr.h> 40ad2056f2SAlexander Leidinger #include <sys/lock.h> 41ad2056f2SAlexander Leidinger #include <sys/malloc.h> 42ad2056f2SAlexander Leidinger #include <sys/mutex.h> 4319e252baSAlexander Leidinger #include <sys/sdt.h> 44ad2056f2SAlexander Leidinger #include <sys/sx.h> 45ad2056f2SAlexander Leidinger #include <sys/proc.h> 46ad2056f2SAlexander Leidinger #include <sys/syscallsubr.h> 4795353459SDimitry Andric #include <sys/sysent.h> 48ad2056f2SAlexander Leidinger #include <sys/sysproto.h> 49ad2056f2SAlexander Leidinger #include <sys/unistd.h> 50ad2056f2SAlexander Leidinger 51ad2056f2SAlexander Leidinger #ifdef COMPAT_LINUX32 52ad2056f2SAlexander Leidinger #include <machine/../linux32/linux.h> 53ad2056f2SAlexander Leidinger #include <machine/../linux32/linux32_proto.h> 54ad2056f2SAlexander Leidinger #else 55ad2056f2SAlexander Leidinger #include <machine/../linux/linux.h> 56ad2056f2SAlexander Leidinger #include <machine/../linux/linux_proto.h> 57ad2056f2SAlexander Leidinger #endif 58ad2056f2SAlexander Leidinger 5919e252baSAlexander Leidinger #include <compat/linux/linux_dtrace.h> 604732e446SRoman Divacky #include <compat/linux/linux_emul.h> 614732e446SRoman Divacky #include <compat/linux/linux_futex.h> 62d825ce0aSJohn Baldwin #include <compat/linux/linux_misc.h> 63*81338031SDmitry Chagin #include <compat/linux/linux_util.h> 644732e446SRoman Divacky 6519e252baSAlexander Leidinger /** 6619e252baSAlexander Leidinger * Special DTrace provider for the linuxulator. 6719e252baSAlexander Leidinger * 6819e252baSAlexander Leidinger * In this file we define the provider for the entire linuxulator. All 6919e252baSAlexander Leidinger * modules (= files of the linuxulator) use it. 7019e252baSAlexander Leidinger * 7119e252baSAlexander Leidinger * We define a different name depending on the emulated bitsize, see 7219e252baSAlexander Leidinger * ../../<ARCH>/linux{,32}/linux.h, e.g.: 7319e252baSAlexander Leidinger * native bitsize = linuxulator 7419e252baSAlexander Leidinger * amd64, 32bit emulation = linuxulator32 7519e252baSAlexander Leidinger */ 7619e252baSAlexander Leidinger LIN_SDT_PROVIDER_DEFINE(LINUX_DTRACE); 7719e252baSAlexander Leidinger 7819e252baSAlexander Leidinger /** 7919e252baSAlexander Leidinger * DTrace probes in this module. 8019e252baSAlexander Leidinger */ 81*81338031SDmitry Chagin LIN_SDT_PROBE_DEFINE1(emul, em_find, entry, "struct thread *"); 8219e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE0(emul, em_find, return); 83*81338031SDmitry Chagin LIN_SDT_PROBE_DEFINE3(emul, proc_init, entry, "struct thread *", 84*81338031SDmitry Chagin "struct thread *", "int"); 8519e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE0(emul, proc_init, create_thread); 8619e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE0(emul, proc_init, fork); 8719e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE0(emul, proc_init, exec); 8819e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE0(emul, proc_init, return); 8919e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(emul, proc_exit, entry, "struct proc *"); 90*81338031SDmitry Chagin LIN_SDT_PROBE_DEFINE1(emul, linux_thread_detach, entry, "struct thread *"); 91*81338031SDmitry Chagin LIN_SDT_PROBE_DEFINE0(emul, linux_thread_detach, futex_failed); 92*81338031SDmitry Chagin LIN_SDT_PROBE_DEFINE1(emul, linux_thread_detach, child_clear_tid_error, "int"); 93*81338031SDmitry Chagin LIN_SDT_PROBE_DEFINE0(emul, linux_thread_detach, return); 9419e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE2(emul, proc_exec, entry, "struct proc *", 9519e252baSAlexander Leidinger "struct image_params *"); 9619e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE0(emul, proc_exec, return); 9719e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE0(emul, linux_schedtail, entry); 9819e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(emul, linux_schedtail, copyout_error, "int"); 9919e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE0(emul, linux_schedtail, return); 10019e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE1(emul, linux_set_tid_address, entry, "int *"); 10119e252baSAlexander Leidinger LIN_SDT_PROBE_DEFINE0(emul, linux_set_tid_address, return); 10219e252baSAlexander Leidinger 103*81338031SDmitry Chagin /* 104*81338031SDmitry Chagin * This returns reference to the emuldata entry (if found) 105*81338031SDmitry Chagin * 106*81338031SDmitry Chagin * Hold PROC_LOCK when referencing emuldata from other threads. 107*81338031SDmitry Chagin */ 108ad2056f2SAlexander Leidinger struct linux_emuldata * 109*81338031SDmitry Chagin em_find(struct thread *td) 110ad2056f2SAlexander Leidinger { 111ad2056f2SAlexander Leidinger struct linux_emuldata *em; 112ad2056f2SAlexander Leidinger 113*81338031SDmitry Chagin LIN_SDT_PROBE1(emul, em_find, entry, td); 11419e252baSAlexander Leidinger 115*81338031SDmitry Chagin em = td->td_emuldata; 116ad2056f2SAlexander Leidinger 11719e252baSAlexander Leidinger LIN_SDT_PROBE1(emul, em_find, return, em); 118*81338031SDmitry Chagin 119ad2056f2SAlexander Leidinger return (em); 120ad2056f2SAlexander Leidinger } 121ad2056f2SAlexander Leidinger 122*81338031SDmitry Chagin void 123*81338031SDmitry Chagin linux_proc_init(struct thread *td, struct thread *newtd, int flags) 124ad2056f2SAlexander Leidinger { 125*81338031SDmitry Chagin struct linux_emuldata *em; 126ad2056f2SAlexander Leidinger 127*81338031SDmitry Chagin LIN_SDT_PROBE3(emul, proc_init, entry, td, newtd, flags); 12819e252baSAlexander Leidinger 129*81338031SDmitry Chagin if (newtd != NULL) { 130*81338031SDmitry Chagin /* non-exec call */ 131*81338031SDmitry Chagin em = malloc(sizeof(*em), M_TEMP, M_WAITOK | M_ZERO); 132955d762aSAlexander Leidinger em->pdeath_signal = 0; 133d14cc07dSDmitry Chagin em->flags = 0; 1344732e446SRoman Divacky em->robust_futexes = NULL; 135a4e3bad7SJung-uk Kim if (flags & LINUX_CLONE_THREAD) { 13619e252baSAlexander Leidinger LIN_SDT_PROBE0(emul, proc_init, create_thread); 137ad2056f2SAlexander Leidinger 138*81338031SDmitry Chagin em->em_tid = newtd->td_tid; 139*81338031SDmitry Chagin } else { 14019e252baSAlexander Leidinger LIN_SDT_PROBE0(emul, proc_init, fork); 14119e252baSAlexander Leidinger 142*81338031SDmitry Chagin em->em_tid = newtd->td_proc->p_pid; 143ad2056f2SAlexander Leidinger } 144*81338031SDmitry Chagin newtd->td_emuldata = em; 145ad2056f2SAlexander Leidinger } else { 14619e252baSAlexander Leidinger /* exec */ 14719e252baSAlexander Leidinger LIN_SDT_PROBE0(emul, proc_init, exec); 14819e252baSAlexander Leidinger 149ad2056f2SAlexander Leidinger /* lookup the old one */ 150*81338031SDmitry Chagin em = em_find(td); 151ad2056f2SAlexander Leidinger KASSERT(em != NULL, ("proc_init: emuldata not found in exec case.\n")); 152*81338031SDmitry Chagin 153*81338031SDmitry Chagin em->em_tid = td->td_proc->p_pid; 154ad2056f2SAlexander Leidinger } 155ad2056f2SAlexander Leidinger 156ad2056f2SAlexander Leidinger em->child_clear_tid = NULL; 157ad2056f2SAlexander Leidinger em->child_set_tid = NULL; 158ad2056f2SAlexander Leidinger 15919e252baSAlexander Leidinger LIN_SDT_PROBE0(emul, proc_init, return); 160ad2056f2SAlexander Leidinger } 161ad2056f2SAlexander Leidinger 162ad2056f2SAlexander Leidinger void 163ad2056f2SAlexander Leidinger linux_proc_exit(void *arg __unused, struct proc *p) 164ad2056f2SAlexander Leidinger { 165*81338031SDmitry Chagin struct thread *td = curthread; 166ad2056f2SAlexander Leidinger 167*81338031SDmitry Chagin if (__predict_false(SV_CURPROC_ABI() != SV_ABI_LINUX)) { 16819e252baSAlexander Leidinger LIN_SDT_PROBE1(emul, proc_exit, entry, p); 169*81338031SDmitry Chagin (p->p_sysent->sv_thread_detach)(td); 170*81338031SDmitry Chagin } 171e8b8b834SAlexander Leidinger } 172ad2056f2SAlexander Leidinger 173*81338031SDmitry Chagin int 174*81338031SDmitry Chagin linux_common_execve(struct thread *td, struct image_args *eargs) 175*81338031SDmitry Chagin { 176*81338031SDmitry Chagin struct linux_emuldata *em; 177*81338031SDmitry Chagin struct proc *p; 178*81338031SDmitry Chagin int error; 179ad2056f2SAlexander Leidinger 180*81338031SDmitry Chagin p = td->td_proc; 181ad2056f2SAlexander Leidinger 182*81338031SDmitry Chagin /* 183*81338031SDmitry Chagin * Unlike FreeBSD abort all other threads before 184*81338031SDmitry Chagin * proceeding exec. 185*81338031SDmitry Chagin */ 186*81338031SDmitry Chagin PROC_LOCK(p); 187*81338031SDmitry Chagin /* See exit1() comments. */ 188*81338031SDmitry Chagin thread_suspend_check(0); 189*81338031SDmitry Chagin while (p->p_flag & P_HADTHREADS) { 190*81338031SDmitry Chagin if (!thread_single(p, SINGLE_EXIT)) 191*81338031SDmitry Chagin break; 192*81338031SDmitry Chagin thread_suspend_check(0); 193*81338031SDmitry Chagin } 194*81338031SDmitry Chagin PROC_UNLOCK(p); 195*81338031SDmitry Chagin 196*81338031SDmitry Chagin error = kern_execve(td, eargs, NULL); 197*81338031SDmitry Chagin if (error != 0) 198*81338031SDmitry Chagin return (error); 199*81338031SDmitry Chagin 200*81338031SDmitry Chagin /* 201*81338031SDmitry Chagin * In a case of transition from Linux binary execing to 202*81338031SDmitry Chagin * FreeBSD binary we destroy linux emuldata thread entry. 203*81338031SDmitry Chagin */ 204*81338031SDmitry Chagin if (SV_CURPROC_ABI() != SV_ABI_LINUX) { 205*81338031SDmitry Chagin PROC_LOCK(p); 206*81338031SDmitry Chagin em = em_find(td); 207*81338031SDmitry Chagin KASSERT(em != NULL, ("proc_exec: emuldata not found.\n")); 208*81338031SDmitry Chagin td->td_emuldata = NULL; 209*81338031SDmitry Chagin PROC_UNLOCK(p); 210*81338031SDmitry Chagin 211*81338031SDmitry Chagin free(em, M_TEMP); 212*81338031SDmitry Chagin } 213*81338031SDmitry Chagin return (0); 214*81338031SDmitry Chagin } 215*81338031SDmitry Chagin 216*81338031SDmitry Chagin void 217*81338031SDmitry Chagin linux_proc_exec(void *arg __unused, struct proc *p, struct image_params *imgp) 218*81338031SDmitry Chagin { 219*81338031SDmitry Chagin struct thread *td = curthread; 220*81338031SDmitry Chagin 221*81338031SDmitry Chagin /* 222*81338031SDmitry Chagin * In a case of execing to linux binary we create linux 223*81338031SDmitry Chagin * emuldata thread entry. 224*81338031SDmitry Chagin */ 225*81338031SDmitry Chagin if (__predict_false((imgp->sysent->sv_flags & SV_ABI_MASK) == 226*81338031SDmitry Chagin SV_ABI_LINUX)) { 227*81338031SDmitry Chagin LIN_SDT_PROBE2(emul, proc_exec, entry, p, imgp); 228*81338031SDmitry Chagin if (SV_PROC_ABI(p) == SV_ABI_LINUX) 229*81338031SDmitry Chagin linux_proc_init(td, NULL, 0); 230*81338031SDmitry Chagin else 231*81338031SDmitry Chagin linux_proc_init(td, td, 0); 232*81338031SDmitry Chagin 233*81338031SDmitry Chagin LIN_SDT_PROBE0(emul, proc_exec, return); 234*81338031SDmitry Chagin } 235*81338031SDmitry Chagin } 236*81338031SDmitry Chagin 237*81338031SDmitry Chagin void 238*81338031SDmitry Chagin linux_thread_detach(struct thread *td) 239*81338031SDmitry Chagin { 240*81338031SDmitry Chagin struct linux_sys_futex_args cup; 241*81338031SDmitry Chagin struct linux_emuldata *em; 242*81338031SDmitry Chagin int *child_clear_tid; 243*81338031SDmitry Chagin int null = 0; 244*81338031SDmitry Chagin int error; 245*81338031SDmitry Chagin 246*81338031SDmitry Chagin LIN_SDT_PROBE1(emul, linux_thread_detach, entry, td); 247*81338031SDmitry Chagin 248*81338031SDmitry Chagin em = em_find(td); 249*81338031SDmitry Chagin KASSERT(em != NULL, ("thread_detach: emuldata not found.\n")); 250*81338031SDmitry Chagin 251*81338031SDmitry Chagin LINUX_CTR1(exit, "thread detach(%d)", em->em_tid); 252*81338031SDmitry Chagin 253*81338031SDmitry Chagin release_futexes(td, em); 254*81338031SDmitry Chagin 255*81338031SDmitry Chagin child_clear_tid = em->child_clear_tid; 256bb63fddeSAlexander Leidinger 257ad2056f2SAlexander Leidinger if (child_clear_tid != NULL) { 258*81338031SDmitry Chagin 259*81338031SDmitry Chagin LINUX_CTR2(exit, "thread detach(%d) %p", 260*81338031SDmitry Chagin em->em_tid, child_clear_tid); 261ad2056f2SAlexander Leidinger 262ad2056f2SAlexander Leidinger error = copyout(&null, child_clear_tid, sizeof(null)); 26328638377SAlexander Leidinger if (error) { 264*81338031SDmitry Chagin LIN_SDT_PROBE1(emul, linux_thread_detach, 26519e252baSAlexander Leidinger child_clear_tid_error, error); 26619e252baSAlexander Leidinger 267*81338031SDmitry Chagin LIN_SDT_PROBE0(emul, linux_thread_detach, return); 268ad2056f2SAlexander Leidinger return; 26928638377SAlexander Leidinger } 270ad2056f2SAlexander Leidinger 271ad2056f2SAlexander Leidinger cup.uaddr = child_clear_tid; 272ad2056f2SAlexander Leidinger cup.op = LINUX_FUTEX_WAKE; 273ad2056f2SAlexander Leidinger cup.val = 0x7fffffff; /* Awake everyone */ 274ad2056f2SAlexander Leidinger cup.timeout = NULL; 275ad2056f2SAlexander Leidinger cup.uaddr2 = NULL; 276ad2056f2SAlexander Leidinger cup.val3 = 0; 277*81338031SDmitry Chagin error = linux_sys_futex(td, &cup); 2780eef2f8aSAlexander Leidinger /* 279a628609eSAlexander Leidinger * this cannot happen at the moment and if this happens it 280802e08a3SAlexander Leidinger * probably means there is a user space bug 281ad2056f2SAlexander Leidinger */ 28219e252baSAlexander Leidinger if (error) { 283*81338031SDmitry Chagin LIN_SDT_PROBE0(emul, linux_thread_detach, futex_failed); 284*81338031SDmitry Chagin printf(LMSG("futex stuff in thread_detach failed.\n")); 285ad2056f2SAlexander Leidinger } 28619e252baSAlexander Leidinger } 287ad2056f2SAlexander Leidinger 288*81338031SDmitry Chagin LIN_SDT_PROBE0(emul, linux_thread_detach, return); 289ad2056f2SAlexander Leidinger } 290ad2056f2SAlexander Leidinger 291a628609eSAlexander Leidinger void 292*81338031SDmitry Chagin linux_thread_dtor(void *arg __unused, struct thread *td) 293ad2056f2SAlexander Leidinger { 294ad2056f2SAlexander Leidinger struct linux_emuldata *em; 295ad2056f2SAlexander Leidinger 296*81338031SDmitry Chagin em = em_find(td); 297*81338031SDmitry Chagin if (em == NULL) 298*81338031SDmitry Chagin return; 299*81338031SDmitry Chagin td->td_emuldata = NULL; 300ad2056f2SAlexander Leidinger 301*81338031SDmitry Chagin LINUX_CTR1(exit, "thread dtor(%d)", em->em_tid); 302ad2056f2SAlexander Leidinger 303*81338031SDmitry Chagin free(em, M_TEMP); 304ad2056f2SAlexander Leidinger } 305ad2056f2SAlexander Leidinger 306ad2056f2SAlexander Leidinger void 307e5d81ef1SDmitry Chagin linux_schedtail(struct thread *td) 308ad2056f2SAlexander Leidinger { 309ad2056f2SAlexander Leidinger struct linux_emuldata *em; 310e5d81ef1SDmitry Chagin struct proc *p; 311ad2056f2SAlexander Leidinger int error = 0; 312ad2056f2SAlexander Leidinger int *child_set_tid; 313ad2056f2SAlexander Leidinger 314*81338031SDmitry Chagin LIN_SDT_PROBE1(emul, linux_schedtail, entry, td); 315*81338031SDmitry Chagin 316e5d81ef1SDmitry Chagin p = td->td_proc; 317e5d81ef1SDmitry Chagin 318*81338031SDmitry Chagin em = em_find(td); 31925954d74SKonstantin Belousov KASSERT(em != NULL, ("linux_schedtail: emuldata not found.\n")); 320ad2056f2SAlexander Leidinger child_set_tid = em->child_set_tid; 321ad2056f2SAlexander Leidinger 32219e252baSAlexander Leidinger if (child_set_tid != NULL) { 323*81338031SDmitry Chagin error = copyout(&em->em_tid, (int *)child_set_tid, 324*81338031SDmitry Chagin sizeof(em->em_tid)); 325*81338031SDmitry Chagin LINUX_CTR4(clone, "schedtail(%d) %p stored %d error %d", 326*81338031SDmitry Chagin td->td_tid, child_set_tid, em->em_tid, error); 327ad2056f2SAlexander Leidinger 32819e252baSAlexander Leidinger if (error != 0) { 32919e252baSAlexander Leidinger LIN_SDT_PROBE1(emul, linux_schedtail, copyout_error, 33019e252baSAlexander Leidinger error); 33119e252baSAlexander Leidinger } 332*81338031SDmitry Chagin } else 333*81338031SDmitry Chagin LINUX_CTR1(clone, "schedtail(%d)", em->em_tid); 33419e252baSAlexander Leidinger 33519e252baSAlexander Leidinger LIN_SDT_PROBE0(emul, linux_schedtail, return); 336ad2056f2SAlexander Leidinger } 337ad2056f2SAlexander Leidinger 338ad2056f2SAlexander Leidinger int 339ad2056f2SAlexander Leidinger linux_set_tid_address(struct thread *td, struct linux_set_tid_address_args *args) 340ad2056f2SAlexander Leidinger { 341ad2056f2SAlexander Leidinger struct linux_emuldata *em; 342ad2056f2SAlexander Leidinger 34319e252baSAlexander Leidinger LIN_SDT_PROBE1(emul, linux_set_tid_address, entry, args->tidptr); 344ad2056f2SAlexander Leidinger 345*81338031SDmitry Chagin em = em_find(td); 346ad2056f2SAlexander Leidinger KASSERT(em != NULL, ("set_tid_address: emuldata not found.\n")); 347ad2056f2SAlexander Leidinger 348ad2056f2SAlexander Leidinger em->child_clear_tid = args->tidptr; 349ad2056f2SAlexander Leidinger 350*81338031SDmitry Chagin td->td_retval[0] = em->em_tid; 351*81338031SDmitry Chagin 352*81338031SDmitry Chagin LINUX_CTR3(set_tid_address, "tidptr(%d) %p, returns %d", 353*81338031SDmitry Chagin em->em_tid, args->tidptr, td->td_retval[0]); 35419e252baSAlexander Leidinger 35519e252baSAlexander Leidinger LIN_SDT_PROBE0(emul, linux_set_tid_address, return); 356*81338031SDmitry Chagin return (0); 357bb63fddeSAlexander Leidinger } 358