[RFC PATCH 7/9] um: nommu: add SMP futex operations
Johannes Berg
johannes at sipsolutions.net
Mon Jul 20 11:26:57 PDT 2026
From: Johannes Berg <johannes.berg at intel.com>
The asm-generic futex implementation only supports UP operations,
and the normal (MMU) implementation from uaccess.c isn't built
nor would it work.
Since NOMMU shares address space anyway, it's all trivial and we
can just make a trivial implementation.
Signed-off-by: Johannes Berg <johannes.berg at intel.com>
---
arch/um/include/asm/futex.h | 53 ++++++++++++++++++++++++++++++++++++-
1 file changed, 52 insertions(+), 1 deletion(-)
diff --git a/arch/um/include/asm/futex.h b/arch/um/include/asm/futex.h
index 785fd6649aa2..ecfaad61acc0 100644
--- a/arch/um/include/asm/futex.h
+++ b/arch/um/include/asm/futex.h
@@ -12,7 +12,58 @@ int arch_futex_atomic_op_inuser(int op, u32 oparg, int *oval, u32 __user *uaddr)
int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
u32 oldval, u32 newval);
#else
+#include <linux/atomic.h>
#include <asm-generic/futex.h>
-#endif
+
+#ifdef CONFIG_SMP
+static inline int
+arch_futex_atomic_op_inuser(int op, u32 oparg, int *oval, u32 __user *uaddr)
+{
+ u32 oldval, newval;
+ u32 *p = (u32 __force *)uaddr;
+
+ do {
+ oldval = READ_ONCE(*p);
+
+ switch (op) {
+ case FUTEX_OP_SET:
+ newval = oparg;
+ break;
+ case FUTEX_OP_ADD:
+ newval = oldval + oparg;
+ break;
+ case FUTEX_OP_OR:
+ newval = oldval | oparg;
+ break;
+ case FUTEX_OP_ANDN:
+ newval = oldval & ~oparg;
+ break;
+ case FUTEX_OP_XOR:
+ newval = oldval ^ oparg;
+ break;
+ default:
+ return -ENOSYS;
+ }
+ } while (!try_cmpxchg(p, &oldval, newval));
+
+ *oval = oldval;
+ return 0;
+}
+
+static inline int
+futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
+ u32 oldval, u32 newval)
+{
+ u32 *p = (u32 __force *)uaddr;
+
+ /* FIXME - shouldn't it be *uval = cmpxchg()? */
+ *uval = *p;
+ cmpxchg(p, oldval, newval);
+
+ return 0;
+}
+#endif /* CONFIG_SMP */
+
+#endif /* CONFIG_MMU */
#endif
--
2.53.0
More information about the linux-um
mailing list