Index: sys/amd64/linux/linux_sysvec.c =================================================================== --- sys/amd64/linux/linux_sysvec.c +++ sys/amd64/linux/linux_sysvec.c @@ -780,6 +780,9 @@ .sv_schedtail = linux_schedtail, .sv_thread_detach = linux_thread_detach, .sv_trap = linux_vsyscall, + .sv_onexec = linux_on_exec, + .sv_onexit = linux_on_exit, + .sv_ontdexit = linux_thread_dtor, }; static void Index: sys/amd64/linux32/linux32_sysvec.c =================================================================== --- sys/amd64/linux32/linux32_sysvec.c +++ sys/amd64/linux32/linux32_sysvec.c @@ -925,6 +925,7 @@ .sv_schedtail = linux_schedtail, .sv_thread_detach = linux_thread_detach, .sv_trap = NULL, + .sv_onexec = linux_on_exec, }; static void Index: sys/arm64/linux/linux_sysvec.c =================================================================== --- sys/arm64/linux/linux_sysvec.c +++ sys/arm64/linux/linux_sysvec.c @@ -419,6 +419,9 @@ .sv_schedtail = linux_schedtail, .sv_thread_detach = linux_thread_detach, .sv_trap = linux_vsyscall, + .sv_onexec = linux_on_exec, + .sv_onexit = linux_on_exit, + .sv_ontdexit = linux_thread_dtor, }; static void Index: sys/compat/linux/linux_common.c =================================================================== --- sys/compat/linux/linux_common.c +++ sys/compat/linux/linux_common.c @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include @@ -71,10 +71,6 @@ struct sx linux_ioctl_sx; SX_SYSINIT(linux_ioctl, &linux_ioctl_sx, "Linux ioctl handlers"); -static eventhandler_tag linux_exec_tag; -static eventhandler_tag linux_thread_dtor_tag; -static eventhandler_tag linux_exit_tag; - static int linux_common_modevent(module_t mod, int type, void *data) { @@ -87,12 +83,6 @@ #endif linux_dev_shm_create(); linux_osd_jail_register(); - 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); SET_FOREACH(ldhp, linux_device_handler_set) linux_device_register_handler(*ldhp); LIST_INIT(&futex_list); @@ -104,9 +94,6 @@ SET_FOREACH(ldhp, linux_device_handler_set) linux_device_unregister_handler(*ldhp); 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); break; default: return (EOPNOTSUPP); Index: sys/compat/linux/linux_emul.h =================================================================== --- sys/compat/linux/linux_emul.h +++ sys/compat/linux/linux_emul.h @@ -52,10 +52,10 @@ int linux_exec_imgact_try(struct image_params *); void linux_proc_init(struct thread *, struct thread *, int); -void linux_proc_exit(void *, struct proc *); +void linux_on_exit(struct proc *); void linux_schedtail(struct thread *); -void linux_proc_exec(void *, struct proc *, struct image_params *); -void linux_thread_dtor(void *arg __unused, struct thread *); +void linux_on_exec(struct proc *, struct image_params *); +void linux_thread_dtor(struct thread *); void linux_thread_detach(struct thread *); int linux_common_execve(struct thread *, struct image_args *); Index: sys/compat/linux/linux_emul.c =================================================================== --- sys/compat/linux/linux_emul.c +++ sys/compat/linux/linux_emul.c @@ -199,14 +199,13 @@ } void -linux_proc_exit(void *arg __unused, struct proc *p) +linux_on_exit(struct proc *p) { struct linux_pemuldata *pem; struct epoll_emuldata *emd; struct thread *td = curthread; - if (__predict_false(SV_CURPROC_ABI() != SV_ABI_LINUX)) - return; + MPASS(SV_CURPROC_ABI() == SV_ABI_LINUX); LINUX_CTR3(proc_exit, "thread(%d) proc(%d) p %p", td->td_tid, p->p_pid, p); @@ -313,7 +312,7 @@ } void -linux_proc_exec(void *arg __unused, struct proc *p, struct image_params *imgp) +linux_on_exec(struct proc *p, struct image_params *imgp) { struct thread *td; struct thread *othertd; @@ -322,55 +321,52 @@ #endif td = curthread; + MPASS((imgp->sysent->sv_flags & SV_ABI_MASK) == SV_ABI_LINUX); /* - * In a case of execing to Linux binary we create Linux - * emuldata thread entry. + * When execing to Linux binary, we create Linux emuldata + * thread entry. */ - if (__predict_false((imgp->sysent->sv_flags & SV_ABI_MASK) == - SV_ABI_LINUX)) { - if (SV_PROC_ABI(p) == SV_ABI_LINUX) { - /* - * Process already was under Linuxolator - * before exec. Update emuldata to reflect - * single-threaded cleaned state after exec. - */ - linux_proc_init(td, NULL, 0); - } else { - /* - * We are switching the process to Linux emulator. - */ - linux_proc_init(td, td, 0); - - /* - * Create a transient td_emuldata for all suspended - * threads, so that p->p_sysent->sv_thread_detach() == - * linux_thread_detach() can find expected but unused - * emuldata. - */ - FOREACH_THREAD_IN_PROC(td->td_proc, othertd) { - if (othertd != td) { - linux_proc_init(td, othertd, - LINUX_CLONE_THREAD); - } - } - } -#if defined(__amd64__) + if (SV_PROC_ABI(p) == SV_ABI_LINUX) { /* - * An IA32 executable which has executable stack will have the - * READ_IMPLIES_EXEC personality flag set automatically. + * Process already was under Linuxolator + * before exec. Update emuldata to reflect + * single-threaded cleaned state after exec. */ - if (SV_PROC_FLAG(td->td_proc, SV_ILP32) && - imgp->stack_prot & VM_PROT_EXECUTE) { - pem = pem_find(p); - pem->persona |= LINUX_READ_IMPLIES_EXEC; + linux_proc_init(td, NULL, 0); + } else { + /* + * We are switching the process to Linux emulator. + */ + linux_proc_init(td, td, 0); + + /* + * Create a transient td_emuldata for all suspended + * threads, so that p->p_sysent->sv_thread_detach() == + * linux_thread_detach() can find expected but unused + * emuldata. + */ + FOREACH_THREAD_IN_PROC(td->td_proc, othertd) { + if (othertd == td) + continue; + linux_proc_init(td, othertd, LINUX_CLONE_THREAD); } -#endif } +#if defined(__amd64__) + /* + * An IA32 executable which has executable stack will have the + * READ_IMPLIES_EXEC personality flag set automatically. + */ + if (SV_PROC_FLAG(td->td_proc, SV_ILP32) && + imgp->stack_prot & VM_PROT_EXECUTE) { + pem = pem_find(p); + pem->persona |= LINUX_READ_IMPLIES_EXEC; + } +#endif } void -linux_thread_dtor(void *arg __unused, struct thread *td) +linux_thread_dtor(struct thread *td) { struct linux_emuldata *em; Index: sys/i386/linux/linux_sysvec.c =================================================================== --- sys/i386/linux/linux_sysvec.c +++ sys/i386/linux/linux_sysvec.c @@ -48,7 +48,6 @@ #include #include #include -#include #include #include @@ -104,10 +103,6 @@ static int linux_szplatform; const char *linux_kplatform; -static eventhandler_tag linux_exit_tag; -static eventhandler_tag linux_exec_tag; -static eventhandler_tag linux_thread_dtor_tag; - #define LINUX_T_UNKNOWN 255 static int _bsd_to_linux_trapcode[] = { LINUX_T_UNKNOWN, /* 0 */ @@ -873,6 +868,9 @@ .sv_schedtail = linux_schedtail, .sv_thread_detach = linux_thread_detach, .sv_trap = NULL, + .sv_onexec = linux_on_exec, + .sv_onexit = linux_on_exit, + .sv_ontdexit = linux_thread_dtor, }; INIT_SYSENTVEC(aout_sysvec, &linux_sysvec); @@ -907,6 +905,9 @@ .sv_schedtail = linux_schedtail, .sv_thread_detach = linux_thread_detach, .sv_trap = NULL, + .sv_onexec = linux_on_exec, + .sv_onexit = linux_on_exit, + .sv_ontdexit = linux_thread_dtor, }; static void @@ -1040,12 +1041,6 @@ linux_ioctl_register_handler(*lihp); 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_kplatform); linux_szplatform = roundup(strlen(linux_kplatform) + 1, sizeof(char *)); @@ -1072,9 +1067,6 @@ SET_FOREACH(lihp, linux_ioctl_handler_set) linux_ioctl_unregister_handler(*lihp); 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_dev_shm_destroy(); linux_osd_jail_deregister(); if (bootverbose) Index: sys/kern/kern_exec.c =================================================================== --- sys/kern/kern_exec.c +++ sys/kern/kern_exec.c @@ -1051,6 +1051,8 @@ sigfastblock_clear(td); umtx_exec(p); itimers_exec(p); + if (sv->sv_onexec != NULL) + sv->sv_onexec(p, imgp); EVENTHANDLER_DIRECT_INVOKE(process_exec, p, imgp); Index: sys/kern/kern_exit.c =================================================================== --- sys/kern/kern_exit.c +++ sys/kern/kern_exit.c @@ -72,6 +72,7 @@ #include #include #include +#include #include #include #ifdef KTRACE @@ -327,6 +328,9 @@ itimers_exit(p); + if (p->p_sysent->sv_onexit != NULL) + p->p_sysent->sv_onexit(p); + /* * Check if any loadable modules need anything done at process exit. * E.g. SYSV IPC stuff. @@ -561,6 +565,9 @@ PROC_LOCK(p); p->p_xthread = td; + if (p->p_sysent->sv_ontdexit != NULL) + p->p_sysent->sv_ontdexit(td); + #ifdef KDTRACE_HOOKS /* * Tell the DTrace fasttrap provider about the exit if it Index: sys/kern/kern_kthread.c =================================================================== --- sys/kern/kern_kthread.c +++ sys/kern/kern_kthread.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -355,6 +356,10 @@ PROC_UNLOCK(p); kproc_exit(0); } + + if (p->p_sysent->sv_ontdexit != NULL) + p->p_sysent->sv_ontdexit(td); + tidhash_remove(td); umtx_thread_exit(td); tdsigcleanup(td); Index: sys/kern/kern_thr.c =================================================================== --- sys/kern/kern_thr.c +++ sys/kern/kern_thr.c @@ -353,6 +353,9 @@ return (0); } + if (p->p_sysent->sv_ontdexit != NULL) + p->p_sysent->sv_ontdexit(td); + td->td_dbgflags |= TDB_EXIT; if (p->p_ptevents & PTRACE_LWP) { p->p_pendingexits++; Index: sys/sys/sysent.h =================================================================== --- sys/sys/sysent.h +++ sys/sys/sysent.h @@ -145,6 +145,9 @@ u_long *sv_hwcap2; /* Value passed in AT_HWCAP2. */ const char *(*sv_machine_arch)(struct proc *); vm_offset_t sv_fxrng_gen_base; + void (*sv_onexec)(struct proc *, struct image_params *); + void (*sv_onexit)(struct proc *); + void (*sv_ontdexit)(struct thread *td); }; #define SV_ILP32 0x000100 /* 32-bit executable. */