PERFORCE change 101643 for review
Roman Divacky
rdivacky at FreeBSD.org
Sat Jul 15 09:05:10 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=101643
Change 101643 by rdivacky at rdivacky_witten on 2006/07/15 09:04:22
Several things at once:
o Change process_exit and process_exec function handlers prototype
to include struct image_params arg.
o Change struct image_params to include struct sysentvec pointer and
initialize it.
o Change all consumers of process_exit/process_exec eventhandlers to
new prototypes
o Change ifdef DEBUG code to actually compile (same was done in linux_futex)
o Move some code from under DEBUG and keep only printfs in DEBUG
o Add eventhandler to userret
o Implement hooks using eventhandlers as jhb suggested
o Remove P_LINUX process flag and its handling
Affected files ...
.. //depot/projects/soc2006/rdivacky_linuxolator/dev/hwpmc/hwpmc_mod.c#2 edit
.. //depot/projects/soc2006/rdivacky_linuxolator/fs/pseudofs/pseudofs_vncache.c#2 edit
.. //depot/projects/soc2006/rdivacky_linuxolator/i386/linux/linux_machdep.c#13 edit
.. //depot/projects/soc2006/rdivacky_linuxolator/i386/linux/linux_sysvec.c#8 edit
.. //depot/projects/soc2006/rdivacky_linuxolator/kern/kern_exec.c#3 edit
.. //depot/projects/soc2006/rdivacky_linuxolator/kern/kern_exit.c#4 edit
.. //depot/projects/soc2006/rdivacky_linuxolator/kern/kern_time.c#2 edit
.. //depot/projects/soc2006/rdivacky_linuxolator/kern/subr_trap.c#3 edit
.. //depot/projects/soc2006/rdivacky_linuxolator/kern/sysv_sem.c#4 edit
.. //depot/projects/soc2006/rdivacky_linuxolator/kern/uipc_mqueue.c#2 edit
.. //depot/projects/soc2006/rdivacky_linuxolator/kern/uipc_sem.c#2 edit
.. //depot/projects/soc2006/rdivacky_linuxolator/kern/vfs_aio.c#3 edit
.. //depot/projects/soc2006/rdivacky_linuxolator/netncp/ncp_subr.c#2 edit
.. //depot/projects/soc2006/rdivacky_linuxolator/sys/eventhandler.h#2 edit
.. //depot/projects/soc2006/rdivacky_linuxolator/sys/imgact.h#2 edit
.. //depot/projects/soc2006/rdivacky_linuxolator/sys/proc.h#3 edit
Differences ...
==== //depot/projects/soc2006/rdivacky_linuxolator/dev/hwpmc/hwpmc_mod.c#2 (text+ko) ====
@@ -182,7 +182,7 @@
static void pmc_maybe_remove_owner(struct pmc_owner *po);
static void pmc_process_csw_in(struct thread *td);
static void pmc_process_csw_out(struct thread *td);
-static void pmc_process_exit(void *arg, struct proc *p);
+static void pmc_process_exit(void *arg, struct proc *p, struct image_params *imgp);
static void pmc_process_fork(void *arg, struct proc *p1,
struct proc *p2, int n);
static void pmc_process_samples(int cpu);
@@ -3814,7 +3814,7 @@
*/
static void
-pmc_process_exit(void *arg __unused, struct proc *p)
+pmc_process_exit(void *arg __unused, struct proc *p, struct image_params *imgp __unused)
{
int is_using_hwpmcs;
int cpu;
==== //depot/projects/soc2006/rdivacky_linuxolator/fs/pseudofs/pseudofs_vncache.c#2 (text+ko) ====
@@ -50,7 +50,7 @@
static struct mtx pfs_vncache_mutex;
static struct pfs_vdata *pfs_vncache;
static eventhandler_tag pfs_exit_tag;
-static void pfs_exit(void *arg, struct proc *p);
+static void pfs_exit(void *arg, struct proc *p, struct image_params *imgp);
SYSCTL_NODE(_vfs_pfs, OID_AUTO, vncache, CTLFLAG_RW, 0,
"pseudofs vnode cache");
@@ -224,7 +224,7 @@
* isn't mounted.
*/
static void
-pfs_exit(void *arg, struct proc *p)
+pfs_exit(void *arg, struct proc *p, struct image_params *imgp __unused)
{
struct pfs_vdata *pvd;
struct vnode *vnp;
==== //depot/projects/soc2006/rdivacky_linuxolator/i386/linux/linux_machdep.c#13 (text+ko) ====
@@ -69,8 +69,9 @@
struct rwlock emul_lock;
static int linux_proc_init(struct thread *, pid_t);
-int linux_proc_exit(struct thread *);
-int linux_userret(struct thread *);
+void linux_proc_exit(void *, struct proc *, struct image_params *);
+void linux_userret(void *, struct proc *);
+void linux_proc_exec(void *, struct proc *, struct image_params *);
static struct linux_emuldata *em_find(pid_t pid, int locked);
struct l_descriptor {
@@ -384,10 +385,9 @@
#ifdef DEBUG
if (ldebug(clone)) {
- printf(ARGS(clone, "flags %x, stack %x, parent tid: %x,
- child tid: %x"),
- (unsigned int)args->flags, (unsigned int)args->stack,
- (unsigned int) args->parent_tidptr, (unsigned int)args->child_tidptr);
+ printf(ARGS(clone, "flags %x, stack %x, parent tid: %x, child tid: %x"),
+ (unsigned int)args->flags, (unsigned int)args->stack,
+ (unsigned int)args->parent_tidptr, (unsigned int)args->child_tidptr);
if (args->flags & CLONE_PID)
printf(LMSG("CLONE_PID not yet supported"));
}
@@ -948,10 +948,10 @@
#ifdef DEBUG
if (ldebug(set_thread_area))
- printf("Args passed to the set_thread_area:\n
- entry number: %i, base address: %i, limit: %i,
- seg32bit: %i, contents: %i, read_exec_only: %i,
- limit in pages: %i, seg_not_present: %i, useable: %i\n",
+ printf(ARGS(set_thread_area, "Args passed to the set_thread_area:\n \
+ entry number: %i, base address: %i, limit: %i, \
+ seg32bit: %i, contents: %i, read_exec_only: %i, \
+ limit in pages: %i, seg_not_present: %i, useable: %i\n"),
info.entry_number,
info.base_addr,
info.limit,
@@ -1006,10 +1006,10 @@
memcpy(&sd, &a, sizeof(a));
#ifdef DEBUG
if (ldebug(set_thread_area))
- printf("Segment created in set_thread_area: \n
- lobase: %x, hibase: %x, lolimit: %x,
- hilimit: %x, type: %i, dpl: %i,
- p: %i, xx: %i, def32: %i, gran: %i\n", sd.sd_lobase,
+ printf(ARGS(set_thread_area, "Segment created in set_thread_area: \n \
+ lobase: %x, hibase: %x, lolimit: %x, \
+ hilimit: %x, type: %i, dpl: %i, \
+ p: %i, xx: %i, def32: %i, gran: %i\n"), sd.sd_lobase,
sd.sd_hibase,
sd.sd_lolimit,
sd.sd_hilimit,
@@ -1093,7 +1093,6 @@
linux_proc_init(struct thread *td, pid_t child)
{
struct linux_emuldata *em, *p_em;
- struct proc *p;
/* XXX: locking? */
if (child != 0) {
@@ -1109,7 +1108,7 @@
if (em == NULL) {
/* this should not happen */
#ifdef DEBUG
- printf("emuldata not found in exec case.\n");
+ printf(LMSG("emuldata not found in exec case.\n"));
#endif
return (0);
}
@@ -1137,33 +1136,28 @@
EMUL_RUNLOCK(&emul_lock);
}
- /* XXX: sched_lock locking? */
-
- /* find the newly created thread and set the P_LINUX flag */
- if (child != 0) {
- p = pfind(child);
- p->p_flag |= P_LINUX;
- PROC_UNLOCK(p);
- }
-
return (0);
}
-int
-linux_proc_exit(struct thread *td)
+void
+linux_proc_exit(void *arg __unused, struct proc *p, struct image_params *imgp __unused)
{
struct linux_emuldata *em;
int error;
+ struct thread *td = FIRST_THREAD_IN_PROC(p);
+
+ if (p->p_sysent != &elf_linux_sysvec)
+ return;
/* find the emuldata */
- em = em_find(td->td_proc->p_pid, EMUL_UNLOCKED);
+ em = em_find(p->p_pid, EMUL_UNLOCKED);
+ if (em == NULL) {
#ifdef DEBUG
- if (em == NULL) {
- printf("we didnt find emuldata for the exiting process.\n");
- return (0);
+ printf(LMSG("we didnt find emuldata for the exiting process.\n"));
+#endif
+ return;
}
-#endif
if (em->clear_tid != NULL) {
struct linux_sys_futex_args cup;
int null = 0;
@@ -1171,7 +1165,7 @@
error = copyout(&null, em->clear_tid, sizeof(null));
if (error) {
EMUL_RUNLOCK(&emul_lock);
- return (error);
+ return;
}
/* futexes stuff */
@@ -1181,9 +1175,9 @@
cup.timeout = NULL;
cup.uaddr2 = NULL;
cup.val3 = 0;
- error = linux_sys_futex(td, &cup);
+ error = linux_sys_futex(FIRST_THREAD_IN_PROC(p), &cup);
if (error)
- printf("futex stuff in proc_exit failed.\n");
+ printf(LMSG("futex stuff in proc_exit failed.\n"));
}
EMUL_RUNLOCK(&emul_lock);
@@ -1197,32 +1191,47 @@
/* clean the stuff up */
FREE(em, M_LINUX);
-
- return (0);
+}
+
+extern struct sysentvec elf32_freebsd_sysvec; /* defined in i386/i386/elf_machdep.c */
+/* 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 == &elf32_freebsd_sysvec))
+ linux_proc_init(FIRST_THREAD_IN_PROC(p), p->p_pid);
}
-int
-linux_userret(struct thread *td)
+void
+linux_userret(void *arg __unused, struct proc *p)
{
struct linux_emuldata *em;
int error = 0;
+ //struct thread *td = FIRST_THREAD_IN_PROC(p);
- /* find the emuldata */
- em = em_find(td->td_proc->p_pid, EMUL_UNLOCKED);
+ if (p->p_sysent != &elf_linux_sysvec)
+ return;
+
+ //printf("XXX: %i\n", p->p_pid);
+ /* find the emuldata */
+ em = em_find(p->p_pid, EMUL_UNLOCKED);
-#ifdef DEBUG
- if (child == NULL) {
- printf("we didnt find emuldata for the userreting process.\n");
- EMUL_RUNLOCK(&emul_lock);
- return (0);
+ if (em == NULL) {
+#ifdef DEBUG
+ // printf(LMSG("we didnt find emuldata for the userreting process.\n"));
+#endif
+ return;
}
-#endif
- if (em->set_tid != NULL)
- error = copyout(&td->td_proc->p_pid, em->set_tid, sizeof(td->td_proc->p_pid));
+ if (em->set_tid != NULL) {
+ error = copyout(&p->p_pid, em->set_tid, sizeof(p->p_pid));
+ }
EMUL_RUNLOCK(&emul_lock);
- return (error);
+ return;
}
int
@@ -1233,13 +1242,13 @@
/* find the emuldata */
em = em_find(td->td_proc->p_pid, EMUL_UNLOCKED);
+ if (em == NULL) {
#ifdef DEBUG
- if (child == NULL) {
- printf("we didnt find emuldata for the userreting process.\n");
+ printf(LMSG("we didnt find emuldata for the userreting process.\n"));
+#endif
EMUL_RUNLOCK(&emul_lock);
return (0);
}
-#endif
em->clear_tid = args->tidptr;
td->td_retval[0] = td->td_proc->p_pid;
==== //depot/projects/soc2006/rdivacky_linuxolator/i386/linux/linux_sysvec.c#8 (text+ko) ====
@@ -46,6 +46,7 @@
#include <sys/sysent.h>
#include <sys/sysproto.h>
#include <sys/vnode.h>
+#include <sys/eventhandler.h>
#include <vm/vm.h>
#include <vm/pmap.h>
@@ -106,15 +107,17 @@
static void exec_linux_setregs(struct thread *td, u_long entry,
u_long stack, u_long ps_strings);
-extern int (*linux_proc_exit_p)(struct thread *);
-extern int (*linux_userret_p)(struct thread *);
-
-extern int linux_userret(struct thread *);
-extern int linux_proc_exit(struct thread *);
+extern void linux_proc_exit(void *, struct proc *, struct image_params *);
+extern void linux_proc_exec(void *, struct proc *, struct image_params *);
+extern void linux_userret(void *, struct proc *);
extern struct rwlock emul_lock;
extern LIST_HEAD(futex_list, futex) futex_list;
extern struct mtx futex_mtx;
+static eventhandler_tag linux_exit_tag;
+static eventhandler_tag linux_userret_tag;
+static eventhandler_tag linux_exec_tag;
+
/*
* Linux syscalls return negative errno's, we do positive and map them
*/
@@ -918,11 +921,15 @@
} else
printf("cannot insert Linux ELF brand handler\n");
SLIST_INIT(&emuldata_head);
- linux_proc_exit_p = linux_proc_exit;
- linux_userret_p = linux_userret;
rw_init(&emul_lock, "emuldata lock");
LIST_INIT(&futex_list);
mtx_init(&futex_mtx, "futex protection lock", NULL, MTX_DEF);
+ linux_exit_tag = EVENTHANDLER_REGISTER(process_exit, linux_proc_exit,
+ NULL, 1000);
+ linux_userret_tag = EVENTHANDLER_REGISTER(userret, linux_userret,
+ NULL, 1000);
+ linux_exec_tag = EVENTHANDLER_REGISTER(process_exec, linux_proc_exec,
+ NULL, 1000);
break;
case MOD_UNLOAD:
for (brandinfo = &linux_brandlist[0]; *brandinfo != NULL;
@@ -944,10 +951,11 @@
printf("Linux ELF exec handler removed\n");
} else
printf("Could not deinstall ELF interpreter entry\n");
- linux_proc_exit_p = NULL;
- linux_userret_p = NULL;
rw_destroy(&emul_lock);
mtx_destroy(&futex_mtx);
+ EVENTHANDLER_DEREGISTER(process_exit, linux_exit_tag);
+ EVENTHANDLER_DEREGISTER(userret, linux_userret_tag);
+ EVENTHANDLER_DEREGISTER(process_exec, linux_exec_tag);
break;
default:
return EOPNOTSUPP;
==== //depot/projects/soc2006/rdivacky_linuxolator/kern/kern_exec.c#3 (text+ko) ====
@@ -889,9 +889,10 @@
vm_map_t map;
imgp->vmspace_destroyed = 1;
+ imgp->sysent = sv;
/* Called with Giant held, do not depend on it! */
- EVENTHANDLER_INVOKE(process_exec, p);
+ EVENTHANDLER_INVOKE(process_exec, p, imgp);
/*
* Here is as good a place as any to do any resource limit cleanups.
==== //depot/projects/soc2006/rdivacky_linuxolator/kern/kern_exit.c#4 (text+ko) ====
@@ -87,7 +87,6 @@
/* Hook for NFS teardown procedure. */
void (*nlminfo_release_p)(struct proc *p);
-int (*linux_proc_exit_p)(struct thread *) = NULL; /* necessary for linuxolator */
/*
* exit --
@@ -235,11 +234,8 @@
* E.g. SYSV IPC stuff
* XXX what if one of these generates an error?
*/
- EVENTHANDLER_INVOKE(process_exit, p);
+ EVENTHANDLER_INVOKE(process_exit, p, NULL);
- /* we have to call linux exit hook */
- if (p->p_flag & P_LINUX && linux_proc_exit_p != NULL)
- (linux_proc_exit_p)(td);
MALLOC(p->p_ru, struct rusage *, sizeof(struct rusage),
M_ZOMBIE, M_WAITOK);
/*
==== //depot/projects/soc2006/rdivacky_linuxolator/kern/kern_time.c#2 (text+ko) ====
@@ -87,7 +87,7 @@
static void itimer_leave(struct itimer *);
static struct itimer *itimer_find(struct proc *, int, int);
static void itimers_alloc(struct proc *);
-static void itimers_event_hook(void *arg, struct proc *p);
+static void itimers_event_hook(void *arg, struct proc *p, struct image_params *imgp);
static int realtimer_create(struct itimer *);
static int realtimer_gettime(struct itimer *, struct itimerspec *);
static int realtimer_settime(struct itimer *, int,
@@ -1511,7 +1511,7 @@
/* Clean up timers when some process events are being triggered. */
static void
-itimers_event_hook(void *arg, struct proc *p)
+itimers_event_hook(void *arg, struct proc *p, struct image_params *imgp __unused)
{
struct itimers *its;
struct itimer *it;
==== //depot/projects/soc2006/rdivacky_linuxolator/kern/subr_trap.c#3 (text+ko) ====
@@ -59,6 +59,7 @@
#include <sys/signalvar.h>
#include <sys/systm.h>
#include <sys/vmmeter.h>
+#include <sys/eventhandler.h>
#ifdef KTRACE
#include <sys/uio.h>
#include <sys/ktrace.h>
@@ -67,8 +68,6 @@
#include <machine/cpu.h>
#include <machine/pcb.h>
-int (*linux_userret_p)(struct thread *) = NULL; /* for linuxolator */
-
/*
* Define the code needed before returning to user mode, for
* trap and syscall.
@@ -130,9 +129,7 @@
addupc_task(td, TRAPF_PC(frame), td->td_pticks * psratio);
}
- /* linux userret */
- if (p->p_flag & P_LINUX && linux_userret_p != NULL)
- (linux_userret_p)(td);
+ EVENTHANDLER_INVOKE(userret, p);
/*
* Let the scheduler adjust our priority etc.
==== //depot/projects/soc2006/rdivacky_linuxolator/kern/sysv_sem.c#4 (text+ko) ====
@@ -77,7 +77,7 @@
static void seminit(void);
static int sysvsem_modload(struct module *, int, void *);
static int semunload(void);
-static void semexit_myhook(void *arg, struct proc *p);
+static void semexit_myhook(void *arg, struct proc *p, struct image_params *imgp);
static int sysctl_sema(SYSCTL_HANDLER_ARGS);
static int semvalid(int semid, struct semid_kernel *semakptr);
@@ -1299,9 +1299,10 @@
* semaphores.
*/
static void
-semexit_myhook(arg, p)
+semexit_myhook(arg, p, imgp)
void *arg;
struct proc *p;
+ struct image_params *imgp;
{
struct sem_undo *suptr;
struct sem_undo **supptr;
==== //depot/projects/soc2006/rdivacky_linuxolator/kern/uipc_mqueue.c#2 (text+ko) ====
@@ -247,7 +247,7 @@
int timo);
static void mqueue_send_notification(struct mqueue *mq);
static void mqueue_fdclose(struct thread *td, int fd, struct file *fp);
-static void mq_proc_exit(void *arg, struct proc *p);
+static void mq_proc_exit(void *arg, struct proc *p, struct image_params *imgp);
/*
* kqueue filters
@@ -2280,7 +2280,7 @@
}
static void
-mq_proc_exit(void *arg __unused, struct proc *p)
+mq_proc_exit(void *arg __unused, struct proc *p, struct image_params *imgp __unused)
{
struct filedesc *fdp;
struct file *fp;
==== //depot/projects/soc2006/rdivacky_linuxolator/kern/uipc_sem.c#2 (text+ko) ====
@@ -71,7 +71,7 @@
static int sem_perm(struct thread *td, struct ksem *ks);
static void sem_enter(struct proc *p, struct ksem *ks);
static int sem_leave(struct proc *p, struct ksem *ks);
-static void sem_exithook(void *arg, struct proc *p);
+static void sem_exithook(void *arg, struct proc *p, struct image_params *imgp);
static void sem_forkhook(void *arg, struct proc *p1, struct proc *p2,
int flags);
static int sem_hasopen(struct thread *td, struct ksem *ks);
@@ -919,7 +919,7 @@
}
static void
-sem_exithook(void *arg, struct proc *p)
+sem_exithook(void *arg, struct proc *p, struct image_params *imgp __unused)
{
struct ksem *ks, *ksnext;
==== //depot/projects/soc2006/rdivacky_linuxolator/kern/vfs_aio.c#3 (text+ko) ====
@@ -321,7 +321,7 @@
static int aio_aqueue(struct thread *td, struct aiocb *job,
struct aioliojob *lio, int type, int osigev);
static void aio_physwakeup(struct buf *bp);
-static void aio_proc_rundown(void *arg, struct proc *p);
+static void aio_proc_rundown(void *arg, struct proc *p, struct image_params *imgp);
static int aio_qphysio(struct proc *p, struct aiocblist *iocb);
static void biohelper(void *, int);
static void aio_daemon(void *param);
@@ -634,7 +634,7 @@
* Rundown the jobs for a given process.
*/
static void
-aio_proc_rundown(void *arg, struct proc *p)
+aio_proc_rundown(void *arg, struct proc *p, struct image_params *imgp __unused)
{
struct kaioinfo *ki;
struct aioliojob *lj;
==== //depot/projects/soc2006/rdivacky_linuxolator/netncp/ncp_subr.c#2 (text+ko) ====
@@ -57,7 +57,7 @@
struct callout_handle ncp_timer_handle;
static eventhandler_tag ncp_exit_tag;
-static void ncp_at_exit(void *arg, struct proc *p);
+static void ncp_at_exit(void *arg, struct proc *p, struct image_params *imgp);
static void ncp_timer(void *arg);
/*
@@ -80,7 +80,7 @@
void
-ncp_at_exit(void *arg, struct proc *p)
+ncp_at_exit(void *arg, struct proc *p, struct image_params *imgp __unused)
{
struct ncp_conn *ncp, *nncp;
struct thread *td;
==== //depot/projects/soc2006/rdivacky_linuxolator/sys/eventhandler.h#2 (text+ko) ====
@@ -162,10 +162,11 @@
* exec handlers are called with Giant, but that is by accident.
*/
struct proc;
+struct image_params;
-typedef void (*exitlist_fn)(void *, struct proc *);
+typedef void (*exitlist_fn)(void *, struct proc *, struct image_params *);
typedef void (*forklist_fn)(void *, struct proc *, struct proc *, int);
-typedef void (*execlist_fn)(void *, struct proc *);
+typedef void (*execlist_fn)(void *, struct proc *, struct image_params *);
EVENTHANDLER_DECLARE(process_exit, exitlist_fn);
EVENTHANDLER_DECLARE(process_fork, forklist_fn);
@@ -174,4 +175,7 @@
typedef void (*uma_zone_chfn)(void *);
EVENTHANDLER_DECLARE(nmbclusters_change, uma_zone_chfn);
EVENTHANDLER_DECLARE(maxsockets_change, uma_zone_chfn);
+
+typedef void(*userret_fn)(void *, struct proc *);
+EVENTHANDLER_DECLARE(userret, userret_fn);
#endif /* SYS_EVENTHANDLER_H */
==== //depot/projects/soc2006/rdivacky_linuxolator/sys/imgact.h#2 (text+ko) ====
@@ -63,6 +63,7 @@
unsigned long ps_strings; /* PS_STRINGS for BSD/OS binaries */
size_t auxarg_size;
struct image_args *args; /* system call arguments */
+ struct sysentvec *sysent; /* system entry vector */
};
#ifdef _KERNEL
==== //depot/projects/soc2006/rdivacky_linuxolator/sys/proc.h#3 (text+ko) ====
@@ -655,7 +655,6 @@
#define P_HWPMC 0x800000 /* Process is using HWPMCs */
#define P_JAILED 0x1000000 /* Process is in jail. */
-#define P_LINUX 0x2000000 /* linux binary */
#define P_INEXEC 0x4000000 /* Process is in execve(). */
#define P_STATCHILD 0x8000000 /* Child process stopped or exited. */
More information about the p4-projects
mailing list