diff options
Diffstat (limited to 'sys/i386/linux/linux_machdep.c')
-rw-r--r-- | sys/i386/linux/linux_machdep.c | 281 |
1 files changed, 185 insertions, 96 deletions
diff --git a/sys/i386/linux/linux_machdep.c b/sys/i386/linux/linux_machdep.c index ce8d52b..dfae7f4 100644 --- a/sys/i386/linux/linux_machdep.c +++ b/sys/i386/linux/linux_machdep.c @@ -54,24 +54,24 @@ #include <compat/linux/linux_signal.h> #include <compat/linux/linux_util.h> -struct linux_descriptor { - unsigned int entry_number; - unsigned long base_addr; - unsigned int limit; - unsigned int seg_32bit:1; - unsigned int contents:2; - unsigned int read_exec_only:1; - unsigned int limit_in_pages:1; - unsigned int seg_not_present:1; - unsigned int useable:1; +struct l_descriptor { + l_uint entry_number; + l_ulong base_addr; + l_uint limit; + l_uint seg_32bit:1; + l_uint contents:2; + l_uint read_exec_only:1; + l_uint limit_in_pages:1; + l_uint seg_not_present:1; + l_uint useable:1; }; -struct linux_select_argv { - int nfds; - fd_set *readfds; - fd_set *writefds; - fd_set *exceptfds; - struct timeval *timeout; +struct l_old_select_argv { + l_int nfds; + l_fd_set *readfds; + l_fd_set *writefds; + l_fd_set *exceptfds; + struct l_timeval *timeout; }; int @@ -118,51 +118,142 @@ linux_execve(struct proc *p, struct linux_execve_args *args) return (execve(p, &bsd)); } +struct l_ipc_kludge { + struct l_msgbuf *msgp; + l_long msgtyp; +}; + int linux_ipc(struct proc *p, struct linux_ipc_args *args) { - switch (args->what) { - case LINUX_SEMOP: - return (linux_semop(p, args)); - case LINUX_SEMGET: - return (linux_semget(p, args)); - case LINUX_SEMCTL: - return (linux_semctl(p, args)); - case LINUX_MSGSND: - return (linux_msgsnd(p, args)); - case LINUX_MSGRCV: - return (linux_msgrcv(p, args)); - case LINUX_MSGGET: - return (linux_msgget(p, args)); - case LINUX_MSGCTL: - return (linux_msgctl(p, args)); - case LINUX_SHMAT: - return (linux_shmat(p, args)); - case LINUX_SHMDT: - return (linux_shmdt(p, args)); - case LINUX_SHMGET: - return (linux_shmget(p, args)); - case LINUX_SHMCTL: - return (linux_shmctl(p, args)); + + switch (args->what & 0xFFFF) { + case LINUX_SEMOP: { + struct linux_semop_args a; + + a.semid = args->arg1; + a.tsops = args->ptr; + a.nsops = args->arg2; + return (linux_semop(p, &a)); + } + case LINUX_SEMGET: { + struct linux_semget_args a; + + a.key = args->arg1; + a.nsems = args->arg2; + a.semflg = args->arg3; + return (linux_semget(p, &a)); + } + case LINUX_SEMCTL: { + struct linux_semctl_args a; + int error; + + a.semid = args->arg1; + a.semnum = args->arg2; + a.cmd = args->arg3; + error = copyin((caddr_t)args->ptr, &a.arg, sizeof(a.arg)); + if (error) + return (error); + return (linux_semctl(p, &a)); + } + case LINUX_MSGSND: { + struct linux_msgsnd_args a; + + a.msqid = args->arg1; + a.msgp = args->ptr; + a.msgsz = args->arg2; + a.msgflg = args->arg3; + return (linux_msgsnd(p, &a)); + } + case LINUX_MSGRCV: { + struct linux_msgrcv_args a; + + a.msqid = args->arg1; + a.msgsz = args->arg2; + a.msgflg = args->arg3; + if ((args->what >> 16) == 0) { + struct l_ipc_kludge tmp; + int error; + + if (args->ptr == NULL) + return (EINVAL); + error = copyin((caddr_t)args->ptr, &tmp, sizeof(tmp)); + if (error) + return (error); + a.msgp = tmp.msgp; + a.msgtyp = tmp.msgtyp; + } else { + a.msgp = args->ptr; + a.msgtyp = args->arg5; + } + return (linux_msgrcv(p, &a)); + } + case LINUX_MSGGET: { + struct linux_msgget_args a; + + a.key = args->arg1; + a.msgflg = args->arg2; + return (linux_msgget(p, &a)); + } + case LINUX_MSGCTL: { + struct linux_msgctl_args a; + + a.msqid = args->arg1; + a.cmd = args->arg2; + a.buf = args->ptr; + return (linux_msgctl(p, &a)); + } + case LINUX_SHMAT: { + struct linux_shmat_args a; + + a.shmid = args->arg1; + a.shmaddr = args->ptr; + a.shmflg = args->arg2; + a.raddr = (l_ulong *)args->arg3; + return (linux_shmat(p, &a)); } + case LINUX_SHMDT: { + struct linux_shmdt_args a; - uprintf("LINUX: 'ipc' typ=%d not implemented\n", args->what); - return (ENOSYS); + a.shmaddr = args->ptr; + return (linux_shmdt(p, &a)); + } + case LINUX_SHMGET: { + struct linux_shmget_args a; + + a.key = args->arg1; + a.size = args->arg2; + a.shmflg = args->arg3; + return (linux_shmget(p, &a)); + } + case LINUX_SHMCTL: { + struct linux_shmctl_args a; + + a.shmid = args->arg1; + a.cmd = args->arg2; + a.buf = args->ptr; + return (linux_shmctl(p, &a)); + } + default: + break; + } + + return (EINVAL); } int -linux_select(struct proc *p, struct linux_select_args *args) +linux_old_select(struct proc *p, struct linux_old_select_args *args) { - struct linux_select_argv linux_args; - struct linux_newselect_args newsel; + struct l_old_select_argv linux_args; + struct linux_select_args newsel; int error; -#ifdef SELECT_DEBUG - if (ldebug(select)) - printf(ARGS(select, "%x"), args->ptr); +#ifdef DEBUG + if (ldebug(old_select)) + printf(ARGS(old_select, "%x"), args->ptr); #endif - error = copyin(args->ptr, &linux_args, sizeof(linux_args)); + error = copyin((caddr_t)args->ptr, &linux_args, sizeof(linux_args)); if (error) return (error); @@ -171,7 +262,7 @@ linux_select(struct proc *p, struct linux_select_args *args) newsel.writefds = linux_args.writefds; newsel.exceptfds = linux_args.exceptfds; newsel.timeout = linux_args.timeout; - return (linux_newselect(p, &newsel)); + return (linux_select(p, &newsel)); } int @@ -222,7 +313,6 @@ linux_clone(struct proc *p, struct linux_clone_args *args) int error, ff = RFPROC | RFSTOPPED; struct proc *p2; int exit_signal; - vm_offset_t start; #ifdef DEBUG if (ldebug(clone)) { @@ -243,9 +333,6 @@ linux_clone(struct proc *p, struct linux_clone_args *args) if (exit_signal <= LINUX_SIGTBLSZ) exit_signal = linux_to_bsd_signal[_SIG_IDX(exit_signal)]; - /* RFTHREAD probably not necessary here, but it shouldn't hurt */ - ff |= RFTHREAD; - if (args->flags & CLONE_VM) ff |= RFMEM; if (args->flags & CLONE_SIGHAND) @@ -253,44 +340,44 @@ linux_clone(struct proc *p, struct linux_clone_args *args) if (!(args->flags & CLONE_FILES)) ff |= RFFDG; - error = 0; - start = 0; - - if ((error = fork1(p, ff, &p2)) != 0) - return (error); + mtx_lock(&Giant); + error = fork1(p, ff, &p2); + if (error == 0) { + p->p_retval[0] = p2->p_pid; + p->p_retval[1] = 0; - PROC_LOCK(p2); - p2->p_sigparent = exit_signal; - PROC_UNLOCK(p2); - p2->p_frame->tf_esp = (unsigned int)args->stack; + PROC_LOCK(p2); + p2->p_sigparent = exit_signal; + p2->p_frame->tf_esp = (unsigned int)args->stack; #ifdef DEBUG - if (ldebug(clone)) - printf(LMSG("clone: successful rfork to %ld"), - (long)p2->p_pid); + if (ldebug(clone)) + printf(LMSG("clone: successful rfork to %ld"), + (long)p2->p_pid); #endif - /* - * Make this runnable after we are finished with it. - */ - mtx_lock_spin(&sched_lock); - p2->p_stat = SRUN; - setrunqueue(p2); - mtx_unlock_spin(&sched_lock); + /* + * Make this runnable after we are finished with it. + */ + mtx_lock_spin(&sched_lock); + p2->p_stat = SRUN; + setrunqueue(p2); + mtx_unlock_spin(&sched_lock); + PROC_UNLOCK(p2); + } + mtx_unlock(&Giant); - p->p_retval[0] = p2->p_pid; - p->p_retval[1] = 0; - return (0); + return (error); } /* XXX move */ -struct linux_mmap_argv { - linux_caddr_t addr; - int len; - int prot; - int flags; - int fd; - int pos; +struct l_mmap_argv { + l_caddr_t addr; + l_int len; + l_int prot; + l_int flags; + l_int fd; + l_int pos; }; #define STACK_SIZE (2 * 1024 * 1024) @@ -309,9 +396,9 @@ linux_mmap(struct proc *p, struct linux_mmap_args *args) off_t pos; } */ bsd_args; int error; - struct linux_mmap_argv linux_args; + struct l_mmap_argv linux_args; - error = copyin(args->ptr, &linux_args, sizeof(linux_args)); + error = copyin((caddr_t)args->ptr, &linux_args, sizeof(linux_args)); if (error) return (error); @@ -488,7 +575,7 @@ linux_modify_ldt(p, uap) caddr_t sg; struct sysarch_args args; struct i386_ldt_args *ldt; - struct linux_descriptor ld; + struct l_descriptor ld; union descriptor *desc; sg = stackgap_init(); @@ -552,8 +639,8 @@ linux_modify_ldt(p, uap) int linux_sigaction(struct proc *p, struct linux_sigaction_args *args) { - linux_osigaction_t osa; - linux_sigaction_t act, oact; + l_osigaction_t osa; + l_sigaction_t act, oact; int error; #ifdef DEBUG @@ -563,7 +650,8 @@ linux_sigaction(struct proc *p, struct linux_sigaction_args *args) #endif if (args->nsa != NULL) { - error = copyin(args->nsa, &osa, sizeof(linux_osigaction_t)); + error = copyin((caddr_t)args->nsa, &osa, + sizeof(l_osigaction_t)); if (error) return (error); act.lsa_handler = osa.lsa_handler; @@ -581,7 +669,8 @@ linux_sigaction(struct proc *p, struct linux_sigaction_args *args) osa.lsa_flags = oact.lsa_flags; osa.lsa_restorer = oact.lsa_restorer; osa.lsa_mask = oact.lsa_mask.__bits[0]; - error = copyout(&osa, args->osa, sizeof(linux_osigaction_t)); + error = copyout(&osa, (caddr_t)args->osa, + sizeof(l_osigaction_t)); } return (error); @@ -597,7 +686,7 @@ linux_sigsuspend(struct proc *p, struct linux_sigsuspend_args *args) { struct sigsuspend_args bsd; sigset_t *sigmask; - linux_sigset_t mask; + l_sigset_t mask; caddr_t sg = stackgap_init(); #ifdef DEBUG @@ -618,7 +707,7 @@ linux_rt_sigsuspend(p, uap) struct proc *p; struct linux_rt_sigsuspend_args *uap; { - linux_sigset_t lmask; + l_sigset_t lmask; sigset_t *bmask; struct sigsuspend_args bsd; caddr_t sg = stackgap_init(); @@ -630,10 +719,10 @@ linux_rt_sigsuspend(p, uap) (void *)uap->newset, uap->sigsetsize); #endif - if (uap->sigsetsize != sizeof(linux_sigset_t)) + if (uap->sigsetsize != sizeof(l_sigset_t)) return (EINVAL); - error = copyin(uap->newset, &lmask, sizeof(linux_sigset_t)); + error = copyin(uap->newset, &lmask, sizeof(l_sigset_t)); if (error) return (error); @@ -670,7 +759,7 @@ linux_sigaltstack(p, uap) { struct sigaltstack_args bsd; stack_t *ss, *oss; - linux_stack_t lss; + l_stack_t lss; int error; caddr_t sg = stackgap_init(); @@ -682,7 +771,7 @@ linux_sigaltstack(p, uap) if (uap->uss == NULL) { ss = NULL; } else { - error = copyin(uap->uss, &lss, sizeof(linux_stack_t)); + error = copyin(uap->uss, &lss, sizeof(l_stack_t)); if (error) return (error); @@ -703,7 +792,7 @@ linux_sigaltstack(p, uap) lss.ss_sp = oss->ss_sp; lss.ss_size = oss->ss_size; lss.ss_flags = bsd_to_linux_sigaltstack(oss->ss_flags); - error = copyout(&lss, uap->uoss, sizeof(linux_stack_t)); + error = copyout(&lss, uap->uoss, sizeof(l_stack_t)); } return (error); |