summaryrefslogtreecommitdiffstats
path: root/sys/i386/linux
diff options
context:
space:
mode:
Diffstat (limited to 'sys/i386/linux')
-rw-r--r--sys/i386/linux/linux_machdep.c19
-rw-r--r--sys/i386/linux/linux_sysvec.c10
2 files changed, 15 insertions, 14 deletions
diff --git a/sys/i386/linux/linux_machdep.c b/sys/i386/linux/linux_machdep.c
index effc32a..d3013e1 100644
--- a/sys/i386/linux/linux_machdep.c
+++ b/sys/i386/linux/linux_machdep.c
@@ -148,15 +148,8 @@ linux_execve(struct thread *td, struct linux_execve_args *args)
free(newpath, M_TEMP);
if (error == 0)
error = kern_execve(td, &eargs, NULL);
- if (error == 0) {
- /* linux process can exec fbsd one, dont attempt
- * to create emuldata for such process using
- * linux_proc_init, this leads to a panic on KASSERT
- * because such process has p->p_emuldata == NULL
- */
- if (SV_PROC_ABI(td->td_proc) == SV_ABI_LINUX)
- error = linux_proc_init(td, 0, 0);
- }
+ if (error == 0)
+ error = linux_common_execve(td, &eargs);
post_execve(td, error, oldvmspace);
return (error);
}
@@ -368,8 +361,14 @@ int
linux_set_upcall_kse(struct thread *td, register_t stack)
{
- td->td_frame->tf_esp = stack;
+ if (stack)
+ td->td_frame->tf_esp = stack;
+ /*
+ * The newly created Linux thread returns
+ * to the user space by the same path that a parent do.
+ */
+ td->td_frame->tf_eax = 0;
return (0);
}
diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c
index 67d5056..0e7ba67 100644
--- a/sys/i386/linux/linux_sysvec.c
+++ b/sys/i386/linux/linux_sysvec.c
@@ -116,6 +116,7 @@ const char *linux_platform;
static eventhandler_tag linux_exit_tag;
static eventhandler_tag linux_exec_tag;
+static eventhandler_tag linux_thread_dtor_tag;
/*
* Linux syscalls return negative errno's, we do positive and map them
@@ -973,6 +974,7 @@ struct sysentvec linux_sysvec = {
.sv_shared_page_base = LINUX_SHAREDPAGE,
.sv_shared_page_len = PAGE_SIZE,
.sv_schedtail = linux_schedtail,
+ .sv_thread_detach = linux_thread_detach,
};
INIT_SYSENTVEC(aout_sysvec, &linux_sysvec);
@@ -1011,6 +1013,7 @@ struct sysentvec elf_linux_sysvec = {
.sv_shared_page_base = LINUX_SHAREDPAGE,
.sv_shared_page_len = PAGE_SIZE,
.sv_schedtail = linux_schedtail,
+ .sv_thread_detach = linux_thread_detach,
};
INIT_SYSENTVEC(elf_sysvec, &elf_linux_sysvec);
@@ -1099,14 +1102,14 @@ linux_elf_modevent(module_t mod, int type, void *data)
linux_ioctl_register_handler(*lihp);
SET_FOREACH(ldhp, linux_device_handler_set)
linux_device_register_handler(*ldhp);
- mtx_init(&emul_lock, "emuldata lock", NULL, MTX_DEF);
- sx_init(&emul_shared_lock, "emuldata->shared lock");
LIST_INIT(&futex_list);
mtx_init(&futex_mtx, "ftllk", NULL, MTX_DEF);
linux_exit_tag = EVENTHANDLER_REGISTER(process_exit, linux_proc_exit,
NULL, 1000);
linux_exec_tag = EVENTHANDLER_REGISTER(process_exec, linux_proc_exec,
NULL, 1000);
+ linux_thread_dtor_tag = EVENTHANDLER_REGISTER(thread_dtor,
+ linux_thread_dtor, NULL, EVENTHANDLER_PRI_ANY);
linux_get_machine(&linux_platform);
linux_szplatform = roundup(strlen(linux_platform) + 1,
sizeof(char *));
@@ -1133,11 +1136,10 @@ linux_elf_modevent(module_t mod, int type, void *data)
linux_ioctl_unregister_handler(*lihp);
SET_FOREACH(ldhp, linux_device_handler_set)
linux_device_unregister_handler(*ldhp);
- mtx_destroy(&emul_lock);
- sx_destroy(&emul_shared_lock);
mtx_destroy(&futex_mtx);
EVENTHANDLER_DEREGISTER(process_exit, linux_exit_tag);
EVENTHANDLER_DEREGISTER(process_exec, linux_exec_tag);
+ EVENTHANDLER_DEREGISTER(thread_dtor, linux_thread_dtor_tag);
linux_osd_jail_deregister();
if (bootverbose)
printf("Linux ELF exec handler removed\n");
OpenPOWER on IntegriCloud