From owner-p4-projects@FreeBSD.ORG Mon Jul 24 14:11:16 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 7D5AD16A4E5; Mon, 24 Jul 2006 14:11:16 +0000 (UTC) X-Original-To: perforce@FreeBSD.org Delivered-To: perforce@FreeBSD.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 4122316A4E1 for ; Mon, 24 Jul 2006 14:11:16 +0000 (UTC) (envelope-from rdivacky@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 9A8BB43D58 for ; Mon, 24 Jul 2006 14:11:15 +0000 (GMT) (envelope-from rdivacky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id k6OEBFGA090787 for ; Mon, 24 Jul 2006 14:11:15 GMT (envelope-from rdivacky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id k6OEBFMC090784 for perforce@freebsd.org; Mon, 24 Jul 2006 14:11:15 GMT (envelope-from rdivacky@FreeBSD.org) Date: Mon, 24 Jul 2006 14:11:15 GMT Message-Id: <200607241411.k6OEBFMC090784@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to rdivacky@FreeBSD.org using -f From: Roman Divacky To: Perforce Change Reviews Cc: Subject: PERFORCE change 102283 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 24 Jul 2006 14:11:16 -0000 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;