All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Zijlstra <peterz@infradead.org>
To: tglx@linutronix.de, axboe@kernel.dk
Cc: linux-kernel@vger.kernel.org, peterz@infradead.org,
	mingo@redhat.com, dvhart@infradead.org, dave@stgolabs.net,
	andrealmeid@igalia.com, Andrew Morton <akpm@linux-foundation.org>,
	urezki@gmail.com, hch@infradead.org, lstoakes@gmail.com,
	Arnd Bergmann <arnd@arndb.de>,
	linux-api@vger.kernel.org, linux-mm@kvack.org,
	linux-arch@vger.kernel.org, malteskarupke@web.de
Subject: [PATCH v1 03/14] futex: Flag conversion
Date: Fri, 21 Jul 2023 12:22:40 +0200	[thread overview]
Message-ID: <20230721105743.887106899@infradead.org> (raw)
In-Reply-To: 20230721102237.268073801@infradead.org

Futex has 3 sets of flags:

 - legacy futex op bits
 - futex2 flags
 - internal flags

Add a few helpers to convert from the API flags into the internal
flags.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 kernel/futex/futex.h    |   64 +++++++++++++++++++++++++++++++++++++++++++++---
 kernel/futex/syscalls.c |   24 ++++++------------
 kernel/futex/waitwake.c |    4 +--
 3 files changed, 72 insertions(+), 20 deletions(-)

--- a/kernel/futex/futex.h
+++ b/kernel/futex/futex.h
@@ -5,6 +5,7 @@
 #include <linux/futex.h>
 #include <linux/rtmutex.h>
 #include <linux/sched/wake_q.h>
+#include <linux/compat.h>
 
 #ifdef CONFIG_PREEMPT_RT
 #include <linux/rcuwait.h>
@@ -16,8 +17,15 @@
  * Futex flags used to encode options to functions and preserve them across
  * restarts.
  */
+#define FLAGS_SIZE_8		0x00
+#define FLAGS_SIZE_16		0x01
+#define FLAGS_SIZE_32		0x02
+#define FLAGS_SIZE_64		0x03
+
+#define FLAGS_SIZE_MASK		0x03
+
 #ifdef CONFIG_MMU
-# define FLAGS_SHARED		0x01
+# define FLAGS_SHARED		0x10
 #else
 /*
  * NOMMU does not have per process address space. Let the compiler optimize
@@ -25,8 +33,58 @@
  */
 # define FLAGS_SHARED		0x00
 #endif
-#define FLAGS_CLOCKRT		0x02
-#define FLAGS_HAS_TIMEOUT	0x04
+#define FLAGS_CLOCKRT		0x20
+#define FLAGS_HAS_TIMEOUT	0x40
+#define FLAGS_NUMA		0x80
+
+/* FUTEX_ to FLAGS_ */
+static inline unsigned int futex_to_flags(unsigned int op)
+{
+	unsigned int flags = FLAGS_SIZE_32;
+
+	if (!(op & FUTEX_PRIVATE_FLAG))
+		flags |= FLAGS_SHARED;
+
+	if (op & FUTEX_CLOCK_REALTIME)
+		flags |= FLAGS_CLOCKRT;
+
+	return flags;
+}
+
+/* FUTEX2_ to FLAGS_ */
+static inline unsigned int futex2_to_flags(unsigned int flags2)
+{
+	unsigned int flags = flags2 & FUTEX2_64;
+
+	if (!(flags2 & FUTEX2_PRIVATE))
+		flags |= FLAGS_SHARED;
+
+	if (flags2 & FUTEX2_NUMA)
+		flags |= FLAGS_NUMA;
+
+	return flags;
+}
+
+static inline bool futex_flags_valid(unsigned int flags)
+{
+	/* Only 64bit futexes for 64bit code */
+	if (!IS_ENABLED(CONFIG_64BIT) || in_compat_syscall()) {
+		if ((flags & FLAGS_SIZE_MASK) == FLAGS_SIZE_64)
+			return false;
+	}
+
+	/* Only 32bit futexes are implemented -- for now */
+	if ((flags & FLAGS_SIZE_MASK) != FLAGS_SIZE_32)
+		return false;
+
+	return true;
+}
+
+static inline unsigned int futex_size(unsigned int flags)
+{
+	unsigned int size = flags & FLAGS_SIZE_MASK;
+	return 1 << size; /* {0,1,2,3} -> {1,2,4,8} */
+}
 
 #ifdef CONFIG_FAIL_FUTEX
 extern bool should_fail_futex(bool fshared);
