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