summaryrefslogtreecommitdiffstats
path: root/sys/compat/linux/linux_fork.c
diff options
context:
space:
mode:
authordchagin <dchagin@FreeBSD.org>2016-01-09 16:11:09 +0000
committerdchagin <dchagin@FreeBSD.org>2016-01-09 16:11:09 +0000
commit6c12e20ac1e5ea5573246049365409feabb20095 (patch)
treefaa5068ff72fa5ba5e4a549a627a6eb1509ad298 /sys/compat/linux/linux_fork.c
parentd30e84112a87337209ea45237f3d9b12e29abaa9 (diff)
downloadFreeBSD-src-6c12e20ac1e5ea5573246049365409feabb20095.zip
FreeBSD-src-6c12e20ac1e5ea5573246049365409feabb20095.tar.gz
MFC r283422:
Refund the proc emuldata struct for future use. For now move flags from thread emuldata to proc emuldata as it was originally intended. As we can have both 64 & 32 bit Linuxulator running any eventhandler can be called twice for us. To prevent this move eventhandlers code from linux_emul.c to the linux_common.ko module.
Diffstat (limited to 'sys/compat/linux/linux_fork.c')
-rw-r--r--sys/compat/linux/linux_fork.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/sys/compat/linux/linux_fork.c b/sys/compat/linux/linux_fork.c
index bffe468..f74c9a2 100644
--- a/sys/compat/linux/linux_fork.c
+++ b/sys/compat/linux/linux_fork.c
@@ -59,6 +59,7 @@ __FBSDID("$FreeBSD$");
#endif
#include <compat/linux/linux_signal.h>
#include <compat/linux/linux_emul.h>
+#include <compat/linux/linux_futex.h>
#include <compat/linux/linux_misc.h>
#include <compat/linux/linux_util.h>
@@ -405,3 +406,63 @@ linux_exit(struct thread *td, struct linux_exit_args *args)
exit1(td, W_EXITCODE(args->rval, 0));
/* NOTREACHED */
}
+
+int
+linux_set_tid_address(struct thread *td, struct linux_set_tid_address_args *args)
+{
+ struct linux_emuldata *em;
+
+ em = em_find(td);
+ KASSERT(em != NULL, ("set_tid_address: emuldata not found.\n"));
+
+ em->child_clear_tid = args->tidptr;
+
+ td->td_retval[0] = em->em_tid;
+
+ LINUX_CTR3(set_tid_address, "tidptr(%d) %p, returns %d",
+ em->em_tid, args->tidptr, td->td_retval[0]);
+
+ return (0);
+}
+
+void
+linux_thread_detach(struct thread *td)
+{
+ struct linux_sys_futex_args cup;
+ struct linux_emuldata *em;
+ int *child_clear_tid;
+ int error;
+
+ em = em_find(td);
+ KASSERT(em != NULL, ("thread_detach: emuldata not found.\n"));
+
+ LINUX_CTR1(exit, "thread detach(%d)", em->em_tid);
+
+ release_futexes(td, em);
+
+ child_clear_tid = em->child_clear_tid;
+
+ if (child_clear_tid != NULL) {
+
+ LINUX_CTR2(exit, "thread detach(%d) %p",
+ em->em_tid, child_clear_tid);
+
+ error = suword32(child_clear_tid, 0);
+ if (error != 0)
+ return;
+
+ cup.uaddr = child_clear_tid;
+ cup.op = LINUX_FUTEX_WAKE;
+ cup.val = 1; /* wake one */
+ cup.timeout = NULL;
+ cup.uaddr2 = NULL;
+ cup.val3 = 0;
+ error = linux_sys_futex(td, &cup);
+ /*
+ * this cannot happen at the moment and if this happens it
+ * probably means there is a user space bug
+ */
+ if (error != 0)
+ linux_msg(td, "futex stuff in thread_detach failed.");
+ }
+}
OpenPOWER on IntegriCloud