--- a/kernel/futex/syscalls.c
+++ b/kernel/futex/syscalls.c
@@ -1,6 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 
-#include <linux/compat.h>
 #include <linux/syscalls.h>
 #include <linux/time_namespace.h>
 
@@ -85,15 +84,12 @@ SYSCALL_DEFINE3(get_robust_list, int, pi
 long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout,
 		u32 __user *uaddr2, u32 val2, u32 val3)
 {
+	unsigned int flags = futex_to_flags(op);
 	int cmd = op & FUTEX_CMD_MASK;
-	unsigned int flags = 0;
 
-	if (!(op & FUTEX_PRIVATE_FLAG))
-		flags |= FLAGS_SHARED;
-
-	if (op & FUTEX_CLOCK_REALTIME) {
-		flags |= FLAGS_CLOCKRT;
-		if (cmd != FUTEX_WAIT_BITSET && cmd != FUTEX_WAIT_REQUEUE_PI &&
+	if (flags & FLAGS_CLOCKRT) {
+		if (cmd != FUTEX_WAIT_BITSET &&
+		    cmd != FUTEX_WAIT_REQUEUE_PI &&
 		    cmd != FUTEX_LOCK_PI2)
 			return -ENOSYS;
 	}
@@ -201,21 +197,19 @@ static int futex_parse_waitv(struct fute
 	unsigned int i;
 
 	for (i = 0; i < nr_futexes; i++) {
+		unsigned int flags;
+
 		if (copy_from_user(&aux, &uwaitv[i], sizeof(aux)))
 			return -EFAULT;
 
 		if ((aux.flags & ~FUTEX2_MASK) || aux.__reserved)
 			return -EINVAL;
 
-		if (!IS_ENABLED(CONFIG_64BIT) || in_compat_syscall()) {
-			if ((aux.flags & FUTEX2_64) == FUTEX2_64)
-				return -EINVAL;
-		}
-
-		if ((aux.flags & FUTEX2_64) != FUTEX2_32)
+		flags = futex2_to_flags(aux.flags);
+		if (!futex_flags_valid(flags))
 			return -EINVAL;
 
-		futexv[i].w.flags = aux.flags;
+		futexv[i].w.flags = flags;
 		futexv[i].w.val = aux.val;
 		futexv[i].w.uaddr = aux.uaddr;
 		futexv[i].q = futex_q_init;
--- a/kernel/futex/waitwake.c
+++ b/kernel/futex/waitwake.c
@@ -419,11 +419,11 @@ static int futex_wait_multiple_setup(str
 	 */
 retry:
 	for (i = 0; i < count; i++) {
-		if ((vs[i].w.flags & FUTEX_PRIVATE_FLAG) && retry)
+		if (!(vs[i].w.flags & FLAGS_SHARED) && retry)
 			continue;
 
 		ret = get_futex_key(u64_to_user_ptr(vs[i].w.uaddr),
-				    !(vs[i].w.flags & FUTEX_PRIVATE_FLAG),
+				    vs[i].w.flags & FLAGS_SHARED,
 				    &vs[i].q.key, FUTEX_READ);
 
 		if (unlikely(ret))



  parent reply	other threads:[~2023-07-21 11:01 UTC|newest]

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-07-21 10:22 [PATCH v1 00/14] futex: More futex2 bits Peter Zijlstra
2023-07-21 10:22 ` [PATCH v1 01/14] futex: Clarify FUTEX2 flags Peter Zijlstra
2023-07-31 16:08   ` Thomas Gleixner
2023-07-21 10:22 ` [PATCH v1 02/14] futex: Extend the " Peter Zijlstra
2023-07-21 15:47   ` Arnd Bergmann
2023-07-21 18:52     ` Peter Zijlstra
2023-07-31 16:11   ` Thomas Gleixner
2023-07-31 16:25     ` Peter Zijlstra
2023-07-31 17:16     ` Thomas Gleixner
2023-07-31 17:35       ` Peter Zijlstra
2023-07-31 20:52         ` Thomas Gleixner
2023-07-31 17:42     ` Thomas Gleixner
2023-07-31 19:20       ` Peter Zijlstra
2023-07-31 21:14         ` Thomas Gleixner
2023-07-31 21:33           ` Peter Zijlstra
2023-07-31 22:43             ` Thomas Gleixner
2023-07-31 22:59               ` Peter Zijlstra
2023-08-01  8:49                 ` Thomas Gleixner
2023-08-01  6:02               ` Arnd Bergmann
2023-07-21 10:22 ` Peter Zijlstra [this message]
2023-07-31 16:21   ` [PATCH v1 03/14] futex: Flag conversion Thomas Gleixner
2023-07-31 16:26     ` Peter Zijlstra
2023-07-21 10:22 ` [PATCH v1 04/14] futex: Validate futex value against futex size Peter Zijlstra
2023-07-31 17:12   ` Thomas Gleixner
2023-07-21 10:22 ` [PATCH v1 05/14] futex: Add sys_futex_wake() Peter Zijlstra
2023-07-21 15:41   ` Arnd Bergmann
2023-07-21 18:54     ` Peter Zijlstra
2023-07-21 21:23       ` Arnd Bergmann
2023-07-25  7:22   ` Geert Uytterhoeven
2023-07-21 10:22 ` [PATCH v1 06/14] futex: Add sys_futex_wait() Peter Zijlstra
2023-07-25  7:22   ` Geert Uytterhoeven
2023-07-31 16:35   ` Thomas Gleixner
2023-07-21 10:22 ` [PATCH v1 07/14] futex: Propagate flags into get_futex_key() Peter Zijlstra
2023-07-31 16:36   ` Thomas Gleixner
2023-07-21 10:22 ` [PATCH v1 08/14] futex: Add flags2 argument to futex_requeue() Peter Zijlstra
2023-07-31 16:43   ` Thomas Gleixner
2023-07-21 10:22 ` [PATCH v1 09/14] futex: Add sys_futex_requeue() Peter Zijlstra
2023-07-25  7:23   ` Geert Uytterhoeven
2023-07-31 17:19   ` Thomas Gleixner
2023-07-31 17:38     ` Peter Zijlstra
2023-07-21 10:22 ` [PATCH v1 10/14] mm: Add vmalloc_huge_node() Peter Zijlstra
2023-07-24 13:46   ` Christoph Hellwig
2023-07-21 10:22 ` [PATCH v1 11/14] futex: Implement FUTEX2_NUMA Peter Zijlstra
2023-07-21 12:16   ` Peter Zijlstra
2023-07-31 17:36   ` Thomas Gleixner
2023-07-31 18:03     ` Peter Zijlstra
2023-07-31 21:26       ` Thomas Gleixner
2023-07-21 10:22 ` [PATCH v1 12/14] futex: Propagate flags into futex_get_value_locked() Peter Zijlstra
2023-07-21 10:22 ` [PATCH v1 13/14] futex: Enable FUTEX2_{8,16} Peter Zijlstra
2023-07-21 10:22 ` [PATCH v1 14/14] futex,selftests: Extend the futex selftests Peter Zijlstra
2023-07-21 14:42 ` [PATCH v1 00/14] futex: More futex2 bits Jens Axboe
2023-07-21 15:49 ` Arnd Bergmann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230721105743.887106899@infradead.org \
    --to=peterz@infradead.org \
    --cc=akpm@linux-foundation.org \
    --cc=andrealmeid@igalia.com \
    --cc=arnd@arndb.de \
    --cc=axboe@kernel.dk \
    --cc=dave@stgolabs.net \
    --cc=dvhart@infradead.org \
    --cc=hch@infradead.org \
    --cc=linux-api@vger.kernel.org \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=lstoakes@gmail.com \
    --cc=malteskarupke@web.de \
    --cc=mingo@redhat.com \
    --cc=tglx@linutronix.de \
    --cc=urezki@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.