summaryrefslogtreecommitdiffstats
path: root/sys/compat/linux
diff options
context:
space:
mode:
authornetchild <netchild@FreeBSD.org>2010-11-15 13:03:35 +0000
committernetchild <netchild@FreeBSD.org>2010-11-15 13:03:35 +0000
commitd3aba4235e74d0db06b04e0581038d0ec62dd93d (patch)
treeca73ed73fa582030123e768ed3aec9c770f07bf0 /sys/compat/linux
parent27725d83cceb418509558e9041d5b1caf8ad3e38 (diff)
downloadFreeBSD-src-d3aba4235e74d0db06b04e0581038d0ec62dd93d.zip
FreeBSD-src-d3aba4235e74d0db06b04e0581038d0ec62dd93d.tar.gz
- print out the PID and program name of the program trying to use an
unsupported futex operation - for those futex operations which are known to be not supported, print out which futex operation it is - shortcut the error return of the unsupported FUTEX_CLOCK_REALTIME in some cases: FUTEX_CLOCK_REALTIME can be used to tell linux to use CLOCK_REALTIME instead of CLOCK_MONOTONIC. FUTEX_CLOCK_REALTIME however must only be set, if either FUTEX_WAIT_BITSET or FUTEX_WAIT_REQUEUE_PI are set too. If that's not the case we can die with ENOSYS right at the beginning. Submitted by: arundel Reviewed by: rdivacky (earlier iteration of the patch) MFC after: 1 week
Diffstat (limited to 'sys/compat/linux')
-rw-r--r--sys/compat/linux/linux_futex.c48
-rw-r--r--sys/compat/linux/linux_futex.h21
2 files changed, 54 insertions, 15 deletions
diff --git a/sys/compat/linux/linux_futex.c b/sys/compat/linux/linux_futex.c
index 01af020..c080dbc 100644
--- a/sys/compat/linux/linux_futex.c
+++ b/sys/compat/linux/linux_futex.c
@@ -416,7 +416,7 @@ futex_atomic_op(struct thread *td, int encoded_op, uint32_t *uaddr)
int
linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args)
{
- int op_ret, val, ret, nrwake;
+ int clockrt, nrwake, op_ret, ret, val;
struct linux_emuldata *em;
struct waiting_proc *wp;
struct futex *f, *f2 = NULL;
@@ -429,7 +429,19 @@ linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args)
* in most cases (ie. when futexes are not shared on file descriptor
* or between different processes.).
*/
- args->op = (args->op & ~LINUX_FUTEX_PRIVATE_FLAG);
+ args->op = args->op & ~LINUX_FUTEX_PRIVATE_FLAG;
+
+ /*
+ * Currently support for switching between CLOCK_MONOTONIC and
+ * CLOCK_REALTIME is not present. However Linux forbids the use of
+ * FUTEX_CLOCK_REALTIME with any op except FUTEX_WAIT_BITSET and
+ * FUTEX_WAIT_REQUEUE_PI.
+ */
+ clockrt = args->op & LINUX_FUTEX_CLOCK_REALTIME;
+ args->op = args->op & ~LINUX_FUTEX_CLOCK_REALTIME;
+ if (clockrt && args->op != LINUX_FUTEX_WAIT_BITSET &&
+ args->op != LINUX_FUTEX_WAIT_REQUEUE_PI)
+ return (ENOSYS);
switch (args->op) {
case LINUX_FUTEX_WAIT:
@@ -612,14 +624,23 @@ linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args)
case LINUX_FUTEX_LOCK_PI:
/* not yet implemented */
+ linux_msg(td,
+ "linux_sys_futex: "
+ "op LINUX_FUTEX_LOCK_PI not implemented.\n");
return (ENOSYS);
case LINUX_FUTEX_UNLOCK_PI:
/* not yet implemented */
+ linux_msg(td,
+ "linux_sys_futex: "
+ "op LINUX_FUTEX_UNLOCK_PI not implemented.\n");
return (ENOSYS);
case LINUX_FUTEX_TRYLOCK_PI:
/* not yet implemented */
+ linux_msg(td,
+ "linux_sys_futex: "
+ "op LINUX_FUTEX_TRYLOCK_PI not implemented.\n");
return (ENOSYS);
case LINUX_FUTEX_REQUEUE:
@@ -632,15 +653,30 @@ linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args)
*/
em = em_find(td->td_proc, EMUL_DONTLOCK);
if (em->used_requeue == 0) {
- printf("linux(%s (%d)) sys_futex: "
- "unsupported futex_requeue op\n",
- td->td_proc->p_comm, td->td_proc->p_pid);
+ linux_msg(td,
+ "linux_sys_futex: "
+ "unsupported futex_requeue op\n");
em->used_requeue = 1;
}
return (EINVAL);
+ case LINUX_FUTEX_WAIT_BITSET:
+ /* not yet implemented */
+ linux_msg(td,
+ "linux_sys_futex: "
+ "op FUTEX_WAIT_BITSET not implemented.\n");
+ return (ENOSYS);
+
+ case LINUX_FUTEX_WAIT_REQUEUE_PI:
+ /* not yet implemented */
+ linux_msg(td,
+ "linux_sys_futex: "
+ "op FUTEX_WAIT_REQUEUE_PI not implemented.\n");
+ return (ENOSYS);
+
default:
- printf("linux_sys_futex: unknown op %d\n", args->op);
+ linux_msg(td,
+ "linux_sys_futex: unknown op %d\n", args->op);
return (ENOSYS);
}
diff --git a/sys/compat/linux/linux_futex.h b/sys/compat/linux/linux_futex.h
index 1d462a7..4ccd46c 100644
--- a/sys/compat/linux/linux_futex.h
+++ b/sys/compat/linux/linux_futex.h
@@ -39,17 +39,20 @@
extern LIST_HEAD(futex_list, futex) futex_list;
extern struct mtx futex_mtx;
-#define LINUX_FUTEX_WAIT 0
-#define LINUX_FUTEX_WAKE 1
-#define LINUX_FUTEX_FD 2 /* unused */
-#define LINUX_FUTEX_REQUEUE 3
-#define LINUX_FUTEX_CMP_REQUEUE 4
-#define LINUX_FUTEX_WAKE_OP 5
-#define LINUX_FUTEX_LOCK_PI 6
-#define LINUX_FUTEX_UNLOCK_PI 7
-#define LINUX_FUTEX_TRYLOCK_PI 8
+#define LINUX_FUTEX_WAIT 0
+#define LINUX_FUTEX_WAKE 1
+#define LINUX_FUTEX_FD 2 /* unused */
+#define LINUX_FUTEX_REQUEUE 3
+#define LINUX_FUTEX_CMP_REQUEUE 4
+#define LINUX_FUTEX_WAKE_OP 5
+#define LINUX_FUTEX_LOCK_PI 6
+#define LINUX_FUTEX_UNLOCK_PI 7
+#define LINUX_FUTEX_TRYLOCK_PI 8
+#define LINUX_FUTEX_WAIT_BITSET 9
+#define LINUX_FUTEX_WAIT_REQUEUE_PI 11
#define LINUX_FUTEX_PRIVATE_FLAG 128
+#define LINUX_FUTEX_CLOCK_REALTIME 256
#define FUTEX_OP_SET 0 /* *(int *)UADDR2 = OPARG; */
#define FUTEX_OP_ADD 1 /* *(int *)UADDR2 += OPARG; */
OpenPOWER on IntegriCloud