|
Davidlohr Bueso |
c6c39e |
From 51cf94d16860a324e97d1b670d88f1f2b643bc32 Mon Sep 17 00:00:00 2001
|
|
Davidlohr Bueso |
c6c39e |
From: Thomas Gleixner <tglx@linutronix.de>
|
|
Davidlohr Bueso |
c6c39e |
Date: Thu, 22 Apr 2021 21:44:21 +0200
|
|
Davidlohr Bueso |
c6c39e |
Subject: [PATCH 4/4] futex: Make syscall entry points less convoluted
|
|
Davidlohr Bueso |
c6c39e |
Git-commit: 51cf94d16860a324e97d1b670d88f1f2b643bc32
|
|
Davidlohr Bueso |
c6c39e |
Patch-mainline: v5.13-rc1
|
|
Davidlohr Bueso |
c6c39e |
References: git-fixes
|
|
Davidlohr Bueso |
c6c39e |
|
|
Davidlohr Bueso |
c6c39e |
The futex and the compat syscall entry points do pretty much the same
|
|
Davidlohr Bueso |
c6c39e |
except for the timespec data types and the corresponding copy from
|
|
Davidlohr Bueso |
c6c39e |
user function.
|
|
Davidlohr Bueso |
c6c39e |
|
|
Davidlohr Bueso |
c6c39e |
Split out the rest into inline functions and share the functionality.
|
|
Davidlohr Bueso |
c6c39e |
|
|
Davidlohr Bueso |
c6c39e |
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
|
|
Davidlohr Bueso |
c6c39e |
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
|
|
Davidlohr Bueso |
c6c39e |
Link: https://lore.kernel.org/r/20210422194705.244476369@linutronix.de
|
|
Davidlohr Bueso |
c6c39e |
Signed-off-by: Davidlohr Bueso <dbueso@suse.de>
|
|
Davidlohr Bueso |
c6c39e |
|
|
Davidlohr Bueso |
c6c39e |
---
|
|
Davidlohr Bueso |
c6c39e |
kernel/futex.c | 63 +++++++++++++++++++++++++++++---------------------
|
|
Davidlohr Bueso |
c6c39e |
1 file changed, 37 insertions(+), 26 deletions(-)
|
|
Davidlohr Bueso |
c6c39e |
|
|
Davidlohr Bueso |
c6c39e |
diff --git a/kernel/futex.c b/kernel/futex.c
|
|
Davidlohr Bueso |
c6c39e |
index 4ddfdce325ad..4938a00bc785 100644
|
|
Davidlohr Bueso |
c6c39e |
--- a/kernel/futex.c
|
|
Davidlohr Bueso |
c6c39e |
+++ b/kernel/futex.c
|
|
Davidlohr Bueso |
c6c39e |
@@ -3757,30 +3757,48 @@ long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout,
|
|
Davidlohr Bueso |
c6c39e |
return -ENOSYS;
|
|
Davidlohr Bueso |
c6c39e |
}
|
|
Davidlohr Bueso |
c6c39e |
|
|
Davidlohr Bueso |
c6c39e |
+static __always_inline bool futex_cmd_has_timeout(u32 cmd)
|
|
Davidlohr Bueso |
c6c39e |
+{
|
|
Davidlohr Bueso |
c6c39e |
+ switch (cmd) {
|
|
Davidlohr Bueso |
c6c39e |
+ case FUTEX_WAIT:
|
|
Davidlohr Bueso |
c6c39e |
+ case FUTEX_LOCK_PI:
|
|
Davidlohr Bueso |
c6c39e |
+ case FUTEX_WAIT_BITSET:
|
|
Davidlohr Bueso |
c6c39e |
+ case FUTEX_WAIT_REQUEUE_PI:
|
|
Davidlohr Bueso |
c6c39e |
+ return true;
|
|
Davidlohr Bueso |
c6c39e |
+ }
|
|
Davidlohr Bueso |
c6c39e |
+ return false;
|
|
Davidlohr Bueso |
c6c39e |
+}
|
|
Davidlohr Bueso |
c6c39e |
+
|
|
Davidlohr Bueso |
c6c39e |
+static __always_inline int
|
|
Davidlohr Bueso |
c6c39e |
+futex_init_timeout(u32 cmd, u32 op, struct timespec64 *ts, ktime_t *t)
|
|
Davidlohr Bueso |
c6c39e |
+{
|
|
Davidlohr Bueso |
c6c39e |
+ if (!timespec64_valid(ts))
|
|
Davidlohr Bueso |
c6c39e |
+ return -EINVAL;
|
|
Davidlohr Bueso |
c6c39e |
+
|
|
Davidlohr Bueso |
c6c39e |
+ *t = timespec64_to_ktime(*ts);
|
|
Davidlohr Bueso |
c6c39e |
+ if (cmd == FUTEX_WAIT)
|
|
Davidlohr Bueso |
c6c39e |
+ *t = ktime_add_safe(ktime_get(), *t);
|
|
Davidlohr Bueso |
c6c39e |
+ else if (cmd != FUTEX_LOCK_PI && !(op & FUTEX_CLOCK_REALTIME))
|
|
Davidlohr Bueso |
c6c39e |
+ *t = timens_ktime_to_host(CLOCK_MONOTONIC, *t);
|
|
Davidlohr Bueso |
c6c39e |
+ return 0;
|
|
Davidlohr Bueso |
c6c39e |
+}
|
|
Davidlohr Bueso |
c6c39e |
|
|
Davidlohr Bueso |
c6c39e |
SYSCALL_DEFINE6(futex, u32 __user *, uaddr, int, op, u32, val,
|
|
Davidlohr Bueso |
c6c39e |
const struct __kernel_timespec __user *, utime,
|
|
Davidlohr Bueso |
c6c39e |
u32 __user *, uaddr2, u32, val3)
|
|
Davidlohr Bueso |
c6c39e |
{
|
|
Davidlohr Bueso |
c6c39e |
- struct timespec64 ts;
|
|
Davidlohr Bueso |
c6c39e |
+ int ret, cmd = op & FUTEX_CMD_MASK;
|
|
Davidlohr Bueso |
c6c39e |
ktime_t t, *tp = NULL;
|
|
Davidlohr Bueso |
c6c39e |
- int cmd = op & FUTEX_CMD_MASK;
|
|
Davidlohr Bueso |
c6c39e |
+ struct timespec64 ts;
|
|
Davidlohr Bueso |
c6c39e |
|
|
Davidlohr Bueso |
c6c39e |
- if (utime && (cmd == FUTEX_WAIT || cmd == FUTEX_LOCK_PI ||
|
|
Davidlohr Bueso |
c6c39e |
- cmd == FUTEX_WAIT_BITSET ||
|
|
Davidlohr Bueso |
c6c39e |
- cmd == FUTEX_WAIT_REQUEUE_PI)) {
|
|
Davidlohr Bueso |
c6c39e |
+ if (utime && futex_cmd_has_timeout(cmd)) {
|
|
Davidlohr Bueso |
c6c39e |
if (unlikely(should_fail_futex(!(op & FUTEX_PRIVATE_FLAG))))
|
|
Davidlohr Bueso |
c6c39e |
return -EFAULT;
|
|
Davidlohr Bueso |
c6c39e |
if (get_timespec64(&ts, utime))
|
|
Davidlohr Bueso |
c6c39e |
return -EFAULT;
|
|
Davidlohr Bueso |
c6c39e |
- if (!timespec64_valid(&ts))
|
|
Davidlohr Bueso |
c6c39e |
- return -EINVAL;
|
|
Davidlohr Bueso |
c6c39e |
-
|
|
Davidlohr Bueso |
c6c39e |
- t = timespec64_to_ktime(ts);
|
|
Davidlohr Bueso |
c6c39e |
- if (cmd == FUTEX_WAIT)
|
|
Davidlohr Bueso |
c6c39e |
- t = ktime_add_safe(ktime_get(), t);
|
|
Davidlohr Bueso |
c6c39e |
- else if (cmd != FUTEX_LOCK_PI && !(op & FUTEX_CLOCK_REALTIME))
|
|
Davidlohr Bueso |
c6c39e |
- t = timens_ktime_to_host(CLOCK_MONOTONIC, t);
|
|
Davidlohr Bueso |
c6c39e |
+ ret = futex_init_timeout(cmd, op, &ts, &t);
|
|
Davidlohr Bueso |
c6c39e |
+ if (ret)
|
|
Davidlohr Bueso |
c6c39e |
+ return ret;
|
|
Davidlohr Bueso |
c6c39e |
tp = &t;
|
|
Davidlohr Bueso |
c6c39e |
}
|
|
Davidlohr Bueso |
c6c39e |
|
|
Davidlohr Bueso |
c6c39e |
@@ -3950,23 +3968,16 @@ SYSCALL_DEFINE6(futex_time32, u32 __user *, uaddr, int, op, u32, val,
|
|
Davidlohr Bueso |
c6c39e |
const struct old_timespec32 __user *, utime, u32 __user *, uaddr2,
|
|
Davidlohr Bueso |
c6c39e |
u32, val3)
|
|
Davidlohr Bueso |
c6c39e |
{
|
|
Davidlohr Bueso |
c6c39e |
- struct timespec64 ts;
|
|
Davidlohr Bueso |
c6c39e |
+ int ret, cmd = op & FUTEX_CMD_MASK;
|
|
Davidlohr Bueso |
c6c39e |
ktime_t t, *tp = NULL;
|
|
Davidlohr Bueso |
c6c39e |
- int cmd = op & FUTEX_CMD_MASK;
|
|
Davidlohr Bueso |
c6c39e |
+ struct timespec64 ts;
|
|
Davidlohr Bueso |
c6c39e |
|
|
Davidlohr Bueso |
c6c39e |
- if (utime && (cmd == FUTEX_WAIT || cmd == FUTEX_LOCK_PI ||
|
|
Davidlohr Bueso |
c6c39e |
- cmd == FUTEX_WAIT_BITSET ||
|
|
Davidlohr Bueso |
c6c39e |
- cmd == FUTEX_WAIT_REQUEUE_PI)) {
|
|
Davidlohr Bueso |
c6c39e |
+ if (utime && futex_cmd_has_timeout(cmd)) {
|
|
Davidlohr Bueso |
c6c39e |
if (get_old_timespec32(&ts, utime))
|
|
Davidlohr Bueso |
c6c39e |
return -EFAULT;
|
|
Davidlohr Bueso |
c6c39e |
- if (!timespec64_valid(&ts))
|
|
Davidlohr Bueso |
c6c39e |
- return -EINVAL;
|
|
Davidlohr Bueso |
c6c39e |
-
|
|
Davidlohr Bueso |
c6c39e |
- t = timespec64_to_ktime(ts);
|
|
Davidlohr Bueso |
c6c39e |
- if (cmd == FUTEX_WAIT)
|
|
Davidlohr Bueso |
c6c39e |
- t = ktime_add_safe(ktime_get(), t);
|
|
Davidlohr Bueso |
c6c39e |
- else if (cmd != FUTEX_LOCK_PI && !(op & FUTEX_CLOCK_REALTIME))
|
|
Davidlohr Bueso |
c6c39e |
- t = timens_ktime_to_host(CLOCK_MONOTONIC, t);
|
|
Davidlohr Bueso |
c6c39e |
+ ret = futex_init_timeout(cmd, op, &ts, &t);
|
|
Davidlohr Bueso |
c6c39e |
+ if (ret)
|
|
Davidlohr Bueso |
c6c39e |
+ return ret;
|
|
Davidlohr Bueso |
c6c39e |
tp = &t;
|
|
Davidlohr Bueso |
c6c39e |
}
|
|
Davidlohr Bueso |
c6c39e |
|
|
Davidlohr Bueso |
c6c39e |
--
|
|
Davidlohr Bueso |
c6c39e |
2.26.2
|
|
Davidlohr Bueso |
c6c39e |
|