Date: Sun, 13 Aug 2006 13:05:34 GMT From: Roman Divacky <rdivacky@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 103757 for review Message-ID: <200608131305.k7DD5Yxh018484@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=103757 Change 103757 by rdivacky@rdivacky_witten on 2006/08/13 13:04:55 Move code between MI and MD sources. Affected files ... .. //depot/projects/soc2006/rdivacky_linuxolator/compat/linux/linux_emul.c#1 add .. //depot/projects/soc2006/rdivacky_linuxolator/compat/linux/linux_emul.h#1 add .. //depot/projects/soc2006/rdivacky_linuxolator/compat/linux/linux_misc.c#12 edit .. //depot/projects/soc2006/rdivacky_linuxolator/compat/linux/linux_signal.c#5 edit .. //depot/projects/soc2006/rdivacky_linuxolator/compat/linux/linux_time.c#4 edit .. //depot/projects/soc2006/rdivacky_linuxolator/i386/linux/linux.h#17 edit .. //depot/projects/soc2006/rdivacky_linuxolator/i386/linux/linux_machdep.c#44 edit .. //depot/projects/soc2006/rdivacky_linuxolator/modules/linux/Makefile#7 edit Differences ... ==== //depot/projects/soc2006/rdivacky_linuxolator/compat/linux/linux_misc.c#12 (text+ko) ==== @@ -74,6 +74,7 @@ #include <posix4/sched.h> #include <compat/linux/linux_sysproto.h> +#include <compat/linux/linux_emul.h> #ifdef COMPAT_LINUX32 #include <machine/../linux32/linux.h> @@ -1349,6 +1350,19 @@ } int +linux_gettid(struct thread *td, struct linux_gettid_args *args) +{ +#ifdef DEBUG + if (ldebug(gettid)) + printf(ARGS(gettid, "")); +#endif + + td->td_retval[0] = td->td_proc->p_pid; + return (0); +} + + +int linux_getppid(struct thread *td, struct linux_getppid_args *args) { #ifdef LINUX_NTPL @@ -1450,3 +1464,39 @@ args->len, 0, 0)); } +int +linux_exit_group(struct thread *td, struct linux_exit_group_args *args) +{ + struct linux_emuldata *em, *td_em, *tmp_em; + struct proc *sp; + +#ifdef DEBUG + if (ldebug(exit_group)) + printf(ARGS(exit_group, "%i"), args->error_code); +#endif + + td_em = em_find(td->td_proc, EMUL_UNLOCKED); + + KASSERT(td_em != NULL, ("exit_group: emuldata not found.\n")); + + EMUL_SHARED_RLOCK(&emul_shared_lock); + LIST_FOREACH_SAFE(em, &td_em->shared->threads, threads, tmp_em) { + if (em->pid == td_em->pid) + continue; + + sp = pfind(em->pid); + psignal(sp, SIGKILL); + PROC_UNLOCK(sp); +#ifdef DEBUG + printf(LMSG("linux_sys_exit_group: kill PID %d\n"), em->pid); +#endif + } + + EMUL_SHARED_RUNLOCK(&emul_shared_lock); + EMUL_UNLOCK(&emul_lock); + + exit1(td, W_EXITCODE(args->error_code,0)); + + return (0); +} + ==== //depot/projects/soc2006/rdivacky_linuxolator/compat/linux/linux_signal.c#5 (text+ko) ==== @@ -49,6 +49,7 @@ #endif #include <compat/linux/linux_signal.h> #include <compat/linux/linux_util.h> +#include <compat/linux/linux_emul.h> extern struct sx emul_shared_lock; extern struct sx emul_lock; @@ -493,3 +494,14 @@ return linux_kill(td, &ka); } + +int +linux_tkill(struct thread *td, struct linux_tkill_args *args) +{ +#ifdef DEBUG + if (ldebug(tkill)) + printf(ARGS(tkill, "%i, %i"), args->tid, args->sig); +#endif + + return (linux_kill(td, (struct linux_kill_args *) args)); +} ==== //depot/projects/soc2006/rdivacky_linuxolator/compat/linux/linux_time.c#4 (text+ko) ==== @@ -201,34 +201,3 @@ return 0; } - -/* copied from kern/kern_time.c */ -int -linux_timer_create(struct thread *td, struct linux_timer_create_args *args) -{ - return ktimer_create(td, (struct ktimer_create_args *) args); -} - -int -linux_timer_settime(struct thread *td, struct linux_timer_settime_args *args) -{ - return ktimer_settime(td, (struct ktimer_settime_args *) args); -} - -int -linux_timer_gettime(struct thread *td, struct linux_timer_gettime_args *args) -{ - return ktimer_gettime(td, (struct ktimer_gettime_args *) args); -} - -int -linux_timer_getoverrun(struct thread *td, struct linux_timer_getoverrun_args *args) -{ - return ktimer_getoverrun(td, (struct ktimer_getoverrun_args *) args); -} - -int -linux_timer_delete(struct thread *td, struct linux_timer_delete_args *args) -{ - return ktimer_delete(td, (struct ktimer_delete_args *) args); -} ==== //depot/projects/soc2006/rdivacky_linuxolator/i386/linux/linux.h#17 (text+ko) ==== @@ -781,41 +781,6 @@ #define GET_PRESENT(desc) (((desc)->b >> ENTRY_B_SEG_NOT_PRESENT) & 1) #define GET_USEABLE(desc) (((desc)->b >> ENTRY_B_USEABLE) & 1) -struct linux_emuldata_shared { - int refs; - pid_t group_pid; - - LIST_HEAD(, linux_emuldata) threads; /* head of list of linux threads */ -}; - -/* modeled after similar structure in NetBSD - * this will be extended as we need more functionality - */ -struct linux_emuldata { - pid_t pid; - - int *child_set_tid; /* in clone(): Child's TID to set on clone */ - int *child_clear_tid; /* in clone(): Child's TID to clear on exit */ - - struct linux_emuldata_shared *shared; - - LIST_ENTRY(linux_emuldata) threads; /* list of linux threads */ -}; - -struct linux_emuldata *em_find(struct proc *, int locked); - -#define EMUL_LOCK(l) sx_xlock(l) -#define EMUL_UNLOCK(l) sx_xunlock(l) - -#define EMUL_SHARED_RLOCK(l) sx_slock(l) -#define EMUL_SHARED_RUNLOCK(l) sx_sunlock(l) -#define EMUL_SHARED_WLOCK(l) sx_xlock(l) -#define EMUL_SHARED_WUNLOCK(l) sx_xunlock(l) - -/* for em_find use */ -#define EMUL_LOCKED 1 -#define EMUL_UNLOCKED 0 - #define LINUX_CLOCK_REALTIME 0 #define LINUX_CLOCK_MONOTONIC 1 #define LINUX_CLOCK_PROCESS_CPUTIME_ID 2 @@ -826,4 +791,18 @@ typedef int l_timer_t; typedef int l_mqd_t; +#define CLONE_VM 0x100 +#define CLONE_FS 0x200 +#define CLONE_FILES 0x400 +#define CLONE_SIGHAND 0x800 +#define CLONE_PID 0x1000 /* this flag does not exist in linux */ +#define CLONE_PARENT 0x00008000 +#define CLONE_THREAD 0x10000 +#define CLONE_SETTLS 0x80000 +#define CLONE_CHILD_CLEARTID 0x00200000 +#define CLONE_CHILD_SETTID 0x01000000 +#define CLONE_PARENT_SETTID 0x00100000 + +#define THREADING_FLAGS (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND) + #endif /* !_I386_LINUX_LINUX_H_ */ ==== //depot/projects/soc2006/rdivacky_linuxolator/i386/linux/linux_machdep.c#44 (text+ko) ==== @@ -58,20 +58,15 @@ #include <i386/linux/linux.h> #include <i386/linux/linux_proto.h> -#include <compat/linux/linux_futex.h> #include <compat/linux/linux_ipc.h> #include <compat/linux/linux_signal.h> #include <compat/linux/linux_util.h> +#include <compat/linux/linux_emul.h> #include <i386/include/pcb.h> /* needed for pcb definition in linux_set_thread_area */ -static int linux_proc_init(struct thread *, pid_t, int); -void linux_proc_exit(void *, struct proc *); -void linux_schedtail(void *, struct proc *); -void linux_proc_exec(void *, struct proc *, struct image_params *); - -struct sx emul_shared_lock; -struct sx emul_lock; +extern struct sx emul_shared_lock; +extern struct sx emul_lock; extern struct sysentvec elf32_freebsd_sysvec; /* defined in i386/i386/elf_machdep.c */ @@ -296,23 +291,6 @@ return (linux_select(td, &newsel)); } -/* this returns locked reference to the emuldata entry (if found) */ -struct linux_emuldata * -em_find(struct proc *p, int locked) -{ - struct linux_emuldata *em; - - if (locked == EMUL_UNLOCKED) - EMUL_LOCK(&emul_lock); - - em = p->p_emuldata; - - if (em == NULL && locked == EMUL_UNLOCKED) - EMUL_UNLOCK(&emul_lock); - - return (em); -} - int linux_fork(struct thread *td, struct linux_fork_args *args) { @@ -356,20 +334,6 @@ return (0); } -#define CLONE_VM 0x100 -#define CLONE_FS 0x200 -#define CLONE_FILES 0x400 -#define CLONE_SIGHAND 0x800 -#define CLONE_PID 0x1000 /* this flag does not exist in linux */ -#define CLONE_PARENT 0x00008000 -#define CLONE_THREAD 0x10000 -#define CLONE_SETTLS 0x80000 -#define CLONE_CHILD_CLEARTID 0x00200000 -#define CLONE_CHILD_SETTID 0x01000000 -#define CLONE_PARENT_SETTID 0x00100000 - -#define THREADING_FLAGS (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND) - int linux_clone(struct thread *td, struct linux_clone_args *args) { @@ -1135,282 +1099,33 @@ return (0); } +/* copied from kern/kern_time.c */ int -linux_gettid(struct thread *td, struct linux_gettid_args *args) +linux_timer_create(struct thread *td, struct linux_timer_create_args *args) { -#ifdef DEBUG - if (ldebug(gettid)) - printf(ARGS(gettid, "")); -#endif - - td->td_retval[0] = td->td_proc->p_pid; - return (0); + return ktimer_create(td, (struct ktimer_create_args *) args); } int -linux_tkill(struct thread *td, struct linux_tkill_args *args) +linux_timer_settime(struct thread *td, struct linux_timer_settime_args *args) { -#ifdef DEBUG - if (ldebug(tkill)) - printf(ARGS(tkill, "%i, %i"), args->tid, args->sig); -#endif - - return (linux_kill(td, (struct linux_kill_args *) args)); + return ktimer_settime(td, (struct ktimer_settime_args *) args); } -static int -linux_proc_init(struct thread *td, pid_t child, int flags) +int +linux_timer_gettime(struct thread *td, struct linux_timer_gettime_args *args) { - struct linux_emuldata *em, *p_em; - struct proc *p; - - /* XXX: locking? */ - if (child != 0) { - /* non-exec call */ - MALLOC(em, struct linux_emuldata *, sizeof *em, M_LINUX, M_WAITOK | M_ZERO); - em->pid = child; - if (flags & CLONE_VM) { - /* handled later in the code */ - } else { - struct linux_emuldata_shared *s; - - MALLOC(s, struct linux_emuldata_shared *, sizeof *s, M_LINUX, M_WAITOK | M_ZERO); - em->shared = s; - s->refs = 1; - s->group_pid = child; - - LIST_INIT(&s->threads); - } - p = pfind(child); - if (p == NULL) - panic("process not found in proc_init\n"); - p->p_emuldata = em; - PROC_UNLOCK(p); - } else { - /* lookup the old one */ - em = em_find(td->td_proc, EMUL_UNLOCKED); - KASSERT(em != NULL, ("proc_init: emuldata not found in exec case.\n")); - } - - em->child_clear_tid = NULL; - em->child_set_tid = NULL; - - /* allocate the shared struct only in clone()/fork cases - * in the case of clone() td = calling proc and child = pid of - * the newly created proc - */ - if (child != 0) { - if (flags & CLONE_VM) { - /* lookup the parent */ - p_em = em_find(td->td_proc, EMUL_LOCKED); - KASSERT(p_em != NULL, ("proc_init: parent emuldata not found for CLONE_VM\n")); - em->shared = p_em->shared; - em->shared->refs++; - } else { - /* handled earlier to avoid malloc(M_WAITOK) with rwlock held */ - } - } - - - if (child != 0) { - EMUL_SHARED_WLOCK(&emul_shared_lock); - LIST_INSERT_HEAD(&em->shared->threads, em, threads); - EMUL_SHARED_WUNLOCK(&emul_shared_lock); - - p = pfind(child); - PROC_UNLOCK(p); - /* we might have a sleeping linux_schedtail */ - wakeup(&p->p_emuldata); - } else - EMUL_UNLOCK(&emul_lock); - - return (0); + return ktimer_gettime(td, (struct ktimer_gettime_args *) args); } -void -linux_proc_exit(void *arg __unused, struct proc *p) -{ - struct linux_emuldata *em; - int error; - struct thread *td = FIRST_THREAD_IN_PROC(p); - int *child_clear_tid; - - if (__predict_true(p->p_sysent != &elf_linux_sysvec)) - return; - - /* find the emuldata */ - em = em_find(p, EMUL_UNLOCKED); - - KASSERT(em != NULL, ("proc_exit: emuldata not found.\n")); - - child_clear_tid = em->child_clear_tid; - - EMUL_UNLOCK(&emul_lock); - - EMUL_SHARED_WLOCK(&emul_shared_lock); - LIST_REMOVE(em, threads); - - PROC_LOCK(p); - p->p_emuldata = NULL; - PROC_UNLOCK(p); - - em->shared->refs--; - if (em->shared->refs == 0) - FREE(em->shared, M_LINUX); - EMUL_SHARED_WUNLOCK(&emul_shared_lock); - - if (child_clear_tid != NULL) { - struct linux_sys_futex_args cup; - int null = 0; - - /* XXX: doesnt futex use the addr? */ - error = copyout(&null, child_clear_tid, sizeof(null)); - if (error) - return; - - /* futexes stuff */ - cup.uaddr = child_clear_tid; - cup.op = LINUX_FUTEX_WAKE; - cup.val = 0x7fffffff; /* Awake everyone */ - cup.timeout = NULL; - cup.uaddr2 = NULL; - cup.val3 = 0; - error = linux_sys_futex(FIRST_THREAD_IN_PROC(p), &cup); - if (error) - printf(LMSG("futex stuff in proc_exit failed.\n")); - } - - /* clean the stuff up */ - FREE(em, M_LINUX); -} - -/* This is used in a case of transition from FreeBSD binary execing to linux binary - * in this case we create linux emuldata proc entry with the pid of the currently running - * process. - */ -void linux_proc_exec(void *arg __unused, struct proc *p, struct image_params *imgp) -{ - if (__predict_false(imgp->sysent == &elf_linux_sysvec - && p->p_sysent != &elf_linux_sysvec)) - linux_proc_init(FIRST_THREAD_IN_PROC(p), p->p_pid, 0); - if (__predict_false(imgp->sysent != &elf_linux_sysvec - && p->p_sysent == &elf_linux_sysvec)) { - struct linux_emuldata *em; - - em = em_find(p, EMUL_UNLOCKED); - - KASSERT(em != NULL, ("proc_exec: emuldata not found.\n")); - - EMUL_UNLOCK(&emul_lock); - - EMUL_SHARED_WLOCK(&emul_shared_lock); - LIST_REMOVE(em, threads); - - PROC_LOCK(p); - p->p_emuldata = NULL; - PROC_UNLOCK(p); - - em->shared->refs--; - if (em->shared->refs == 0) - FREE(em->shared, M_LINUX); - EMUL_SHARED_WUNLOCK(&emul_shared_lock); - - FREE(em, M_LINUX); - } -} - -extern int hz; /* in subr_param.c */ - -void -linux_schedtail(void *arg __unused, struct proc *p) -{ - struct linux_emuldata *em; - int error = 0; -#ifdef DEBUG - struct thread *td = FIRST_THREAD_IN_PROC(p); -#endif - int *child_set_tid; - - if (p->p_sysent != &elf_linux_sysvec) - return; - -retry: - /* find the emuldata */ - em = em_find(p, EMUL_UNLOCKED); - - if (em == NULL) { - /* We might have been called before proc_init for this process so - * tsleep and be woken up by it. We use p->p_emuldata for this - */ - - error = tsleep(&p->p_emuldata, PLOCK, "linux_schedtail", hz); - if (error == 0) - goto retry; - panic("no emuldata found for userreting process.\n"); - } - child_set_tid = em->child_set_tid; - EMUL_UNLOCK(&emul_lock); - - if (child_set_tid != NULL) - error = copyout(&p->p_pid, (int *) child_set_tid, sizeof(p->p_pid)); - - return; -} - int -linux_set_tid_address(struct thread *td, struct linux_set_tid_address_args *args) +linux_timer_getoverrun(struct thread *td, struct linux_timer_getoverrun_args *args) { - struct linux_emuldata *em; - -#ifdef DEBUG - if (ldebug(set_tid_address)) - printf(ARGS(set_tid_address, "%p"), args->tidptr); -#endif - - /* find the emuldata */ - em = em_find(td->td_proc, EMUL_UNLOCKED); - - KASSERT(em != NULL, ("set_tid_address: emuldata not found.\n")); - - em->child_clear_tid = args->tidptr; - td->td_retval[0] = td->td_proc->p_pid; - - EMUL_UNLOCK(&emul_lock); - return 0; + return ktimer_getoverrun(td, (struct ktimer_getoverrun_args *) args); } int -linux_exit_group(struct thread *td, struct linux_exit_group_args *args) +linux_timer_delete(struct thread *td, struct linux_timer_delete_args *args) { - struct linux_emuldata *em, *td_em, *tmp_em; - struct proc *sp; - -#ifdef DEBUG - if (ldebug(exit_group)) - printf(ARGS(exit_group, "%i"), args->error_code); -#endif - - td_em = em_find(td->td_proc, EMUL_UNLOCKED); - - KASSERT(td_em != NULL, ("exit_group: emuldata not found.\n")); - - EMUL_SHARED_RLOCK(&emul_shared_lock); - LIST_FOREACH_SAFE(em, &td_em->shared->threads, threads, tmp_em) { - if (em->pid == td_em->pid) - continue; - - sp = pfind(em->pid); - psignal(sp, SIGKILL); - PROC_UNLOCK(sp); -#ifdef DEBUG - printf(LMSG("linux_sys_exit_group: kill PID %d\n"), em->pid); -#endif - } - - EMUL_SHARED_RUNLOCK(&emul_shared_lock); - EMUL_UNLOCK(&emul_lock); - - exit1(td, W_EXITCODE(args->error_code,0)); - - return (0); + return ktimer_delete(td, (struct ktimer_delete_args *) args); } ==== //depot/projects/soc2006/rdivacky_linuxolator/modules/linux/Makefile#7 (text+ko) ==== @@ -8,7 +8,7 @@ .PATH: ${.CURDIR}/../../compat/linux ${.CURDIR}/../../${MACHINE_ARCH}/linux${SFX} KMOD= linux -SRCS= linux${SFX}_dummy.c linux_file.c linux_futex.c linux_getcwd.c linux_ioctl.c \ +SRCS= linux${SFX}_dummy.c linux_emul.c linux_file.c linux_futex.c linux_getcwd.c linux_ioctl.c \ linux_ipc.c linux${SFX}_machdep.c linux_mib.c linux_misc.c linux_signal.c \ linux_socket.c linux_stats.c linux_sysctl.c linux${SFX}_sysent.c linux${SFX}_sysvec.c \ linux_uid16.c linux_util.c linux_time.c opt_inet6.h opt_mac.h opt_compat.h opt_posix.h \
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200608131305.k7DD5Yxh018484>