summaryrefslogtreecommitdiff
path: root/sys/compat/linux32/common/linux32_misc.c
diff options
context:
space:
mode:
authorchs <chs@NetBSD.org>2010-07-07 01:30:32 +0000
committerchs <chs@NetBSD.org>2010-07-07 01:30:32 +0000
commit33fa5ccbbf17bc2390e2d136c34926c6f93ac5d1 (patch)
treec52fdcf81396fba59fce0a9c410d0dcc8c104091 /sys/compat/linux32/common/linux32_misc.c
parent56acc98394a822ba38a843f6385171e0b1aa5e9a (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.c79
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),
+ &lts, sizeof(lts))) != 0) {
+ return error;
+ }
+ linux32_to_native_timespec(&ts, &lts);
+ }
+ 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);
+}