PERFORCE change 104585 for review
Roman Divacky
rdivacky at FreeBSD.org
Sun Aug 20 09:08:51 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=104585
Change 104585 by rdivacky at rdivacky_witten on 2006/08/20 09:08:45
MI parts of amd64 linuxoaltor. Not working yet.
Affected files ...
.. //depot/projects/soc2006/rdivacky_linuxolator/amd64/linux32/linux32_machdep.c#9 edit
.. //depot/projects/soc2006/rdivacky_linuxolator/compat/linux/linux_misc.c#24 edit
Differences ...
==== //depot/projects/soc2006/rdivacky_linuxolator/amd64/linux32/linux32_machdep.c#9 (text+ko) ====
@@ -60,6 +60,7 @@
#include <compat/linux/linux_ipc.h>
#include <compat/linux/linux_signal.h>
#include <compat/linux/linux_util.h>
+#include <compat/linux/linux_emul.h>
struct l_old_select_argv {
l_int nfds;
@@ -211,6 +212,14 @@
free(path, 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 (td->td_proc->p_sysent == &elf_linux_sysvec)
+ error = linux_proc_init(td, 0, 0);
return (error);
}
@@ -452,6 +461,10 @@
if (td->td_retval[1] == 1)
td->td_retval[0] = 0;
+ error = linux_proc_init(td, td->td_retval[0], 0);
+ if (error)
+ return (error);
+
return (0);
}
@@ -470,6 +483,9 @@
/* Are we the child? */
if (td->td_retval[1] == 1)
td->td_retval[0] = 0;
+ error = linux_proc_init(td, td->td_retval[0], 0);
+ if (error)
+ return (error);
return (0);
}
@@ -480,12 +496,14 @@
struct proc *p2;
struct thread *td2;
int exit_signal;
+ struct linux_emuldata *em;
#ifdef DEBUG
if (ldebug(clone)) {
- printf(ARGS(clone, "flags %x, stack %x"),
- (unsigned int)(uintptr_t)args->flags,
- (unsigned int)(uintptr_t)args->stack);
+ printf(ARGS(clone, "flags %x, stack %x, parent tid: %x, child tid: %x"),
+ (unsigned int)args->flags, (unsigned int)(uintptr_t)args->stack,
+ (unsigned int)(uintptr_t)args->parent_tidptr,
+ (unsigned int)(uintptr_t)args->child_tidptr);
}
#endif
@@ -503,11 +521,75 @@
if (!(args->flags & CLONE_FILES))
ff |= RFFDG;
+ /*
+ * Attempt to detect when linux_clone(2) is used for creating
+ * kernel threads. Unfortunately despite the existence of the
+ * CLONE_THREAD flag, version of linuxthreads package used in
+ * most popular distros as of beginning of 2005 doesn't make
+ * any use of it. Therefore, this detection relay fully on
+ * empirical observation that linuxthreads sets certain
+ * combination of flags, so that we can make more or less
+ * precise detection and notify the FreeBSD kernel that several
+ * processes are in fact part of the same threading group, so
+ * that special treatment is necessary for signal delivery
+ * between those processes and fd locking.
+ */
+ if ((args->flags & 0xffffff00) == THREADING_FLAGS)
+ ff |= RFTHREAD;
+
error = fork1(td, ff, 0, &p2);
if (error)
return (error);
+ /* create the emuldata */
+ error = linux_proc_init(td, p2->p_pid, args->flags);
+ /* reference it - no need to check this */
+ em = em_find(p2, EMUL_UNLOCKED);
+ KASSERT(em != NULL, ("clone: emuldata not found.\n"));
+ /* and adjust it */
+ if (args->flags & CLONE_PARENT_SETTID) {
+ if (args->parent_tidptr == NULL) {
+ EMUL_UNLOCK(&emul_lock);
+ return (EINVAL);
+ }
+ error = copyout(&p2->p_pid, args->parent_tidptr, sizeof(p2->p_pid));
+ if (error) {
+ EMUL_UNLOCK(&emul_lock);
+ return (error);
+ }
+ }
+
+ if (args->flags & CLONE_PARENT) {
+#ifdef DEBUG
+ printf("linux_clone: CLONE_PARENT\n");
+#endif
+ }
+
+ if (args->flags & CLONE_THREAD) {
+ /* XXX: linux mangles pgrp and pptr somehow
+ * I think it might be this but I am not sure.
+ */
+#ifdef notyet
+ p2->p_pgrp = td->td_proc->p_pgrp;
+ p2->p_pptr = td->td_proc->p_pptr;
+#endif
+ exit_signal = 0;
+#ifdef DEBUG
+ printf("linux_clone: CLONE_THREADS\n");
+#endif
+ }
+ if (args->flags & CLONE_CHILD_SETTID)
+ em->child_set_tid = args->child_tidptr;
+ else
+ em->child_set_tid = NULL;
+
+ if (args->flags & CLONE_CHILD_CLEARTID)
+ em->child_clear_tid = args->child_tidptr;
+ else
+ em->child_clear_tid = NULL;
+ EMUL_UNLOCK(&emul_lock);
+
PROC_LOCK(p2);
p2->p_sigparent = exit_signal;
PROC_UNLOCK(p2);
@@ -519,6 +601,10 @@
if (args->stack)
td2->td_frame->tf_rsp = PTROUT(args->stack);
+ if (args->flags & CLONE_SETTLS) {
+ /* XXX: todo */
+ }
+
#ifdef DEBUG
if (ldebug(clone))
printf(LMSG("clone: successful rfork to %ld, stack %p sig = %d"),
==== //depot/projects/soc2006/rdivacky_linuxolator/compat/linux/linux_misc.c#24 (text+ko) ====
@@ -1331,7 +1331,6 @@
int
linux_getpid(struct thread *td, struct linux_getpid_args *args)
{
-#ifdef __i386__
struct linux_emuldata *em;
char osrel[LINUX_MAX_UTSNAME];
@@ -1346,11 +1345,7 @@
td->td_retval[0] = td->td_proc->p_pid;
PROC_UNLOCK(td->td_proc);
}
-#else
- PROC_LOCK(td->td_proc);
- td->td_retval[0] = td->td_proc->p_pid;
- PROC_UNLOCK(td->td_proc);
-#endif
+
return (0);
}
@@ -1370,7 +1365,6 @@
int
linux_getppid(struct thread *td, struct linux_getppid_args *args)
{
-#ifdef __i386__
struct linux_emuldata *em;
struct proc *p, *pp;
char osrel[LINUX_MAX_UTSNAME];
@@ -1412,9 +1406,6 @@
EMUL_UNLOCK(&emul_lock);
PROC_UNLOCK(pp);
-#else
- return getppid(td, (struct getppid_args *) args);
-#endif
return (0);
}
@@ -1481,7 +1472,6 @@
int
linux_exit_group(struct thread *td, struct linux_exit_group_args *args)
{
-#ifdef __i386__
struct linux_emuldata *em, *td_em, *tmp_em;
struct proc *sp;
char osrel[LINUX_MAX_UTSNAME];
@@ -1513,10 +1503,8 @@
EMUL_SHARED_RUNLOCK(&emul_shared_lock);
EMUL_UNLOCK(&emul_lock);
}
-#endif
exit1(td, W_EXITCODE(args->error_code,0));
return (0);
}
-
More information about the p4-projects
mailing list