summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Guenthe <guenther@cvs.openbsd.org>2012-05-24 01:19:17 +0000
committerPhilip Guenthe <guenther@cvs.openbsd.org>2012-05-24 01:19:17 +0000
commit89112fc737b1fd0902aa84d9fa0488f9340a79bc (patch)
tree6479d748204430df10f7c2ac5a1394e6a12be6a8
parent620b98d789e9a25233e6bce3255aa99ff0ae03e8 (diff)
If LINUX_CLONE_SETTLS isn't set, then the clone()d child should inherit
the TCB value from the parent instead of having it zeroed. ok pirofti@
-rw-r--r--sys/compat/linux/linux_emuldata.h3
-rw-r--r--sys/compat/linux/linux_sched.c8
2 files changed, 7 insertions, 4 deletions
diff --git a/sys/compat/linux/linux_emuldata.h b/sys/compat/linux/linux_emuldata.h
index 783327715cb..1235db308ae 100644
--- a/sys/compat/linux/linux_emuldata.h
+++ b/sys/compat/linux/linux_emuldata.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: linux_emuldata.h,v 1.8 2011/12/14 08:33:18 robert Exp $ */
+/* $OpenBSD: linux_emuldata.h,v 1.9 2012/05/24 01:19:16 guenther Exp $ */
/* $NetBSD: linux_emuldata.h,v 1.4 2002/02/15 16:48:02 christos Exp $ */
/*-
* Copyright (c) 1998,2002 The NetBSD Foundation, Inc.
@@ -43,6 +43,7 @@ struct linux_emuldata {
void *child_set_tid; /* Let the child set the thread ID at start */
void *child_clear_tid; /* Let the child clear the thread ID on exit */
unsigned child_tls_base;/* Set the Thread Local Storage on clone */
+ int set_tls_base; /* boolean: should my_tls_base be used? */
/* Same as above, passed by the parent when forking. */
void *my_set_tid;
diff --git a/sys/compat/linux/linux_sched.c b/sys/compat/linux/linux_sched.c
index d0a3ea5c88a..cb35647a43b 100644
--- a/sys/compat/linux/linux_sched.c
+++ b/sys/compat/linux/linux_sched.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: linux_sched.c,v 1.12 2012/04/12 15:42:52 guenther Exp $ */
+/* $OpenBSD: linux_sched.c,v 1.13 2012/05/24 01:19:16 guenther Exp $ */
/* $NetBSD: linux_sched.c,v 1.6 2000/05/28 05:49:05 thorpej Exp $ */
/*-
@@ -166,9 +166,10 @@ linux_sys_clone(struct proc *p, void *v, register_t *retval)
if (ldesc.entry_number != GUGS_SEL)
return (EINVAL);
emul->child_tls_base = ldesc.base_addr;
+ emul->set_tls_base = 1;
}
else
- emul->child_tls_base = 0;
+ emul->set_tls_base = 0;
/*
* Note that Linux does not provide a portable way of specifying
@@ -407,7 +408,8 @@ linux_child_return(void *arg)
struct proc *p = (struct proc *)arg;
struct linux_emuldata *emul = p->p_emuldata;
- i386_set_threadbase(p, emul->my_tls_base, TSEG_GS);
+ if (emul->set_tls_base)
+ i386_set_threadbase(p, emul->my_tls_base, TSEG_GS);
if (emul->my_set_tid) {
pid_t pid = p->p_pid + THREAD_PID_OFFSET;