summaryrefslogtreecommitdiffstats
path: root/sys/i386/linux/linux_machdep.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/i386/linux/linux_machdep.c')
-rw-r--r--sys/i386/linux/linux_machdep.c281
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);
OpenPOWER on IntegriCloud