Changeset View
Changeset View
Standalone View
Standalone View
sys/compat/linux/linux_emul.c
Show All 36 Lines | |||||
#include <sys/ktr.h> | #include <sys/ktr.h> | ||||
#include <sys/lock.h> | #include <sys/lock.h> | ||||
#include <sys/malloc.h> | #include <sys/malloc.h> | ||||
#include <sys/mutex.h> | #include <sys/mutex.h> | ||||
#include <sys/sx.h> | #include <sys/sx.h> | ||||
#include <sys/proc.h> | #include <sys/proc.h> | ||||
#include <sys/syscallsubr.h> | #include <sys/syscallsubr.h> | ||||
#include <sys/sysent.h> | #include <sys/sysent.h> | ||||
#include <sys/sysproto.h> | |||||
#include <sys/unistd.h> | |||||
#include <compat/linux/linux_emul.h> | #include <compat/linux/linux_emul.h> | ||||
#include <compat/linux/linux_misc.h> | #include <compat/linux/linux_misc.h> | ||||
#include <compat/linux/linux_util.h> | #include <compat/linux/linux_util.h> | ||||
/* | /* | ||||
* This returns reference to the thread emuldata entry (if found) | * This returns reference to the thread emuldata entry (if found) | ||||
Show All 26 Lines | pem_find(struct proc *p) | ||||
return (pem); | return (pem); | ||||
} | } | ||||
void | void | ||||
linux_proc_init(struct thread *td, struct thread *newtd, int flags) | linux_proc_init(struct thread *td, struct thread *newtd, int flags) | ||||
{ | { | ||||
struct linux_emuldata *em; | struct linux_emuldata *em; | ||||
struct linux_pemuldata *pem; | struct linux_pemuldata *pem; | ||||
struct epoll_emuldata *emd; | |||||
if (newtd != NULL) { | if (newtd != NULL) { | ||||
/* non-exec call */ | /* non-exec call */ | ||||
em = malloc(sizeof(*em), M_TEMP, M_WAITOK | M_ZERO); | em = malloc(sizeof(*em), M_TEMP, M_WAITOK | M_ZERO); | ||||
em->pdeath_signal = 0; | em->pdeath_signal = 0; | ||||
em->robust_futexes = NULL; | em->robust_futexes = NULL; | ||||
if (flags & LINUX_CLONE_THREAD) { | if (flags & LINUX_CLONE_THREAD) { | ||||
LINUX_CTR1(proc_init, "thread newtd(%d)", | |||||
newtd->td_tid); | |||||
em->em_tid = newtd->td_tid; | em->em_tid = newtd->td_tid; | ||||
} else { | } else { | ||||
LINUX_CTR1(proc_init, "fork newtd(%d)", | |||||
newtd->td_proc->p_pid); | |||||
em->em_tid = newtd->td_proc->p_pid; | em->em_tid = newtd->td_proc->p_pid; | ||||
pem = malloc(sizeof(*pem), M_LINUX, M_WAITOK | M_ZERO); | pem = malloc(sizeof(*pem), M_LINUX, M_WAITOK | M_ZERO); | ||||
sx_init(&pem->pem_sx, "lpemlk"); | sx_init(&pem->pem_sx, "lpemlk"); | ||||
newtd->td_proc->p_emuldata = pem; | newtd->td_proc->p_emuldata = pem; | ||||
} | } | ||||
newtd->td_emuldata = em; | newtd->td_emuldata = em; | ||||
} else { | } else { | ||||
/* exec */ | /* exec */ | ||||
LINUX_CTR1(proc_init, "exec newtd(%d)", | |||||
td->td_proc->p_pid); | |||||
/* lookup the old one */ | /* lookup the old one */ | ||||
em = em_find(td); | em = em_find(td); | ||||
KASSERT(em != NULL, ("proc_init: emuldata not found in exec case.\n")); | KASSERT(em != NULL, ("proc_init: emuldata not found in exec case.\n")); | ||||
em->em_tid = td->td_proc->p_pid; | em->em_tid = td->td_proc->p_pid; | ||||
/* epoll should be destroyed in a case of exec. */ | |||||
pem = pem_find(td->td_proc); | |||||
KASSERT(pem != NULL, ("proc_exit: proc emuldata not found.\n")); | |||||
if (pem->epoll != NULL) { | |||||
emd = pem->epoll; | |||||
pem->epoll = NULL; | |||||
free(emd, M_EPOLL); | |||||
} | } | ||||
} | |||||
em->child_clear_tid = NULL; | em->child_clear_tid = NULL; | ||||
em->child_set_tid = NULL; | em->child_set_tid = NULL; | ||||
} | } | ||||
void | void | ||||
linux_proc_exit(void *arg __unused, struct proc *p) | linux_proc_exit(void *arg __unused, struct proc *p) | ||||
{ | { | ||||
struct linux_pemuldata *pem; | struct linux_pemuldata *pem; | ||||
struct epoll_emuldata *emd; | |||||
struct thread *td = curthread; | struct thread *td = curthread; | ||||
if (__predict_false(SV_CURPROC_ABI() != SV_ABI_LINUX)) | if (__predict_false(SV_CURPROC_ABI() != SV_ABI_LINUX)) | ||||
return; | return; | ||||
pem = pem_find(p); | pem = pem_find(p); | ||||
if (pem == NULL) | if (pem == NULL) | ||||
return; | return; | ||||
(p->p_sysent->sv_thread_detach)(td); | (p->p_sysent->sv_thread_detach)(td); | ||||
p->p_emuldata = NULL; | p->p_emuldata = NULL; | ||||
if (pem->epoll != NULL) { | |||||
emd = pem->epoll; | |||||
pem->epoll = NULL; | |||||
free(emd, M_EPOLL); | |||||
} | |||||
sx_destroy(&pem->pem_sx); | sx_destroy(&pem->pem_sx); | ||||
free(pem, M_LINUX); | free(pem, M_LINUX); | ||||
} | } | ||||
int | int | ||||
linux_common_execve(struct thread *td, struct image_args *eargs) | linux_common_execve(struct thread *td, struct image_args *eargs) | ||||
{ | { | ||||
struct linux_pemuldata *pem; | struct linux_pemuldata *pem; | ||||
struct epoll_emuldata *emd; | |||||
struct linux_emuldata *em; | struct linux_emuldata *em; | ||||
struct proc *p; | struct proc *p; | ||||
int error; | int error; | ||||
p = td->td_proc; | p = td->td_proc; | ||||
error = kern_execve(td, eargs, NULL); | error = kern_execve(td, eargs, NULL); | ||||
Show All 19 Lines | if (SV_CURPROC_ABI() != SV_ABI_LINUX) { | ||||
KASSERT(em != NULL, ("proc_exec: thread emuldata not found.\n")); | KASSERT(em != NULL, ("proc_exec: thread emuldata not found.\n")); | ||||
td->td_emuldata = NULL; | td->td_emuldata = NULL; | ||||
pem = pem_find(p); | pem = pem_find(p); | ||||
KASSERT(pem != NULL, ("proc_exec: proc pemuldata not found.\n")); | KASSERT(pem != NULL, ("proc_exec: proc pemuldata not found.\n")); | ||||
p->p_emuldata = NULL; | p->p_emuldata = NULL; | ||||
PROC_UNLOCK(p); | PROC_UNLOCK(p); | ||||
if (pem->epoll != NULL) { | |||||
emd = pem->epoll; | |||||
pem->epoll = NULL; | |||||
free(emd, M_EPOLL); | |||||
} | |||||
free(em, M_TEMP); | free(em, M_TEMP); | ||||
free(pem, M_LINUX); | free(pem, M_LINUX); | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
void | void | ||||
linux_proc_exec(void *arg __unused, struct proc *p, struct image_params *imgp) | linux_proc_exec(void *arg __unused, struct proc *p, struct image_params *imgp) | ||||
{ | { | ||||
struct thread *td = curthread; | struct thread *td = curthread; | ||||
/* | /* | ||||
* In a case of execing to linux binary we create linux | * In a case of execing to linux binary we create linux | ||||
* emuldata thread entry. | * emuldata thread entry. | ||||
*/ | */ | ||||
if (__predict_false((imgp->sysent->sv_flags & SV_ABI_MASK) == | if (__predict_false((imgp->sysent->sv_flags & SV_ABI_MASK) == | ||||
SV_ABI_LINUX)) { | SV_ABI_LINUX)) { | ||||
if (SV_PROC_ABI(p) == SV_ABI_LINUX) | if (SV_PROC_ABI(p) == SV_ABI_LINUX) | ||||
linux_proc_init(td, NULL, 0); | linux_proc_init(td, NULL, 0); | ||||
else | else | ||||
linux_proc_init(td, td, 0); | linux_proc_init(td, td, 0); | ||||
} | } | ||||
} | } | ||||
void | void | ||||
Show All 36 Lines |