mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] s390/vdso: Implement __vdso_futex_robust_try_unlock()
@ 2026-10-19 11:12 Heiko Carstens
  2026-10-19 11:28 ` Heiko Carstens
  0 siblings, 1 reply; 2+ messages in thread
From: Heiko Carstens @ 2026-10-19 11:12 UTC (permalink / raw)
  To: Thomas Gleixner, Peter Zijlstra, André Almeida,
	Alexander Gordeev, Sven Schnelle, Vasily Gorbik,
	Christian Borntraeger
  Cc: linux-kernel, linux-s390

Provide the s390 backend for the FUTEX_ROBUST_UNLOCK fix that was
introduced for x86 with commit a2274cc0091e ("x86/vdso: Implement
__vdso_futex_robust_try_unlock()"). See that commit for details.

Note that the Fixes tag does not mean that the x86 commit is broken,
it is only helpful for backporting purposes, so required prerequisite
code is present if this commit is backported.

Cc: stable@vger.kernel.org # 7.2
Fixes: a2274cc0091e ("x86/vdso: Implement __vdso_futex_robust_try_unlock()")
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
---

Notes:
    This passes all robust_list selftests in
    tools/testing/selftests/futex/functional, except those listed below.
    
    wake32, wake_bitset32, unlock_pi32 fail, which seems to be kind of
    expected, since those selftests set FUTEX_ROBUST_LIST32, which doesn't seem
    to make too much sense for a 64 bit kernel without COMPAT support, since
    futex_robust_list_clear_pending() contains this:
    
            if (IS_ENABLED(CONFIG_64BIT) && size32bit)
                    return compat_robust_list_clear_pending(pop);
    
    which means that compat_robust_list_clear_pending() is guaranteed to do
    nothing except returning false for !COMPAT. Therefore this looks like a
    test case bug to me, but I could be entirely wrong.

 arch/s390/Kconfig                         |  1 +
 arch/s390/include/asm/futex_robust.h      | 25 +++++++++++++++++++++++
 arch/s390/kernel/vdso.c                   | 20 +++++++++++++++++-
 arch/s390/kernel/vdso/Makefile            |  7 ++++---
 arch/s390/kernel/vdso/gen_vdso_offsets.sh |  3 ++-
 arch/s390/kernel/vdso/vdso.lds.S          |  3 +++
 arch/s390/kernel/vdso/vfutex.S            | 22 ++++++++++++++++++++
 7 files changed, 76 insertions(+), 5 deletions(-)
 create mode 100644 arch/s390/include/asm/futex_robust.h
 create mode 100644 arch/s390/kernel/vdso/vfutex.S

diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 4b51bc6e8948..a58b541e06e7 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -213,6 +213,7 @@ config S390
 	select HAVE_DYNAMIC_FTRACE_WITH_REGS
 	select HAVE_EBPF_JIT if HAVE_MARCH_Z196_FEATURES
 	select HAVE_EFFICIENT_UNALIGNED_ACCESS
+	select HAVE_FUTEX_ROBUST_UNLOCK
 	select HAVE_GENERIC_TIF_BITS
 	select HAVE_GUP_FAST
 	select HAVE_FENTRY
diff --git a/arch/s390/include/asm/futex_robust.h b/arch/s390/include/asm/futex_robust.h
new file mode 100644
index 000000000000..6a5fb2506192
--- /dev/null
+++ b/arch/s390/include/asm/futex_robust.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_S390_FUTEX_ROBUST_H
+#define _ASM_S390_FUTEX_ROBUST_H
+
+#include <asm/ptrace.h>
+
+#define VDSO_FUTEX_ROBUST_POP_GPR	4
+
+static __always_inline void __user *s390_futex_robust_unlock_get_pop(struct pt_regs *regs)
+{
+	/*
+	 * Within critical section of
+	 * __vdso_futex_robust_list64_try_unlock(__u32 *lock, __u32 tid, __u64 *pop)
+	 *
+	 * If condition code is 0, cmpxchg succeeded, and the pending
+	 * op pointer in gpr4 needs to be returned for clearing.
+	 */
+	if (psw_bits(regs->psw).cc != 0)
+		return NULL;
+	return (void __user *)regs->gprs[VDSO_FUTEX_ROBUST_POP_GPR];
+}
+
+#define arch_futex_robust_unlock_get_pop(regs)	s390_futex_robust_unlock_get_pop(regs)
+
+#endif /* _ASM_S390_FUTEX_ROBUST_H */
diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c
index 0fe616c49fcc..efe492364a93 100644
--- a/arch/s390/kernel/vdso.c
+++ b/arch/s390/kernel/vdso.c
@@ -12,22 +12,39 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/futex.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
 #include <linux/smp.h>
 #include <linux/random.h>
 #include <linux/vdso_datastore.h>
 #include <vdso/datapage.h>
-#include <asm/vdso/vsyscall.h>
 #include <asm/alternative.h>
+#include <asm/vdso/vsyscall.h>
+#include <asm/vdso-symbols.h>
 #include <asm/vdso.h>
 
 extern char vdso_start[], vdso_end[];
 
+static inline void vdso_futex_robust_unlock_update_ips(void)
+{
+#ifdef CONFIG_FUTEX_ROBUST_UNLOCK
+	unsigned long vdso = current->mm->context.vdso_base;
+	struct futex_mm_data *fd = &current->mm->futex;
+
+	futex_reset_cs_ranges(fd);
+	futex_set_vdso_cs_range(fd, 0,
+				vdso + vdso_offset___futex_list64_try_unlock_cs_start,
+				vdso + vdso_offset___futex_list64_try_unlock_cs_end,
+				false);
+#endif
+}
+
 static int vdso_mremap(const struct vm_special_mapping *sm,
 		       struct vm_area_struct *vma)
 {
 	current->mm->context.vdso_base = vma->vm_start;
+	vdso_futex_robust_unlock_update_ips();
 	return 0;
 }
 
@@ -74,6 +91,7 @@ static int map_vdso(unsigned long addr, unsigned long vdso_mapping_len)
 		rc = PTR_ERR(vma);
 	} else {
 		current->mm->context.vdso_base = vdso_text_start;
+		vdso_futex_robust_unlock_update_ips();
 		rc = 0;
 	}
 out:
diff --git a/arch/s390/kernel/vdso/Makefile b/arch/s390/kernel/vdso/Makefile
index 54bcf2984ca1..35e4e3dd23c7 100644
--- a/arch/s390/kernel/vdso/Makefile
+++ b/arch/s390/kernel/vdso/Makefile
@@ -3,7 +3,8 @@
 
 # Include the generic Makefile to check the built vdso.
 include $(srctree)/lib/vdso/Makefile.include
-obj-vdso = vdso_user_wrapper.o note.o vgetrandom-chacha.o
+obj-vdso-y = vdso_user_wrapper.o note.o vgetrandom-chacha.o
+obj-vdso-$(CONFIG_FUTEX_ROBUST_UNLOCK) += vfutex.o
 obj-cvdso = vdso_generic.o getcpu.o vgetrandom.o
 VDSO_CFLAGS_REMOVE := -pg $(CC_FLAGS_FTRACE) $(CC_FLAGS_EXPOLINE)
 CFLAGS_REMOVE_getcpu.o = $(VDSO_CFLAGS_REMOVE)
@@ -16,8 +17,8 @@ endif
 
 # Build rules
 
-targets := $(obj-vdso) $(obj-cvdso) vdso.so vdso.so.dbg
-obj-vdso := $(addprefix $(obj)/, $(obj-vdso))
+targets := $(obj-vdso-y) $(obj-cvdso) vdso.so vdso.so.dbg
+obj-vdso := $(addprefix $(obj)/, $(obj-vdso-y))
 obj-cvdso := $(addprefix $(obj)/, $(obj-cvdso))
 
 KBUILD_AFLAGS_VDSO := $(KBUILD_AFLAGS) -DBUILD_VDSO
diff --git a/arch/s390/kernel/vdso/gen_vdso_offsets.sh b/arch/s390/kernel/vdso/gen_vdso_offsets.sh
index 359982fb002d..4039e6cfca51 100755
--- a/arch/s390/kernel/vdso/gen_vdso_offsets.sh
+++ b/arch/s390/kernel/vdso/gen_vdso_offsets.sh
@@ -12,4 +12,5 @@
 #
 
 LC_ALL=C
-sed -n 's/\([0-9a-f]*\) . __kernel_\(.*\)/\#define vdso_offset_\2\t0x\1/p'
+sed -n -e 's/\([0-9a-f]*\) . __kernel_\(.*\)/\#define vdso_offset_\2\t0x\1/p' \
+       -e 's/\([0-9a-f]*\) . \(__futex_.*\)/\#define vdso_offset_\2\t0x\1/p'
diff --git a/arch/s390/kernel/vdso/vdso.lds.S b/arch/s390/kernel/vdso/vdso.lds.S
index 841daeec4be2..10ea5e8fc43f 100644
--- a/arch/s390/kernel/vdso/vdso.lds.S
+++ b/arch/s390/kernel/vdso/vdso.lds.S
@@ -111,6 +111,9 @@ VERSION
 		__kernel_rt_sigreturn;
 		__kernel_sigreturn;
 		__kernel_getrandom;
+#ifdef CONFIG_FUTEX_ROBUST_UNLOCK
+		__vdso_futex_robust_list64_try_unlock;
+#endif
 	local: *;
 	};
 }
diff --git a/arch/s390/kernel/vdso/vfutex.S b/arch/s390/kernel/vdso/vfutex.S
new file mode 100644
index 000000000000..8a25bd4ecea4
--- /dev/null
+++ b/arch/s390/kernel/vdso/vfutex.S
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#include <linux/linkage.h>
+#include <asm/dwarf.h>
+
+/*
+ * __u32 __vdso_futex_robust_list64_try_unlock(__u32 *lock, __u32 tid, __u64 *pop)
+ *
+ * Returns tid on success, or lock value on failure.
+ */
+SYM_FUNC_START(__vdso_futex_robust_list64_try_unlock)
+	CFI_STARTPROC
+	lghi	%r1,0
+	cs	%r3,%r1,0(%r2)
+__futex_list64_try_unlock_cs_start:
+	jnz	__futex_list64_try_unlock_cs_end
+__futex_list64_try_unlock_cs_success:
+	mvghi	0(%r4),0
+__futex_list64_try_unlock_cs_end:
+	llgfr	%r2,%r3
+	br	%r14
+	CFI_ENDPROC
+SYM_FUNC_END(__vdso_futex_robust_list64_try_unlock)
-- 
2.53.0


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] s390/vdso: Implement __vdso_futex_robust_try_unlock()
  2026-10-19 11:12 [PATCH] s390/vdso: Implement __vdso_futex_robust_try_unlock() Heiko Carstens
@ 2026-10-19 11:28 ` Heiko Carstens
  0 siblings, 0 replies; 2+ messages in thread
