Date: Mon, 24 Jul 2006 14:11:15 GMT From: Roman Divacky <rdivacky@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 102283 for review Message-ID: <200607241411.k6OEBFMC090784@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=102283 Change 102283 by rdivacky@rdivacky_witten on 2006/07/24 14:10:38 Implement CLONE_TLS semantic for clone() syscall. This let me pass my pthread testing stuff (trivial 2 threads program). Also make it compilable without -DDEBUG. Affected files ... .. //depot/projects/soc2006/rdivacky_linuxolator/i386/linux/linux_machdep.c#22 edit Differences ... ==== //depot/projects/soc2006/rdivacky_linuxolator/i386/linux/linux_machdep.c#22 (text+ko) ==== @@ -447,10 +447,6 @@ em->child_clear_tid = NULL; EMUL_RUNLOCK(&emul_lock); - if (args->flags & CLONE_SETTLS) { - /* XXX: set the TLS */ - } - PROC_LOCK(p2); p2->p_sigparent = exit_signal; PROC_UNLOCK(p2); @@ -461,8 +457,64 @@ if (args->stack) td2->td_frame->tf_esp = (unsigned int)args->stack; + if (args->flags & CLONE_SETTLS) { + struct l_user_desc info; + int idx; + int a[2]; + struct segment_descriptor sd; + + error = copyin((void *)td->td_frame->tf_esi, &info, sizeof(struct l_user_desc)); + if (error) + return (error); + + idx = info.entry_number; + + /* looks like we're getting the idx we returned + * in the set_thread_area() syscall + */ + if (idx != 6 && idx != 3) + return (EINVAL); + +#ifdef notyet + /* this doesnt happen in practice */ + if (idx == 6) { + /* we might copy out the entry_number as 3 */ + idx = info.entry_number = 3; + error = copyout(&info, args->desc, sizeof(struct l_user_desc)); + if (error) + return (error); + } +#endif + + a[0] = LDT_entry_a(&info); + a[1] = LDT_entry_b(&info); + + memcpy(&sd, &a, sizeof(a)); #ifdef DEBUG if (ldebug(clone)) + printf("Segment created in clone with CLONE_SETTLS: lobase: %x, hibase: %x, lolimit: %x, hilimit: %x, type: %i, dpl: %i, p: %i, xx: %i, def32: %i, gran: %i\n", sd.sd_lobase, + sd.sd_hibase, + sd.sd_lolimit, + sd.sd_hilimit, + sd.sd_type, + sd.sd_dpl, + sd.sd_p, + sd.sd_xx, + sd.sd_def32, + sd.sd_gran); +#endif + + /* this is taken from i386 version of cpu_set_user_tls() */ + critical_enter(); + /* set %gs */ + td2->td_pcb->pcb_gsd = sd; + PCPU_GET(fsgs_gdt)[1] = sd; + load_gs(GSEL(GUGS_SEL, SEL_UPL)); + critical_exit(); + } + +#ifdef DEBUG + if (ldebug(clone)) printf(LMSG("clone: successful rfork to %ld, stack %p sig = %d"), (long)p2->p_pid, args->stack, exit_signal); #endif @@ -1185,12 +1237,12 @@ if (__predict_false(imgp->sysent == &elf32_freebsd_sysvec && p->p_sysent == &elf_linux_sysvec)) { struct linux_emuldata *em; - struct thread *td = FIRST_THREAD_IN_PROC(p); em = em_find(p->p_pid, EMUL_UNLOCKED); if (em == NULL) { #ifdef DEBUG + struct thread *td = FIRST_THREAD_IN_PROC(p); printf(LMSG("we didnt find emuldata for the execing process.\n")); #endif return;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200607241411.k6OEBFMC090784>