PERFORCE change 103757 for review
Roman Divacky
rdivacky at FreeBSD.org
Sun Aug 13 13:05:35 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=103757
Change 103757 by rdivacky at 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 \
More information about the p4-projects
mailing list