diff options
| author | chs <chs@NetBSD.org> | 2010-07-07 01:30:32 +0000 |
|---|---|---|
| committer | chs <chs@NetBSD.org> | 2010-07-07 01:30:32 +0000 |
| commit | 33fa5ccbbf17bc2390e2d136c34926c6f93ac5d1 (patch) | |
| tree | c52fdcf81396fba59fce0a9c410d0dcc8c104091 /sys/compat/linux32/common/linux32_misc.c | |
| parent | 56acc98394a822ba38a843f6385171e0b1aa5e9a (diff) | |
many changes for COMPAT_LINUX:
- update the linux syscall table for each platform.
- support new-style (NPTL) linux pthreads on all platforms.
clone() with CLONE_THREAD uses 1 process with many LWPs
instead of separate processes.
- move the contents of sys__lwp_setprivate() into a new
lwp_setprivate() and use that everywhere.
- update linux_release[] and linux32_release[] to "2.6.18".
- adjust placement of emul fork/exec/exit hooks as needed
and adjust other emul code to match.
- convert all struct emul definitions to use named initializers.
- change the pid allocator to allow multiple pids to refer to the same proc.
- remove a few fields from struct proc that are no longer needed.
- disable the non-functional "vdso" code in linux32/amd64,
glibc works fine without it.
- fix a race in the futex code where we could miss a wakeup after
a requeue operation.
- redo futex locking to be a little more efficient.
Diffstat (limited to 'sys/compat/linux32/common/linux32_misc.c')
| -rw-r--r-- | sys/compat/linux32/common/linux32_misc.c | 79 |
1 files changed, 77 insertions, 2 deletions
diff --git a/sys/compat/linux32/common/linux32_misc.c b/sys/compat/linux32/common/linux32_misc.c index 73c82600442..805e6e26882 100644 --- a/sys/compat/linux32/common/linux32_misc.c +++ b/sys/compat/linux32/common/linux32_misc.c @@ -1,4 +1,4 @@ -/* $NetBSD: linux32_misc.c,v 1.18 2009/11/24 10:42:44 njoly Exp $ */ +/* $NetBSD: linux32_misc.c,v 1.19 2010/07/07 01:30:35 chs Exp $ */ /*- * Copyright (c) 1995, 1998, 1999 The NetBSD Foundation, Inc. @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: linux32_misc.c,v 1.18 2009/11/24 10:42:44 njoly Exp $"); +__KERNEL_RCSID(0, "$NetBSD: linux32_misc.c,v 1.19 2010/07/07 01:30:35 chs Exp $"); #include <sys/param.h> #include <sys/proc.h> @@ -53,16 +53,19 @@ __KERNEL_RCSID(0, "$NetBSD: linux32_misc.c,v 1.18 2009/11/24 10:42:44 njoly Exp #include <compat/linux/common/linux_ptrace.h> #include <compat/linux/common/linux_types.h> +#include <compat/linux/common/linux_emuldata.h> #include <compat/linux/common/linux_signal.h> #include <compat/linux/common/linux_misc.h> #include <compat/linux/common/linux_statfs.h> #include <compat/linux/common/linux_ipc.h> #include <compat/linux/common/linux_sem.h> +#include <compat/linux/common/linux_futex.h> #include <compat/linux/linux_syscallargs.h> extern const struct linux_mnttypes linux_fstypes[]; extern const int linux_fstypes_cnt; +void linux32_to_native_timespec(struct timespec *, struct linux32_timespec *); /* * Implement the fs stat functions. Straightforward. @@ -189,3 +192,75 @@ linux32_sys_personality(struct lwp *l, const struct linux32_sys_personality_args retval[0] = LINUX_PER_LINUX; return 0; } + +int +linux32_sys_futex(struct lwp *l, + const struct linux32_sys_futex_args *uap, register_t *retval) +{ + /* { + syscallarg(linux32_intp_t) uaddr; + syscallarg(int) op; + syscallarg(int) val; + syscallarg(linux32_timespecp_t) timeout; + syscallarg(linux32_intp_t) uaddr2; + syscallarg(int) val3; + } */ + struct linux_sys_futex_args ua; + struct linux32_timespec lts; + struct timespec ts = { 0, 0 }; + int error; + + NETBSD32TOP_UAP(uaddr, int); + NETBSD32TO64_UAP(op); + NETBSD32TO64_UAP(val); + NETBSD32TOP_UAP(timeout, struct linux_timespec); + NETBSD32TOP_UAP(uaddr2, int); + NETBSD32TO64_UAP(val3); + if ((SCARG(uap, op) & ~LINUX_FUTEX_PRIVATE_FLAG) == LINUX_FUTEX_WAIT && + SCARG_P32(uap, timeout) != NULL) { + if ((error = copyin((void *)SCARG_P32(uap, timeout), + <s, sizeof(lts))) != 0) { + return error; + } + linux32_to_native_timespec(&ts, <s); + } + return linux_do_futex(l, &ua, retval, &ts); +} + +int +linux32_sys_set_robust_list(struct lwp *l, + const struct linux32_sys_set_robust_list_args *uap, register_t *retval) +{ + /* { + syscallarg(linux32_robust_list_headp_t) head; + syscallarg(linux32_size_t) len; + } */ + struct linux_sys_set_robust_list_args ua; + struct linux_emuldata *led; + + if (SCARG(uap, len) != 12) + return EINVAL; + + NETBSD32TOP_UAP(head, struct robust_list_head); + NETBSD32TOX64_UAP(len, size_t); + + led = l->l_emuldata; + led->led_robust_head = SCARG(&ua, head); + *retval = 0; + return 0; +} + +int +linux32_sys_get_robust_list(struct lwp *l, + const struct linux32_sys_get_robust_list_args *uap, register_t *retval) +{ + /* { + syscallarg(linux32_robust_list_headpp_t) head; + syscallarg(linux32_sizep_t) len; + } */ + struct linux_sys_get_robust_list_args ua; + + NETBSD32TOP_UAP(head, struct robust_list_head *); + NETBSD32TOP_UAP(head, size_t *); + return linux_sys_get_robust_list(l, &ua, retval); +} |