From: Heiko Carstens @ 2026-10-19 11:28 UTC (permalink / raw)
  To: Heiko Carstens
  Cc: Thomas Gleixner, Peter Zijlstra, André Almeida,
	Alexander Gordeev, Sven Schnelle, Vasily Gorbik,
	Christian Borntraeger, linux-kernel, linux-s390

On Mon, Oct 19, 2026 at 01:12:33PM +0200, Heiko Carstens wrote:
> Provide the s390 backend for the FUTEX_ROBUST_UNLOCK fix that was
> introduced for x86 with commit a2274cc0091e ("x86/vdso: Implement
> __vdso_futex_robust_try_unlock()"). See that commit for details.
> 
> Note that the Fixes tag does not mean that the x86 commit is broken,
> it is only helpful for backporting purposes, so required prerequisite
> code is present if this commit is backported.
> 
> Cc: stable@vger.kernel.org # 7.2
> Fixes: a2274cc0091e ("x86/vdso: Implement __vdso_futex_robust_try_unlock()")
> Signed-off-by: Heiko Carstens <hca@linux.ibm.com>

Thinking about this again: the entire paragraph about "fixing" and
stable is nonsense. This is only about enabling FUTEX_ROBUST_UNLOCK
for s390. But the comment below about the test case remains true:

> Notes:
>     This passes all robust_list selftests in
>     tools/testing/selftests/futex/functional, except those listed below.
>     
>     wake32, wake_bitset32, unlock_pi32 fail, which seems to be kind of
>     expected, since those selftests set FUTEX_ROBUST_LIST32, which doesn't seem
>     to make too much sense for a 64 bit kernel without COMPAT support, since
>     futex_robust_list_clear_pending() contains this:
>     
>             if (IS_ENABLED(CONFIG_64BIT) && size32bit)
>                     return compat_robust_list_clear_pending(pop);
>     
>     which means that compat_robust_list_clear_pending() is guaranteed to do
>     nothing except returning false for !COMPAT. Therefore this looks like a
>     test case bug to me, but I could be entirely wrong.

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-10-19 11:28 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-19 11:12 [PATCH] s390/vdso: Implement __vdso_futex_robust_try_unlock() Heiko Carstens
2026-10-19 11:28 ` Heiko Carstens

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®