PERFORCE change 102283 for review

Roman Divacky rdivacky at FreeBSD.org
Mon Jul 24 14:11:16 UTC 2006


http://perforce.freebsd.org/chv.cgi?CH=102283

Change 102283 by rdivacky at 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;			


More information about the p4-projects mailing list