public inbox for linux-arm-kernel@lists.infradead.org 
 help / color / mirror / Atom feed
* [PATCH v3 0/5] arm64: vdso: Implement __vdso_futex_robust_try_unlock()
@ 2026-05-29 16:33 André Almeida
  2026-05-29 16:33 ` [PATCH v3 1/5] arm64: vdso: Prepare for robust futex unlock support André Almeida
                   ` (4 more replies)
  0 siblings, 5 replies; 13+ messages in thread
From: André Almeida @ 2026-05-29 16:33 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon, Thomas Gleixner, Mark Rutland,
	Mathieu Desnoyers, Sebastian Andrzej Siewior, Carlos O'Donell,
	Peter Zijlstra, Florian Weimer, Rich Felker, Torvald Riegel,
	Darren Hart, Ingo Molnar, Davidlohr Bueso, Arnd Bergmann,
	Liam R . Howlett, Uros Bizjak, Thomas Weißschuh
  Cc: linux-arm-kernel, linux-kernel, linux-arch, kernel-dev, LKML,
	André Almeida

Hi folks,

This is my take on implementing the new vDSO for unlocking a robust futex in
arm64. If you don't know what's that, Thomas wrote a good summary,
including the motivation for this work and the x86 implementation:

   https://lore.kernel.org/lkml/878qb89g7b.ffs@tglx/

This patchset depends on this series:

   https://lore.kernel.org/lkml/20260402151131.876492985@kernel.org/

The only part that I didn't figure out about this implementation is
something that I have removed from patch 01:

        /*
         * Avoid dereferencing current->mm if not returning from interrupt.
         * current->rseq.event is going to be used subsequently, so bringing the
         * cache line in is not a big deal.
         */
        if (!current->rseq.event.user_irq)
                return;

On arm64 _it seems_ that user_irq is never true. I had to remove this if
to make the code reach __futex_fixup_robust_unlock() and make the test work.

On x86, this is the callstack that sets user_irq to true:

	rseq_note_user_irq_entry
	irqentry_enter_from_user_mode
	exc_debug_user
	noist_exc_debug
	asm_exc_debug

So I'm not sure if there's something missing on arm64 and it should also hit 
irqentry_enter_from_user_mode(), or if we should look into other flag to check
if the task is returing from interrupt.

* Testing

This patchset works fine with the tests proposed at
https://lore.kernel.org/lkml/20260330120118.012924430@kernel.org/

In the series there's also a patch to adapt Sebastian's test to arm64, and it
worked:
https://lore.kernel.org/lkml/20260404093939.7XgeW_54@linutronix.de/

I also used gdb to manually check if the address is cleared when the kernel
interrupts the critical section.

Changes in v3:
 - Change asm to always use x2 to store *pop
 - Fix clang asm errors
 - Moved 32 bit entry point to vdso32/ and use littlearm asm
 - Adapted Sebastians test for arm
v2: https://patch.msgid.link/20260424-tonyk-robust_arm-v2-0-db4e46f752cf@igalia.com

Changes in v2:
 - s/CONFIG_COMPAT/CONFIG_COMPAT_VDSO (Thomas Weißschuh)
 - Fixed linker not finding the symbols (Thomas Weißschuh)
v1: https://patch.msgid.link/20260417-tonyk-robust_arm-v1-0-03aa64e2ff1a@igalia.com

---
André Almeida (5):
      arm64: vdso: Prepare for robust futex unlock support
      arm64: vdso: Implement __vdso_futex_robust_try_unlock()
      selftests: futex: Add support for aarch64 in robust_list_critical
      arm64: vdso32: Bring vdso32-offsets.h back
      arm64: vdso32: Implement __vdso_futex_robust_try_unlock()

 arch/arm64/Kconfig                                 |  1 +
 arch/arm64/Makefile                                |  2 +-
 arch/arm64/include/asm/futex_robust.h              | 20 +++++
 arch/arm64/include/asm/vdso.h                      |  3 +
 arch/arm64/kernel/vdso.c                           | 34 ++++++++
 arch/arm64/kernel/vdso/Makefile                    |  9 ++-
 arch/arm64/kernel/vdso/vdso.lds.S                  |  5 ++
 arch/arm64/kernel/vdso/vfutex.c                    | 34 ++++++++
 arch/arm64/kernel/vdso32/Makefile                  | 10 ++-
 arch/arm64/kernel/vdso32/vdso.lds.S                |  5 ++
 arch/arm64/kernel/vdso32/vfutex.c                  | 33 ++++++++
 arch/x86/entry/vdso/vma.c                          |  4 +-
 include/linux/futex.h                              | 13 +--
 include/vdso/futex.h                               |  1 +
 .../futex/functional/robust_list_critical.c        | 92 ++++++++++++++++++++--
 15 files changed, 245 insertions(+), 21 deletions(-)
---
base-commit: 78333d5371a5fe6f3eaec5e6e4c16d22fe386cbe
change-id: 20260416-tonyk-robust_arm-54ff77d2c4e4

Best regards,
--  
André Almeida <andrealmeid@igalia•com>



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

* [PATCH v3 1/5] arm64: vdso: Prepare for robust futex unlock support
  2026-05-29 16:33 [PATCH v3 0/5] arm64: vdso: Implement __vdso_futex_robust_try_unlock() André Almeida
@ 2026-05-29 16:33 ` André Almeida
  2026-05-29 17:16   ` Thomas Weißschuh
  2026-05-29 16:33 ` [PATCH v3 2/5] arm64: vdso: Implement __vdso_futex_robust_try_unlock() André Almeida
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 13+ messages in thread
From: André Almeida @ 2026-05-29 16:33 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon, Thomas Gleixner, Mark Rutland,
	Mathieu Desnoyers, Sebastian Andrzej Siewior, Carlos O'Donell,
	Peter Zijlstra, Florian Weimer, Rich Felker, Torvald Riegel,
	Darren Hart, Ingo Molnar, Davidlohr Bueso, Arnd Bergmann,
	Liam R . Howlett, Uros Bizjak, Thomas Weißschuh
  Cc: linux-arm-kernel, linux-kernel, linux-arch, kernel-dev, LKML,
	André Almeida

There will be a VDSO function to unlock non-contended robust futexes in
user space. The unlock sequence is racy vs. clearing the list_pending_op
pointer in the task's robust list head. To plug this race the kernel needs
to know the critical section window so it can clear the pointer when the
task is interrupted within that race window. The window is determined by
labels in the inline assembly.

Signed-off-by: André Almeida <andrealmeid@igalia•com>
---
Notes:
 - The diff futex_set_vdso_cs_range() should happen in the commit that
 introduced it, and rebase will clear it from here
 - So far I couldn't figure out why current->rseq.event.user_irq is never set in
 aarch64

v3:
 - Fix adding vdso base addr twice
 - Call vdso_futex_robust_unlock_update_ips() on remap as well
v2:
 - Fixed linker not finding VDSO symbols
---
 arch/arm64/kernel/vdso.c          | 25 +++++++++++++++++++++++++
 arch/arm64/kernel/vdso/vdso.lds.S |  5 +++++
 arch/x86/entry/vdso/vma.c         |  4 ++--
 include/linux/futex.h             | 13 ++-----------
 4 files changed, 34 insertions(+), 13 deletions(-)

diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
index 592dd8668de4..76f22ea8e181 100644
--- a/arch/arm64/kernel/vdso.c
+++ b/arch/arm64/kernel/vdso.c
@@ -11,6 +11,7 @@
 #include <linux/clocksource.h>
 #include <linux/elf.h>
 #include <linux/err.h>
+#include <linux/futex.h>
 #include <linux/errno.h>
 #include <linux/gfp.h>
 #include <linux/kernel.h>
@@ -57,11 +58,31 @@ static struct vdso_abi_info vdso_info[] __ro_after_init = {
 #endif /* CONFIG_COMPAT_VDSO */
 };
 
+#ifdef CONFIG_FUTEX_ROBUST_UNLOCK
+static void vdso_futex_robust_unlock_update_ips(enum vdso_abi abi, struct mm_struct *mm)
+{
+	unsigned long vdso = (unsigned long) mm->context.vdso;
+	struct futex_mm_data *fd = &mm->futex;
+	uintptr_t success, end;
+
+	if (abi == VDSO_ABI_AA64) {
+		success = (uintptr_t) VDSO_SYMBOL(vdso, futex_list64_try_unlock_cs_success);
+		end = (uintptr_t) VDSO_SYMBOL(vdso, futex_list64_try_unlock_cs_end);
+
+		futex_set_vdso_cs_range(fd, 0, success, end, false);
+	}
+}
+#else
+static inline void vdso_futex_robust_unlock_update_ips(enum vdso_abi abi, struct mm_struct *mm) { }
+#endif /* CONFIG_FUTEX_ROBUST_UNLOCK */
+
 static int vdso_mremap(const struct vm_special_mapping *sm,
 		struct vm_area_struct *new_vma)
 {
 	current->mm->context.vdso = (void *)new_vma->vm_start;
 
+	vdso_futex_robust_unlock_update_ips(VDSO_ABI_AA64, current->mm);
+
 	return 0;
 }
 
@@ -134,6 +155,8 @@ static int __setup_additional_pages(enum vdso_abi abi,
 	if (IS_ERR(ret))
 		goto up_fail;
 
+	vdso_futex_robust_unlock_update_ips(abi, mm);
+
 	return 0;
 
 up_fail:
@@ -159,6 +182,8 @@ static int aarch32_sigpage_mremap(const struct vm_special_mapping *sm,
 {
 	current->mm->context.sigpage = (void *)new_vma->vm_start;
 
+	vdso_futex_robust_unlock_update_ips(VDSO_ABI_AA32, current->mm);
+
 	return 0;
 }
 
diff --git a/arch/arm64/kernel/vdso/vdso.lds.S b/arch/arm64/kernel/vdso/vdso.lds.S
index 52314be29191..8633aafe6b81 100644
--- a/arch/arm64/kernel/vdso/vdso.lds.S
+++ b/arch/arm64/kernel/vdso/vdso.lds.S
@@ -104,6 +104,7 @@ VERSION
 		__kernel_clock_gettime;
 		__kernel_clock_getres;
 		__kernel_getrandom;
+		__vdso_futex_robust_list64_try_unlock;
 	local: *;
 	};
 }
@@ -112,3 +113,7 @@ VERSION
  * Make the sigreturn code visible to the kernel.
  */
 VDSO_sigtramp		= __kernel_rt_sigreturn;
+
+VDSO_futex_list64_try_unlock_cs_start = __futex_list64_try_unlock_cs_start;
+VDSO_futex_list64_try_unlock_cs_success = __futex_list64_try_unlock_cs_success;
+VDSO_futex_list64_try_unlock_cs_end = __futex_list64_try_unlock_cs_end;
diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c
index 357e18db0c7a..988568a62a8b 100644
--- a/arch/x86/entry/vdso/vma.c
+++ b/arch/x86/entry/vdso/vma.c
@@ -85,13 +85,13 @@ static void vdso_futex_robust_unlock_update_ips(void)
 	futex_reset_cs_ranges(fd);
 
 #ifdef CONFIG_X86_64
-	futex_set_vdso_cs_range(fd, idx, vdso, image->sym___futex_list64_try_unlock_cs_start,
+	futex_set_vdso_cs_range(fd, idx, image->sym___futex_list64_try_unlock_cs_start + vdso,
 				image->sym___futex_list64_try_unlock_cs_end, false);
 	idx++;
 #endif /* CONFIG_X86_64 */
 
 #if defined(CONFIG_X86_32) || defined(CONFIG_COMPAT)
-	futex_set_vdso_cs_range(fd, idx, vdso, image->sym___futex_list32_try_unlock_cs_start,
+	futex_set_vdso_cs_range(fd, idx, image->sym___futex_list32_try_unlock_cs_start + vdso,
 				image->sym___futex_list32_try_unlock_cs_end, true);
 #endif /* CONFIG_X86_32 || CONFIG_COMPAT */
 }
diff --git a/include/linux/futex.h b/include/linux/futex.h
index 33524dfb3fe4..cb378872e4e7 100644
--- a/include/linux/futex.h
+++ b/include/linux/futex.h
@@ -122,14 +122,6 @@ static inline void futex_fixup_robust_unlock(struct pt_regs *regs)
 {
 	struct futex_unlock_cs_range *csr;
 
-	/*
-	 * Avoid dereferencing current->mm if not returning from interrupt.
-	 * current->rseq.event is going to be used subsequently, so bringing the
-	 * cache line in is not a big deal.
-	 */
-	if (!current->rseq.event.user_irq)
-		return;
-
 	csr = current->mm->futex.unlock.cs_ranges;
 
 	/* The loop is optimized out for !COMPAT */
@@ -142,10 +134,9 @@ static inline void futex_fixup_robust_unlock(struct pt_regs *regs)
 }
 
 static inline void futex_set_vdso_cs_range(struct futex_mm_data *fd, unsigned int idx,
-					   unsigned long vdso, unsigned long start,
-					   unsigned long end, bool sz32)
+					   unsigned long start, unsigned long end, bool sz32)
 {
-	fd->unlock.cs_ranges[idx].start_ip = vdso + start;
+	fd->unlock.cs_ranges[idx].start_ip = start;
 	fd->unlock.cs_ranges[idx].len = end - start;
 	fd->unlock.cs_ranges[idx].pop_size32 = sz32;
 }

-- 
2.54.0



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

* [PATCH v3 2/5] arm64: vdso: Implement __vdso_futex_robust_try_unlock()
  2026-05-29 16:33 [PATCH v3 0/5] arm64: vdso: Implement __vdso_futex_robust_try_unlock() André Almeida
  2026-05-29 16:33 ` [PATCH v3 1/5] arm64: vdso: Prepare for robust futex unlock support André Almeida
@ 2026-05-29 16:33 ` André Almeida
  2026-05-29 17:18   ` Thomas Weißschuh
  2026-05-29 17:47   ` Mathieu Desnoyers
  2026-05-29 16:33 ` [PATCH v3 3/5] selftests: futex: Add support for aarch64 in robust_list_critical André Almeida
                   ` (2 subsequent siblings)
  4 siblings, 2 replies; 13+ messages in thread
From: André Almeida @ 2026-05-29 16:33 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon, Thomas Gleixner, Mark Rutland,
	Mathieu Desnoyers, Sebastian Andrzej Siewior, Carlos O'Donell,
	Peter Zijlstra, Florian Weimer, Rich Felker, Torvald Riegel,
	Darren Hart, Ingo Molnar, Davidlohr Bueso, Arnd Bergmann,
	Liam R . Howlett, Uros Bizjak, Thomas Weißschuh
  Cc: linux-arm-kernel, linux-kernel, linux-arch, kernel-dev, LKML,
	André Almeida

Based on the x86 implementation, implement the vDSO function for unlocking
a robust futex correctly.

Commit xxxxxxxxxxxx ("x86/vdso: Implement __vdso_futex_robust_try_unlock()") has
the full explanation about why this mechanism is needed.

The unlock assembly sequence for arm64 is:

	__vdso_futex_robust_list64_try_unlock:
	retry:
		ldxr	w8, [x0] // Load the value from *futex
		cmp	w1, w8   // Compare with TID
		b.ne	__vdso_futex_list64_try_unlock_cs_end
		stlxr	w9, wzr, [x0] // Try to zero *futex
		cbnz	w9, retry
	__vdso_futex_list64_try_unlock_cs_start:
		str	xzr, [x2] // After zeroing *futex, zero *op_pending
	__vdso_futex_list64_try_unlock_cs_end>:

The decision regarding if the pointer should be cleared or not lies on checking
the condition flag zero:

	return (regs->user_regs.pstate & PSR_Z_BIT) ?
		(void __user *) regs->user_regs.regs[2] : NULL;

If it's not zero, that means that the comparassion worked and the kernel should
clear op_pending (if userspace didn't managed to) stored at x2.

Signed-off-by: André Almeida <andrealmeid@igalia•com>
---
Notes:
 - Only LL/SC for now but I can add LSE later if this looks good

v3:
 - Managed to get pop to always be stored at x2
---
 arch/arm64/Kconfig                    |  1 +
 arch/arm64/include/asm/futex_robust.h | 20 ++++++++++++++++++++
 arch/arm64/kernel/vdso/Makefile       |  9 ++++++++-
 arch/arm64/kernel/vdso/vfutex.c       | 34 ++++++++++++++++++++++++++++++++++
 include/vdso/futex.h                  |  1 +
 5 files changed, 64 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 427151a9db7f..e10cb97a51c7 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -249,6 +249,7 @@ config ARM64
 	select HAVE_RELIABLE_STACKTRACE
 	select HAVE_POSIX_CPU_TIMERS_TASK_WORK
 	select HAVE_FUNCTION_ARG_ACCESS_API
+	select HAVE_FUTEX_ROBUST_UNLOCK
 	select MMU_GATHER_RCU_TABLE_FREE
 	select HAVE_RSEQ
 	select HAVE_RUST if RUSTC_SUPPORTS_ARM64
diff --git a/arch/arm64/include/asm/futex_robust.h b/arch/arm64/include/asm/futex_robust.h
new file mode 100644
index 000000000000..26b4006c4aeb
--- /dev/null
+++ b/arch/arm64/include/asm/futex_robust.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_ARM64_FUTEX_ROBUST_H
+#define _ASM_ARM64_FUTEX_ROBUST_H
+
+#include <asm/ptrace.h>
+
+static __always_inline void __user *arm64_futex_robust_unlock_get_pop(struct pt_regs *regs)
+{
+	/*
+	 * If Z bit is set then the ll/sc cmpxchg succeeded and the pending op
+	 * pointer needs to be cleared.
+	 */
+	return (regs->user_regs.pstate & PSR_Z_BIT) ?
+		(void __user *) regs->user_regs.regs[2] : NULL;
+}
+
+#define arch_futex_robust_unlock_get_pop(regs)	\
+	arm64_futex_robust_unlock_get_pop(regs)
+
+#endif /* _ASM_ARM64_FUTEX_ROBUST_H */
diff --git a/arch/arm64/kernel/vdso/Makefile b/arch/arm64/kernel/vdso/Makefile
index 7dec05dd33b7..3c7f220fe783 100644
--- a/arch/arm64/kernel/vdso/Makefile
+++ b/arch/arm64/kernel/vdso/Makefile
@@ -9,7 +9,8 @@
 # Include the generic Makefile to check the built vdso.
 include $(srctree)/lib/vdso/Makefile.include
 
-obj-vdso := vgettimeofday.o note.o sigreturn.o vgetrandom.o vgetrandom-chacha.o
+obj-vdso := vgettimeofday.o note.o sigreturn.o vgetrandom.o vgetrandom-chacha.o \
+	    vfutex.o
 
 # Build rules
 targets := $(obj-vdso) vdso.so vdso.so.dbg
@@ -45,9 +46,11 @@ CC_FLAGS_ADD_VDSO := -O2 -mcmodel=tiny -fasynchronous-unwind-tables
 
 CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_REMOVE_VDSO)
 CFLAGS_REMOVE_vgetrandom.o = $(CC_FLAGS_REMOVE_VDSO)
+CFLAGS_REMOVE_vfutex.o = $(CC_FLAGS_REMOVE_VDSO)
 
 CFLAGS_vgettimeofday.o = $(CC_FLAGS_ADD_VDSO)
 CFLAGS_vgetrandom.o = $(CC_FLAGS_ADD_VDSO)
+CFLAGS_vfutex.o = $(CC_FLAGS_ADD_VDSO)
 
 ifneq ($(c-gettimeofday-y),)
   CFLAGS_vgettimeofday.o += -include $(c-gettimeofday-y)
@@ -57,6 +60,10 @@ ifneq ($(c-getrandom-y),)
   CFLAGS_vgetrandom.o += -include $(c-getrandom-y)
 endif
 
+ifneq ($(c-futex-y),)
+  CFLAGS_vfutex.o += -include $(c-futex-y)
+endif
+
 targets += vdso.lds
 CPPFLAGS_vdso.lds += -P -C -U$(ARCH)
 
diff --git a/arch/arm64/kernel/vdso/vfutex.c b/arch/arm64/kernel/vdso/vfutex.c
new file mode 100644
index 000000000000..3561b869d8bb
--- /dev/null
+++ b/arch/arm64/kernel/vdso/vfutex.c
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include <linux/stringify.h>
+#include <vdso/futex.h>
+
+#define LABEL(name, sz) __stringify(__futex_list##sz##_try_unlock_cs_##name)
+
+#define GLOBLS(sz) ".globl " LABEL(start, sz) ", " LABEL(success, sz) ", " LABEL(end, sz) "\n"
+
+__u32 __vdso_futex_robust_list64_try_unlock(__u32 *lock, __u32 tid, __u64 *pop)
+{
+	register __u64 *pop_reg asm("x2") = pop;
+	__u32 val, result;
+
+	asm volatile (
+		GLOBLS(64)
+		"	prfm pstl1strm, %[lock]			\n"
+		"retry:						\n"
+		"	ldxr %w[val], %[lock]			\n"
+		"	cmp %w[tid], %w[val]			\n"
+		"	bne " LABEL(end, 64)"			\n"
+		"	stlxr %w[result], wzr, %[lock]		\n"
+		"	cbnz %w[result], retry			\n"
+		LABEL(start, 64)":				\n"
+		LABEL(success, 64)":				\n"
+		"	str xzr, %[pop_reg]			\n"
+		LABEL(end, 64)":				\n"
+
+		: [val] "=&r" (val), [result] "=&r" (result)
+		: [tid] "r" (tid), [lock] "Q" (*lock), [pop_reg] "Q" (*pop_reg)
+		: "memory"
+	);
+
+	return val;
+}
diff --git a/include/vdso/futex.h b/include/vdso/futex.h
index 3cd175eefe64..80934561a10d 100644
--- a/include/vdso/futex.h
+++ b/include/vdso/futex.h
@@ -4,6 +4,7 @@
 
 #include <uapi/linux/types.h>
 
+
 /**
  * __vdso_futex_robust_list64_try_unlock - Try to unlock an uncontended robust futex
  *					   with a 64-bit pending op pointer

-- 
2.54.0



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

* [PATCH v3 3/5] selftests: futex: Add support for aarch64 in robust_list_critical
  2026-05-29 16:33 [PATCH v3 0/5] arm64: vdso: Implement __vdso_futex_robust_try_unlock() André Almeida
  2026-05-29 16:33 ` [PATCH v3 1/5] arm64: vdso: Prepare for robust futex unlock support André Almeida
  2026-05-29 16:33 ` [PATCH v3 2/5] arm64: vdso: Implement __vdso_futex_robust_try_unlock() André Almeida
@ 2026-05-29 16:33 ` André Almeida
  2026-05-29 16:33 ` [PATCH v3 4/5] arm64: vdso32: Bring vdso32-offsets.h back André Almeida
  2026-05-29 16:33 ` [PATCH v3 5/5] arm64: vdso32: Implement __vdso_futex_robust_try_unlock() André Almeida
  4 siblings, 0 replies; 13+ messages in thread
From: André Almeida @ 2026-05-29 16:33 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon, Thomas Gleixner, Mark Rutland,
	Mathieu Desnoyers, Sebastian Andrzej Siewior, Carlos O'Donell,
	Peter Zijlstra, Florian Weimer, Rich Felker, Torvald Riegel,
	Darren Hart, Ingo Molnar, Davidlohr Bueso, Arnd Bergmann,
	Liam R . Howlett, Uros Bizjak, Thomas Weißschuh
  Cc: linux-arm-kernel, linux-kernel, linux-arch, kernel-dev, LKML,
	André Almeida

Add support for aarch64 for robust_list_critical test.

Apart from the arch specific registers, as the cmpxchg is implemented
using LL/SC, doing single steps clears the exclusive monitor and then the
store fails.

To avoid that, insert a breakpoint just after the store and let it run
continuously until there.

Signed-off-by: André Almeida <andrealmeid@igalia•com>
---
 .../futex/functional/robust_list_critical.c        | 92 ++++++++++++++++++++--
 1 file changed, 87 insertions(+), 5 deletions(-)

diff --git a/tools/testing/selftests/futex/functional/robust_list_critical.c b/tools/testing/selftests/futex/functional/robust_list_critical.c
index b9490d24eb10..a4fe69a21297 100644
--- a/tools/testing/selftests/futex/functional/robust_list_critical.c
+++ b/tools/testing/selftests/futex/functional/robust_list_critical.c
@@ -65,8 +65,9 @@ static bool pc_is_within(struct user_regs_struct *regs, uint64_t start, uint64_t
 
 #if defined(__x86_64__)
 	pc = regs->rip;
-#elif defined(__riscv)
-	pc = reg->pc;
+#elif defined(__riscv) || defined(__aarch64__)
+	pc = regs->pc;
+#else
 # error Missing ptrace support
 #endif
 	if (pc >= (long) start && pc < end)
@@ -219,12 +220,79 @@ enum trace_state {
 	STATE_LEAVE_VDSO,
 };
 
+static int ptrace_get_regs(struct user_regs_struct *regs, pid_t child)
+{
+#if defined(__x86_64__)
+
+	return ptrace(PTRACE_GETREGS, child, 0, regs);
+
+#elif defined(__aarch64__)
+
+	struct iovec io;
+	io.iov_base = regs;
+	io.iov_len = sizeof(struct user_regs_struct);
+
+	return ptrace(PTRACE_GETREGSET, child, NT_PRSTATUS, &io);
+
+#endif
+}
+
+#if defined(__aarch64__)
+/*
+ * A cmpxchg in Arm64 implemented using LL/SC can't single step on every
+ * instruction. This clears the exclusive monitor and invalidates the store.
+ * Instead, we need to add a breakpoint just after the store (on the label
+ * __futex_list64_try_unlock_cs_success) and let it be executed continuously.
+ */
+
+#define AARCH64_BRK 0xD4200000
+static void set_breakpoint(pid_t child, uint64_t *inst)
+{
+
+	long ret;
+
+	ret = ptrace(PTRACE_PEEKDATA, child, __futex_list64_try_unlock_cs_success, 0);
+	if (ret == -1)
+		err(1, "PTRACE_PEEKDATA");
+
+	*inst = (uint64_t) ret;
+
+	ret = ptrace(PTRACE_POKEDATA, child, __futex_list64_try_unlock_cs_success, AARCH64_BRK);
+	if (ret == -1)
+		err(1, "PTRACE_POKEDATA");
+}
+
+static void remove_breakpoint(pid_t child, struct user_regs_struct *regs, uint64_t inst)
+{
+	uint64_t addr = regs->pc;
+	int ret;
+
+	ret = ptrace(PTRACE_POKEDATA, child, addr, inst);
+	if (ret == -1)
+		err(1, "PTRACE_POKEDATA");
+}
+
+#define ptrace_cont()				\
+	if (ptrace(PTRACE_CONT, child, 0, 0))	\
+		err(1, "PTRACE_CONT");		\
+	continue;
+
+#else
+
+static void set_breakpoint(pid_t child, uint64_t *inst) {}
+static void remove_breakpoint(pid_t child, struct user_regs_struct *regs, uint64_t inst) {}
+
+#define ptrace_cont() {}
+
+#endif
+
 static void trace_child(struct __test_metadata *_metadata, pid_t child, bool is_32bit)
 {
 	int state = STATE_WAIT;
 	struct robust_list_head *rhead;
 	size_t sz;
-	bool do_end = false;
+	bool do_end = false, enter_cs = false;
+	uint64_t inst = 0;
 
 	syscall(SYS_get_robust_list, 0, &rhead, &sz);
 	do {
@@ -235,6 +303,7 @@ static void trace_child(struct __test_metadata *_metadata, pid_t child, bool is_
 		pid_t rpid;
 
 		rpid = waitpid(child, &wstatus, 0);
+
 		if (rpid != child)
 			errx(1, "waitpid");
 		if (!do_end) {
@@ -244,11 +313,15 @@ static void trace_child(struct __test_metadata *_metadata, pid_t child, bool is_
 			if (!WIFEXITED(wstatus))
 				errx(1, "Did not exit, but we are done");
 			ASSERT_EQ(WEXITSTATUS(wstatus), 0);
+
+			/* check if the code really reached the critical section */
+			ASSERT_EQ(enter_cs, true);
+
 			return;
 		}
 
-		if (ptrace(PTRACE_GETREGS, child, 0, &regs) != 0)
-			errx(1, "PTRACE_GETREGS");
+		if (ptrace_get_regs(&regs, child))
+			errx(1, "ptrace_get_regs");
 
 		if (is_32bit) {
 			in_vdso = pc_is_within(&regs, (long)frtu32, frtu32_end);
@@ -261,6 +334,11 @@ static void trace_child(struct __test_metadata *_metadata, pid_t child, bool is_
 			if (state == STATE_WAIT) {
 				state = STATE_ENTER_VDSO;
 
+				/* set a bp first time we enter vdso */
+				set_breakpoint(child, &inst);
+
+				/* and let the execution continue until it reaches the CS */
+				ptrace_cont();
 			} else {
 				if (is_32bit) {
 					if (pc_is_within(&regs, __futex_list32_try_unlock_cs_start,
@@ -301,8 +379,12 @@ static void trace_child(struct __test_metadata *_metadata, pid_t child, bool is_
 				if (is_32bit)
 					rhead_val &= 0xffffffff;
 
+				enter_cs = true;
 				ASSERT_EQ(rhead_val, 0);
 				ASSERT_EQ(lock_val, 0);
+
+				/* remove the breakpoint and continue execution */
+				remove_breakpoint(child, &regs, inst);
 			}
 
 			if (ptrace(PTRACE_SINGLESTEP, child, 0, 0))

-- 
2.54.0



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

* [PATCH v3 4/5] arm64: vdso32: Bring vdso32-offsets.h back
  2026-05-29 16:33 [PATCH v3 0/5] arm64: vdso: Implement __vdso_futex_robust_try_unlock() André Almeida
                   ` (2 preceding siblings ...)
  2026-05-29 16:33 ` [PATCH v3 3/5] selftests: futex: Add support for aarch64 in robust_list_critical André Almeida
@ 2026-05-29 16:33 ` André Almeida
  2026-05-29 16:33 ` [PATCH v3 5/5] arm64: vdso32: Implement __vdso_futex_robust_try_unlock() André Almeida
  4 siblings, 0 replies; 13+ messages in thread
From: André Almeida @ 2026-05-29 16:33 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon, Thomas Gleixner, Mark Rutland,
	Mathieu Desnoyers, Sebastian Andrzej Siewior, Carlos O'Donell,
	Peter Zijlstra, Florian Weimer, Rich Felker, Torvald Riegel,
	Darren Hart, Ingo Molnar, Davidlohr Bueso, Arnd Bergmann,
	Liam R . Howlett, Uros Bizjak, Thomas Weißschuh
  Cc: linux-arm-kernel, linux-kernel, linux-arch, kernel-dev, LKML,
	André Almeida

Commit c7767f5c43df ("arm64: vdso32: Remove unused vdso32-offsets.h")
removed vdso32-offsets.h because it was empty and therefore useless.

With the introduction of __vdso_futex_robust_try_unlock(), there is the
need to expose offsets again.

Signed-off-by: André Almeida <andrealmeid@igalia•com>
---
 arch/arm64/Makefile               | 2 +-
 arch/arm64/include/asm/vdso.h     | 3 +++
 arch/arm64/kernel/vdso32/Makefile | 8 ++++++++
 3 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index 73a10f65ce8b..6164d905d402 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -208,7 +208,7 @@ vdso_prepare: prepare0
 	include/generated/vdso-offsets.h arch/arm64/kernel/vdso/vdso.so
 ifdef CONFIG_COMPAT_VDSO
 	$(Q)$(MAKE) $(build)=arch/arm64/kernel/vdso32 \
-	arch/arm64/kernel/vdso32/vdso.so
+	include/generated/vdso32-offsets.h arch/arm64/kernel/vdso32/vdso.so
 endif
 endif
 
diff --git a/arch/arm64/include/asm/vdso.h b/arch/arm64/include/asm/vdso.h
index 232b46969088..43a214b93524 100644
--- a/arch/arm64/include/asm/vdso.h
+++ b/arch/arm64/include/asm/vdso.h
@@ -10,6 +10,9 @@
 #ifndef __ASSEMBLER__
 
 #include <generated/vdso-offsets.h>
+#ifdef CONFIG_COMPAT_VDSO
+#include <generated/vdso32-offsets.h>
+#endif
 
 #define VDSO_SYMBOL(base, name)						   \
 ({									   \
diff --git a/arch/arm64/kernel/vdso32/Makefile b/arch/arm64/kernel/vdso32/Makefile
index 9d0efed91414..2775843e53cd 100644
--- a/arch/arm64/kernel/vdso32/Makefile
+++ b/arch/arm64/kernel/vdso32/Makefile
@@ -136,6 +136,14 @@ $(c-obj-vdso-gettimeofday): %.o: %.c FORCE
 $(asm-obj-vdso): %.o: %.S FORCE
 	$(call if_changed_dep,vdsoas)
 
+# Generate VDSO offsets using helper script
+gen-vdsosym := $(src)/../vdso/gen_vdso_offsets.sh
+quiet_cmd_vdsosym = VDSOSYM $@
+      cmd_vdsosym = $(NM) $< | $(gen-vdsosym) | LC_ALL=C sort > $@
+
+include/generated/vdso32-offsets.h: $(obj)/vdso32.so.dbg FORCE
+	$(call if_changed,vdsosym)
+
 # Actual build commands
 quiet_cmd_vdsold_and_vdso_check = LD32    $@
       cmd_vdsold_and_vdso_check = $(cmd_vdsold); $(cmd_vdso_check)

-- 
2.54.0



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

* [PATCH v3 5/5] arm64: vdso32: Implement __vdso_futex_robust_try_unlock()
  2026-05-29 16:33 [PATCH v3 0/5] arm64: vdso: Implement __vdso_futex_robust_try_unlock() André Almeida
                   ` (3 preceding siblings ...)
  2026-05-29 16:33 ` [PATCH v3 4/5] arm64: vdso32: Bring vdso32-offsets.h back André Almeida
@ 2026-05-29 16:33 ` André Almeida
  2026-05-29 19:15   ` Mathieu Desnoyers
  2026-06-02  8:30   ` Thomas Weißschuh
  4 siblings, 2 replies; 13+ messages in thread
From: André Almeida @ 2026-05-29 16:33 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon, Thomas Gleixner, Mark Rutland,
	Mathieu Desnoyers, Sebastian Andrzej Siewior, Carlos O'Donell,
	Peter Zijlstra, Florian Weimer, Rich Felker, Torvald Riegel,
	Darren Hart, Ingo Molnar, Davidlohr Bueso, Arnd Bergmann,
	Liam R . Howlett, Uros Bizjak, Thomas Weißschuh
  Cc: linux-arm-kernel, linux-kernel, linux-arch, kernel-dev, LKML,
	André Almeida

Based on aarch64 implementation, provide a 32 bit entry point for this vDSO.

In order to keep compatibility with arm64_futex_robust_unlock_get_pop(),
make sure to store the pop address at r2.

Signed-off-by: André Almeida <andrealmeid@igalia•com>
---
 arch/arm64/kernel/vdso.c            |  9 +++++++++
 arch/arm64/kernel/vdso32/Makefile   |  2 +-
 arch/arm64/kernel/vdso32/vdso.lds.S |  5 +++++
 arch/arm64/kernel/vdso32/vfutex.c   | 33 +++++++++++++++++++++++++++++++++
 4 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
index 76f22ea8e181..3ce9d9d79431 100644
--- a/arch/arm64/kernel/vdso.c
+++ b/arch/arm64/kernel/vdso.c
@@ -71,6 +71,15 @@ static void vdso_futex_robust_unlock_update_ips(enum vdso_abi abi, struct mm_str
 
 		futex_set_vdso_cs_range(fd, 0, success, end, false);
 	}
+
+#ifdef CONFIG_COMPAT_VDSO
+	if (abi == VDSO_ABI_AA32) {
+		success = (uintptr_t) VDSO_SYMBOL(vdso, futex_list32_try_unlock_cs_success);
+		end = (uintptr_t) VDSO_SYMBOL(vdso, futex_list32_try_unlock_cs_end);
+
+		futex_set_vdso_cs_range(fd, 1, success, end, true);
+	}
+#endif
 }
 #else
 static inline void vdso_futex_robust_unlock_update_ips(enum vdso_abi abi, struct mm_struct *mm) { }
diff --git a/arch/arm64/kernel/vdso32/Makefile b/arch/arm64/kernel/vdso32/Makefile
index 2775843e53cd..cc4248539bec 100644
--- a/arch/arm64/kernel/vdso32/Makefile
+++ b/arch/arm64/kernel/vdso32/Makefile
@@ -97,7 +97,7 @@ VDSO_LDFLAGS += --orphan-handling=$(CONFIG_LD_ORPHAN_WARN_LEVEL)
 munge := ../../../arm/vdso/vdsomunge
 hostprogs := $(munge)
 
-c-obj-vdso := note.o
+c-obj-vdso := note.o vfutex.o
 c-obj-vdso-gettimeofday := vgettimeofday.o
 
 ifneq ($(c-gettimeofday-y),)
diff --git a/arch/arm64/kernel/vdso32/vdso.lds.S b/arch/arm64/kernel/vdso32/vdso.lds.S
index c374fb0146f3..31e0a3770c32 100644
--- a/arch/arm64/kernel/vdso32/vdso.lds.S
+++ b/arch/arm64/kernel/vdso32/vdso.lds.S
@@ -87,6 +87,11 @@ VERSION
 		__vdso_clock_getres;
 		__vdso_clock_gettime64;
 		__vdso_clock_getres_time64;
+		__vdso_futex_robust_list32_try_unlock;
 	local: *;
 	};
 }
+
+VDSO_futex_list32_try_unlock_cs_success = __futex_list32_try_unlock_cs_success;
+VDSO_futex_list32_try_unlock_cs_start = __futex_list32_try_unlock_cs_start;
+VDSO_futex_list32_try_unlock_cs_end = __futex_list32_try_unlock_cs_end;
diff --git a/arch/arm64/kernel/vdso32/vfutex.c b/arch/arm64/kernel/vdso32/vfutex.c
new file mode 100644
index 000000000000..a347da5ef47f
--- /dev/null
+++ b/arch/arm64/kernel/vdso32/vfutex.c
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include <linux/stringify.h>
+#include <vdso/futex.h>
+
+#define LABEL(name, sz) __stringify(__futex_list##sz##_try_unlock_cs_##name)
+
+#define GLOBLS(sz) ".globl " LABEL(start, sz) ", " LABEL(success, sz) ", " LABEL(end, sz) "\n"
+
+__u32 __vdso_futex_robust_list32_try_unlock(__u32 *lock, __u32 tid, __u32 *pop)
+{
+	register __u32 *pop_reg asm("r2") = pop;
+	__u32 val, result, zero = 0;
+
+	asm volatile (
+		GLOBLS(32)
+		"retry:						\n"
+		"	ldrex %[val], %[lock]			\n"
+		"	cmp %[tid], %[val]			\n"
+		"	bne " LABEL(end, 32)"			\n"
+		"	strex %[result], %[zero], %[lock]	\n"
+		"	cmp %[result], #0			\n"
+		"	bne retry				\n"
+		LABEL(start, 32)":				\n"
+		LABEL(success, 32)":				\n"
+		"	str %[zero], %[pop_reg]			\n"
+		LABEL(end, 32)":				\n"
+		: [val] "=&r" (val), [result] "=r" (result)
+		: [tid] "r" (tid), [lock] "Q" (*lock), [pop_reg] "Q" (*pop_reg), [zero] "r" (zero)
+		: "memory"
+	);
+
+	return val;
+}

-- 
2.54.0



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

* Re: [PATCH v3 1/5] arm64: vdso: Prepare for robust futex unlock support
  2026-05-29 16:33 ` [PATCH v3 1/5] arm64: vdso: Prepare for robust futex unlock support André Almeida
@ 2026-05-29 17:16   ` Thomas Weißschuh
  2026-06-01 16:17     ` André Almeida
  0 siblings, 1 reply; 13+ messages in thread
From: Thomas Weißschuh @ 2026-05-29 17:16 UTC (permalink / raw)
  To: André Almeida
  Cc: Catalin Marinas, Will Deacon, Thomas Gleixner, Mark Rutland,
	Mathieu Desnoyers, Sebastian Andrzej Siewior, Carlos O'Donell,
	Peter Zijlstra, Florian Weimer, Rich Felker, Torvald Riegel,
	Darren Hart, Ingo Molnar, Davidlohr Bueso, Arnd Bergmann,
	Liam R . Howlett, Uros Bizjak, linux-arm-kernel, linux-kernel,
	linux-arch, kernel-dev

On 2026-05-29 13:33:53-0300, André Almeida wrote:
> There will be a VDSO function to unlock non-contended robust futexes in
> user space. The unlock sequence is racy vs. clearing the list_pending_op
> pointer in the task's robust list head. To plug this race the kernel needs
> to know the critical section window so it can clear the pointer when the
> task is interrupted within that race window. The window is determined by
> labels in the inline assembly.
> 
> Signed-off-by: André Almeida <andrealmeid@igalia•com>
> ---
> Notes:
>  - The diff futex_set_vdso_cs_range() should happen in the commit that
>  introduced it, and rebase will clear it from here
>  - So far I couldn't figure out why current->rseq.event.user_irq is never set in
>  aarch64

Why not put these unrelated changes into their own commits?
It makes reviewing and integrating it into the original series easier.

> v3:
>  - Fix adding vdso base addr twice
>  - Call vdso_futex_robust_unlock_update_ips() on remap as well
> v2:
>  - Fixed linker not finding VDSO symbols
> ---
>  arch/arm64/kernel/vdso.c          | 25 +++++++++++++++++++++++++
>  arch/arm64/kernel/vdso/vdso.lds.S |  5 +++++
>  arch/x86/entry/vdso/vma.c         |  4 ++--
>  include/linux/futex.h             | 13 ++-----------
>  4 files changed, 34 insertions(+), 13 deletions(-)
> 
> diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
> index 592dd8668de4..76f22ea8e181 100644
> --- a/arch/arm64/kernel/vdso.c
> +++ b/arch/arm64/kernel/vdso.c
> @@ -11,6 +11,7 @@
>  #include <linux/clocksource.h>
>  #include <linux/elf.h>
>  #include <linux/err.h>
> +#include <linux/futex.h>
>  #include <linux/errno.h>
>  #include <linux/gfp.h>
>  #include <linux/kernel.h>
> @@ -57,11 +58,31 @@ static struct vdso_abi_info vdso_info[] __ro_after_init = {
>  #endif /* CONFIG_COMPAT_VDSO */
>  };
>  
> +#ifdef CONFIG_FUTEX_ROBUST_UNLOCK
> +static void vdso_futex_robust_unlock_update_ips(enum vdso_abi abi, struct mm_struct *mm)
> +{
> +	unsigned long vdso = (unsigned long) mm->context.vdso;
> +	struct futex_mm_data *fd = &mm->futex;
> +	uintptr_t success, end;
> +
> +	if (abi == VDSO_ABI_AA64) {
> +		success = (uintptr_t) VDSO_SYMBOL(vdso, futex_list64_try_unlock_cs_success);
> +		end = (uintptr_t) VDSO_SYMBOL(vdso, futex_list64_try_unlock_cs_end);
> +
> +		futex_set_vdso_cs_range(fd, 0, success, end, false);
> +	}
> +}
> +#else
> +static inline void vdso_futex_robust_unlock_update_ips(enum vdso_abi abi, struct mm_struct *mm) { }
> +#endif /* CONFIG_FUTEX_ROBUST_UNLOCK */
> +
>  static int vdso_mremap(const struct vm_special_mapping *sm,
>  		struct vm_area_struct *new_vma)
>  {
>  	current->mm->context.vdso = (void *)new_vma->vm_start;
>  
> +	vdso_futex_robust_unlock_update_ips(VDSO_ABI_AA64, current->mm);
> +
>  	return 0;
>  }
>  
> @@ -134,6 +155,8 @@ static int __setup_additional_pages(enum vdso_abi abi,
>  	if (IS_ERR(ret))
>  		goto up_fail;
>  
> +	vdso_futex_robust_unlock_update_ips(abi, mm);
> +
>  	return 0;
>  
>  up_fail:
> @@ -159,6 +182,8 @@ static int aarch32_sigpage_mremap(const struct vm_special_mapping *sm,
>  {
>  	current->mm->context.sigpage = (void *)new_vma->vm_start;
>  
> +	vdso_futex_robust_unlock_update_ips(VDSO_ABI_AA32, current->mm);

This is for the sigpage remap, not the vDSO, is it really necessary?
If yes it should be part of the later VDSO_ABI_AA32 patch IMO.


If there is a way for a 64-bit application to call 32-bit syscalls then 
the 64-bit vDSO also needs the 32-bit functions. See:
[0] https://lore.kernel.org/lkml/875x4zw4bp.ffs@tglx/

>  	return 0;
>  }
>  
> diff --git a/arch/arm64/kernel/vdso/vdso.lds.S b/arch/arm64/kernel/vdso/vdso.lds.S
> index 52314be29191..8633aafe6b81 100644
> --- a/arch/arm64/kernel/vdso/vdso.lds.S
> +++ b/arch/arm64/kernel/vdso/vdso.lds.S
> @@ -104,6 +104,7 @@ VERSION
>  		__kernel_clock_gettime;
>  		__kernel_clock_getres;
>  		__kernel_getrandom;
> +		__vdso_futex_robust_list64_try_unlock;

Guard behind CONFIG_FUTEX_ROBUST_UNLOCK ?

ld.lld fails when a function mentioned in the linker script is missing.

>  	local: *;
>  	};
>  }
> @@ -112,3 +113,7 @@ VERSION
>   * Make the sigreturn code visible to the kernel.
>   */
>  VDSO_sigtramp		= __kernel_rt_sigreturn;
> +
> +VDSO_futex_list64_try_unlock_cs_start = __futex_list64_try_unlock_cs_start;
> +VDSO_futex_list64_try_unlock_cs_success = __futex_list64_try_unlock_cs_success;
> +VDSO_futex_list64_try_unlock_cs_end = __futex_list64_try_unlock_cs_end;

(...)


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

* Re: [PATCH v3 2/5] arm64: vdso: Implement __vdso_futex_robust_try_unlock()
  2026-05-29 16:33 ` [PATCH v3 2/5] arm64: vdso: Implement __vdso_futex_robust_try_unlock() André Almeida
@ 2026-05-29 17:18   ` Thomas Weißschuh
  2026-05-29 17:47   ` Mathieu Desnoyers
  1 sibling, 0 replies; 13+ messages in thread
From: Thomas Weißschuh @ 2026-05-29 17:18 UTC (permalink / raw)
  To: André Almeida
  Cc: Catalin Marinas, Will Deacon, Thomas Gleixner, Mark Rutland,
	Mathieu Desnoyers, Sebastian Andrzej Siewior, Carlos O'Donell,
	Peter Zijlstra, Florian Weimer, Rich Felker, Torvald Riegel,
	Darren Hart, Ingo Molnar, Davidlohr Bueso, Arnd Bergmann,
	Liam R . Howlett, Uros Bizjak, linux-arm-kernel, linux-kernel,
	linux-arch, kernel-dev

On 2026-05-29 13:33:54-0300, André Almeida wrote:
> Based on the x86 implementation, implement the vDSO function for unlocking
> a robust futex correctly.
> 
> Commit xxxxxxxxxxxx ("x86/vdso: Implement __vdso_futex_robust_try_unlock()") has
> the full explanation about why this mechanism is needed.
> 
> The unlock assembly sequence for arm64 is:
> 
> 	__vdso_futex_robust_list64_try_unlock:
> 	retry:
> 		ldxr	w8, [x0] // Load the value from *futex
> 		cmp	w1, w8   // Compare with TID
> 		b.ne	__vdso_futex_list64_try_unlock_cs_end
> 		stlxr	w9, wzr, [x0] // Try to zero *futex
> 		cbnz	w9, retry
> 	__vdso_futex_list64_try_unlock_cs_start:
> 		str	xzr, [x2] // After zeroing *futex, zero *op_pending
> 	__vdso_futex_list64_try_unlock_cs_end>:
> 
> The decision regarding if the pointer should be cleared or not lies on checking
> the condition flag zero:
> 
> 	return (regs->user_regs.pstate & PSR_Z_BIT) ?
> 		(void __user *) regs->user_regs.regs[2] : NULL;
> 
> If it's not zero, that means that the comparassion worked and the kernel should
> clear op_pending (if userspace didn't managed to) stored at x2.
> 
> Signed-off-by: André Almeida <andrealmeid@igalia•com>
> ---
> Notes:
>  - Only LL/SC for now but I can add LSE later if this looks good
> 
> v3:
>  - Managed to get pop to always be stored at x2
> ---
>  arch/arm64/Kconfig                    |  1 +
>  arch/arm64/include/asm/futex_robust.h | 20 ++++++++++++++++++++
>  arch/arm64/kernel/vdso/Makefile       |  9 ++++++++-
>  arch/arm64/kernel/vdso/vfutex.c       | 34 ++++++++++++++++++++++++++++++++++
>  include/vdso/futex.h                  |  1 +
>  5 files changed, 64 insertions(+), 1 deletion(-)

(...)

> diff --git a/arch/arm64/kernel/vdso/Makefile b/arch/arm64/kernel/vdso/Makefile
> index 7dec05dd33b7..3c7f220fe783 100644
> --- a/arch/arm64/kernel/vdso/Makefile
> +++ b/arch/arm64/kernel/vdso/Makefile
> @@ -9,7 +9,8 @@
>  # Include the generic Makefile to check the built vdso.
>  include $(srctree)/lib/vdso/Makefile.include
>  
> -obj-vdso := vgettimeofday.o note.o sigreturn.o vgetrandom.o vgetrandom-chacha.o
> +obj-vdso := vgettimeofday.o note.o sigreturn.o vgetrandom.o vgetrandom-chacha.o \
> +	    vfutex.o

Should depend on CONFIG_FUTEX_ROBUST_UNLOCK ?

>  
>  # Build rules
>  targets := $(obj-vdso) vdso.so vdso.so.dbg
> @@ -45,9 +46,11 @@ CC_FLAGS_ADD_VDSO := -O2 -mcmodel=tiny -fasynchronous-unwind-tables
>  
>  CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_REMOVE_VDSO)
>  CFLAGS_REMOVE_vgetrandom.o = $(CC_FLAGS_REMOVE_VDSO)
> +CFLAGS_REMOVE_vfutex.o = $(CC_FLAGS_REMOVE_VDSO)
>  
>  CFLAGS_vgettimeofday.o = $(CC_FLAGS_ADD_VDSO)
>  CFLAGS_vgetrandom.o = $(CC_FLAGS_ADD_VDSO)
> +CFLAGS_vfutex.o = $(CC_FLAGS_ADD_VDSO)
>  
>  ifneq ($(c-gettimeofday-y),)
>    CFLAGS_vgettimeofday.o += -include $(c-gettimeofday-y)
> @@ -57,6 +60,10 @@ ifneq ($(c-getrandom-y),)
>    CFLAGS_vgetrandom.o += -include $(c-getrandom-y)
>  endif
>  
> +ifneq ($(c-futex-y),)
> +  CFLAGS_vfutex.o += -include $(c-futex-y)
> +endif
> +
>  targets += vdso.lds
>  CPPFLAGS_vdso.lds += -P -C -U$(ARCH)

(...)

> diff --git a/include/vdso/futex.h b/include/vdso/futex.h
> index 3cd175eefe64..80934561a10d 100644
> --- a/include/vdso/futex.h
> +++ b/include/vdso/futex.h
> @@ -4,6 +4,7 @@
>  
>  #include <uapi/linux/types.h>
>  
> +

Spurious change.

>  /**
>   * __vdso_futex_robust_list64_try_unlock - Try to unlock an uncontended robust futex
>   *					   with a 64-bit pending op pointer
> 
> -- 
> 2.54.0
> 


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

* Re: [PATCH v3 2/5] arm64: vdso: Implement __vdso_futex_robust_try_unlock()
  2026-05-29 16:33 ` [PATCH v3 2/5] arm64: vdso: Implement __vdso_futex_robust_try_unlock() André Almeida
  2026-05-29 17:18   ` Thomas Weißschuh
@ 2026-05-29 17:47   ` Mathieu Desnoyers
  2026-06-01 16:22     ` André Almeida
  1 sibling, 1 reply; 13+ messages in thread
From: Mathieu Desnoyers @ 2026-05-29 17:47 UTC (permalink / raw)
  To: André Almeida, Catalin Marinas, Will Deacon, Thomas Gleixner,
	Mark Rutland, Sebastian Andrzej Siewior, Carlos O'Donell,
	Peter Zijlstra, Florian Weimer, Rich Felker, Torvald Riegel,
	Darren Hart, Ingo Molnar, Davidlohr Bueso, Arnd Bergmann,
	Liam R . Howlett, Uros Bizjak, Thomas Weißschuh
  Cc: linux-arm-kernel, linux-kernel, linux-arch, kernel-dev

On 2026-05-29 12:33, André Almeida wrote:
> Based on the x86 implementation, implement the vDSO function for unlocking
> a robust futex correctly.
> 
> Commit xxxxxxxxxxxx ("x86/vdso: Implement __vdso_futex_robust_try_unlock()") has
> the full explanation about why this mechanism is needed.
> 
> The unlock assembly sequence for arm64 is:
> 
> 	__vdso_futex_robust_list64_try_unlock:
> 	retry:
> 		ldxr	w8, [x0] // Load the value from *futex
> 		cmp	w1, w8   // Compare with TID
> 		b.ne	__vdso_futex_list64_try_unlock_cs_end
> 		stlxr	w9, wzr, [x0] // Try to zero *futex

So it looks like stlxr can be successful, and the process is killed
right here. This is not within the start/end critical section, so the
fixup is missed ? Or am I missing something ?

> 		cbnz	w9, retry
> 	__vdso_futex_list64_try_unlock_cs_start:
> 		str	xzr, [x2] // After zeroing *futex, zero *op_pending
> 	__vdso_futex_list64_try_unlock_cs_end>:
> 
> The decision regarding if the pointer should be cleared or not lies on checking
> the condition flag zero:
> 
> 	return (regs->user_regs.pstate & PSR_Z_BIT) ?
> 		(void __user *) regs->user_regs.regs[2] : NULL;
> 
> If it's not zero, that means that the comparassion worked and the kernel should

comparison

> clear op_pending (if userspace didn't managed to) stored at x2.
Thanks,

Mathieu

-- 
Mathieu Desnoyers
EfficiOS Inc.
https://www.efficios.com


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

* Re: [PATCH v3 5/5] arm64: vdso32: Implement __vdso_futex_robust_try_unlock()
  2026-05-29 16:33 ` [PATCH v3 5/5] arm64: vdso32: Implement __vdso_futex_robust_try_unlock() André Almeida
@ 2026-05-29 19:15   ` Mathieu Desnoyers
  2026-06-02  8:30   ` Thomas Weißschuh
  1 sibling, 0 replies; 13+ messages in thread
From: Mathieu Desnoyers @ 2026-05-29 19:15 UTC (permalink / raw)
  To: André Almeida, Catalin Marinas, Will Deacon, Thomas Gleixner,
	Mark Rutland, Sebastian Andrzej Siewior, Carlos O'Donell,
	Peter Zijlstra, Florian Weimer, Rich Felker, Torvald Riegel,
	Darren Hart, Ingo Molnar, Davidlohr Bueso, Arnd Bergmann,
	Liam R . Howlett, Uros Bizjak, Thomas Weißschuh
  Cc: linux-arm-kernel, linux-kernel, linux-arch, kernel-dev

> +__u32 __vdso_futex_robust_list32_try_unlock(__u32 *lock, __u32 tid, __u32 *pop)
> +{
> +	register __u32 *pop_reg asm("r2") = pop;
> +	__u32 val, result, zero = 0;
> +
> +	asm volatile (
> +		GLOBLS(32)
> +		"retry:						\n"
> +		"	ldrex %[val], %[lock]			\n"
> +		"	cmp %[tid], %[val]			\n"
> +		"	bne " LABEL(end, 32)"			\n"
> +		"	strex %[result], %[zero], %[lock]	\n"

Here too the address range between strex (success) and start is not
covered. Failure to fixup if the process is killed here.

Thanks,

Mathieu


-- 
Mathieu Desnoyers
EfficiOS Inc.
https://www.efficios.com


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

* Re: [PATCH v3 1/5] arm64: vdso: Prepare for robust futex unlock support
  2026-05-29 17:16   ` Thomas Weißschuh
@ 2026-06-01 16:17     ` André Almeida
  0 siblings, 0 replies; 13+ messages in thread
From: André Almeida @ 2026-06-01 16:17 UTC (permalink / raw)
  To: Thomas Weißschuh
  Cc: Catalin Marinas, Will Deacon, Thomas Gleixner, Mark Rutland,
	Mathieu Desnoyers, Sebastian Andrzej Siewior, Carlos O'Donell,
	Peter Zijlstra, Florian Weimer, Rich Felker, Torvald Riegel,
	Darren Hart, Ingo Molnar, Davidlohr Bueso, Arnd Bergmann,
	Liam R . Howlett, Uros Bizjak, linux-arm-kernel, linux-kernel,
	linux-arch, kernel-dev

Em 29/05/2026 14:16, Thomas Weißschuh escreveu:
> On 2026-05-29 13:33:53-0300, André Almeida wrote:
>> There will be a VDSO function to unlock non-contended robust futexes in
>> user space. The unlock sequence is racy vs. clearing the list_pending_op
>> pointer in the task's robust list head. To plug this race the kernel needs
>> to know the critical section window so it can clear the pointer when the
>> task is interrupted within that race window. The window is determined by
>> labels in the inline assembly.
>>
>> Signed-off-by: André Almeida <andrealmeid@igalia•com>
>> ---
>> Notes:
>>   - The diff futex_set_vdso_cs_range() should happen in the commit that
>>   introduced it, and rebase will clear it from here
>>   - So far I couldn't figure out why current->rseq.event.user_irq is never set in
>>   aarch64
> 
> Why not put these unrelated changes into their own commits?
> It makes reviewing and integrating it into the original series easier.
> 

OK, I will separated them for a next version. But hopefully those 
changes won't be needed for the next one.

>> v3:
>>   - Fix adding vdso base addr twice
>>   - Call vdso_futex_robust_unlock_update_ips() on remap as well
>> v2:
>>   - Fixed linker not finding VDSO symbols
>> ---
>>   arch/arm64/kernel/vdso.c          | 25 +++++++++++++++++++++++++
>>   arch/arm64/kernel/vdso/vdso.lds.S |  5 +++++
>>   arch/x86/entry/vdso/vma.c         |  4 ++--
>>   include/linux/futex.h             | 13 ++-----------
>>   4 files changed, 34 insertions(+), 13 deletions(-)
>>
>> diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
>> index 592dd8668de4..76f22ea8e181 100644
>> --- a/arch/arm64/kernel/vdso.c
>> +++ b/arch/arm64/kernel/vdso.c
>> @@ -11,6 +11,7 @@
>>   #include <linux/clocksource.h>
>>   #include <linux/elf.h>
>>   #include <linux/err.h>
>> +#include <linux/futex.h>
>>   #include <linux/errno.h>
>>   #include <linux/gfp.h>
>>   #include <linux/kernel.h>
>> @@ -57,11 +58,31 @@ static struct vdso_abi_info vdso_info[] __ro_after_init = {
>>   #endif /* CONFIG_COMPAT_VDSO */
>>   };
>>   
>> +#ifdef CONFIG_FUTEX_ROBUST_UNLOCK
>> +static void vdso_futex_robust_unlock_update_ips(enum vdso_abi abi, struct mm_struct *mm)
>> +{
>> +	unsigned long vdso = (unsigned long) mm->context.vdso;
>> +	struct futex_mm_data *fd = &mm->futex;
>> +	uintptr_t success, end;
>> +
>> +	if (abi == VDSO_ABI_AA64) {
>> +		success = (uintptr_t) VDSO_SYMBOL(vdso, futex_list64_try_unlock_cs_success);
>> +		end = (uintptr_t) VDSO_SYMBOL(vdso, futex_list64_try_unlock_cs_end);
>> +
>> +		futex_set_vdso_cs_range(fd, 0, success, end, false);
>> +	}
>> +}
>> +#else
>> +static inline void vdso_futex_robust_unlock_update_ips(enum vdso_abi abi, struct mm_struct *mm) { }
>> +#endif /* CONFIG_FUTEX_ROBUST_UNLOCK */
>> +
>>   static int vdso_mremap(const struct vm_special_mapping *sm,
>>   		struct vm_area_struct *new_vma)
>>   {
>>   	current->mm->context.vdso = (void *)new_vma->vm_start;
>>   
>> +	vdso_futex_robust_unlock_update_ips(VDSO_ABI_AA64, current->mm);
>> +
>>   	return 0;
>>   }
>>   
>> @@ -134,6 +155,8 @@ static int __setup_additional_pages(enum vdso_abi abi,
>>   	if (IS_ERR(ret))
>>   		goto up_fail;
>>   
>> +	vdso_futex_robust_unlock_update_ips(abi, mm);
>> +
>>   	return 0;
>>   
>>   up_fail:
>> @@ -159,6 +182,8 @@ static int aarch32_sigpage_mremap(const struct vm_special_mapping *sm,
>>   {
>>   	current->mm->context.sigpage = (void *)new_vma->vm_start;
>>   
>> +	vdso_futex_robust_unlock_update_ips(VDSO_ABI_AA32, current->mm);
> 
> This is for the sigpage remap, not the vDSO, is it really necessary?
> If yes it should be part of the later VDSO_ABI_AA32 patch IMO.
> 

Ok, I don't think it moves the vDSO indeed.

> 
> If there is a way for a 64-bit application to call 32-bit syscalls then
> the 64-bit vDSO also needs the 32-bit functions. See:
> [0] https://lore.kernel.org/lkml/875x4zw4bp.ffs@tglx/
> 

I believe this is true for x86, but not for aarch64. Currently x86 apps 
running on top of arm64 have no way to register a 32 bit list, but this 
will change with the upcoming multi list feature.
>>   	return 0;
>>   }
>>   
>> diff --git a/arch/arm64/kernel/vdso/vdso.lds.S b/arch/arm64/kernel/vdso/vdso.lds.S
>> index 52314be29191..8633aafe6b81 100644
>> --- a/arch/arm64/kernel/vdso/vdso.lds.S
>> +++ b/arch/arm64/kernel/vdso/vdso.lds.S
>> @@ -104,6 +104,7 @@ VERSION
>>   		__kernel_clock_gettime;
>>   		__kernel_clock_getres;
>>   		__kernel_getrandom;
>> +		__vdso_futex_robust_list64_try_unlock;
> 
> Guard behind CONFIG_FUTEX_ROBUST_UNLOCK ?
> 
> ld.lld fails when a function mentioned in the linker script is missing.

Yes, you are right, thanks for the review!

> 
>>   	local: *;
>>   	};
>>   }
>> @@ -112,3 +113,7 @@ VERSION
>>    * Make the sigreturn code visible to the kernel.
>>    */
>>   VDSO_sigtramp		= __kernel_rt_sigreturn;
>> +
>> +VDSO_futex_list64_try_unlock_cs_start = __futex_list64_try_unlock_cs_start;
>> +VDSO_futex_list64_try_unlock_cs_success = __futex_list64_try_unlock_cs_success;
>> +VDSO_futex_list64_try_unlock_cs_end = __futex_list64_try_unlock_cs_end;
> 
> (...)



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

* Re: [PATCH v3 2/5] arm64: vdso: Implement __vdso_futex_robust_try_unlock()
  2026-05-29 17:47   ` Mathieu Desnoyers
@ 2026-06-01 16:22     ` André Almeida
  0 siblings, 0 replies; 13+ messages in thread
From: André Almeida @ 2026-06-01 16:22 UTC (permalink / raw)
  To: Mathieu Desnoyers
  Cc: linux-arm-kernel, Rich Felker, Florian Weimer, Thomas Gleixner,
	Peter Zijlstra, Davidlohr Bueso, Sebastian Andrzej Siewior,
	Carlos O'Donell, Thomas Weißschuh, Will Deacon,
	Catalin Marinas, Uros Bizjak, Arnd Bergmann, Darren Hart,
	Liam R . Howlett, Torvald Riegel, Ingo Molnar, linux-kernel,
	linux-arch, kernel-dev, Mark Rutland

Em 29/05/2026 14:47, Mathieu Desnoyers escreveu:
> On 2026-05-29 12:33, André Almeida wrote:
>> Based on the x86 implementation, implement the vDSO function for 
>> unlocking
>> a robust futex correctly.
>>
>> Commit xxxxxxxxxxxx ("x86/vdso: Implement 
>> __vdso_futex_robust_try_unlock()") has
>> the full explanation about why this mechanism is needed.
>>
>> The unlock assembly sequence for arm64 is:
>>
>>     __vdso_futex_robust_list64_try_unlock:
>>     retry:
>>         ldxr    w8, [x0] // Load the value from *futex
>>         cmp    w1, w8   // Compare with TID
>>         b.ne    __vdso_futex_list64_try_unlock_cs_end
>>         stlxr    w9, wzr, [x0] // Try to zero *futex
> 
> So it looks like stlxr can be successful, and the process is killed
> right here. This is not within the start/end critical section, so the
> fixup is missed ? Or am I missing something ?
> 

As me and Mathieu discussed on IRC, this should be the right thing to do 
here:

  - Move the critical section label one instruction above to include 
`cbnz` on it
  - Use the result register as the check for the store success, not the 
zero flag register.

So it will look like this:

	__vdso_futex_robust_list64_try_unlock:
	retry:
		ldxr	w8, [x0] // Load the value from *futex
		cmp	w1, w8   // Compare with TID
		b.ne	__vdso_futex_list64_try_unlock_cs_end
		stlxr	w9, wzr, [x0] // Try to zero *futex
	__vdso_futex_list64_try_unlock_cs_start:
		cbnz	w9, retry
		str	xzr, [x2] // After zeroing *futex, zero *op_pending
	__vdso_futex_list64_try_unlock_cs_end>:

The decision regarding if the pointer should be cleared or not lies on 
checking the result register:

	return (regs->user_regs[9]) ? NULL :
		(void __user *) regs->user_regs.regs[2];

Thanks for the review!


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

* Re: [PATCH v3 5/5] arm64: vdso32: Implement __vdso_futex_robust_try_unlock()
  2026-05-29 16:33 ` [PATCH v3 5/5] arm64: vdso32: Implement __vdso_futex_robust_try_unlock() André Almeida
  2026-05-29 19:15   ` Mathieu Desnoyers
@ 2026-06-02  8:30   ` Thomas Weißschuh
  1 sibling, 0 replies; 13+ messages in thread
From: Thomas Weißschuh @ 2026-06-02  8:30 UTC (permalink / raw)
  To: André Almeida
  Cc: Catalin Marinas, Will Deacon, Thomas Gleixner, Mark Rutland,
	Mathieu Desnoyers, Sebastian Andrzej Siewior, Carlos O'Donell,
	Peter Zijlstra, Florian Weimer, Rich Felker, Torvald Riegel,
	Darren Hart, Ingo Molnar, Davidlohr Bueso, Arnd Bergmann,
	Liam R . Howlett, Uros Bizjak, linux-arm-kernel, linux-kernel,
	linux-arch, kernel-dev

On 2026-05-29 13:33:57-0300, André Almeida wrote:
> Based on aarch64 implementation, provide a 32 bit entry point for this vDSO.
> 
> In order to keep compatibility with arm64_futex_robust_unlock_get_pop(),
> make sure to store the pop address at r2.
> 
> Signed-off-by: André Almeida <andrealmeid@igalia•com>
> ---
>  arch/arm64/kernel/vdso.c            |  9 +++++++++
>  arch/arm64/kernel/vdso32/Makefile   |  2 +-
>  arch/arm64/kernel/vdso32/vdso.lds.S |  5 +++++
>  arch/arm64/kernel/vdso32/vfutex.c   | 33 +++++++++++++++++++++++++++++++++
>  4 files changed, 48 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
> index 76f22ea8e181..3ce9d9d79431 100644
> --- a/arch/arm64/kernel/vdso.c
> +++ b/arch/arm64/kernel/vdso.c
> @@ -71,6 +71,15 @@ static void vdso_futex_robust_unlock_update_ips(enum vdso_abi abi, struct mm_str
>  
>  		futex_set_vdso_cs_range(fd, 0, success, end, false);
>  	}
> +
> +#ifdef CONFIG_COMPAT_VDSO
> +	if (abi == VDSO_ABI_AA32) {
> +		success = (uintptr_t) VDSO_SYMBOL(vdso, futex_list32_try_unlock_cs_success);
> +		end = (uintptr_t) VDSO_SYMBOL(vdso, futex_list32_try_unlock_cs_end);
> +
> +		futex_set_vdso_cs_range(fd, 1, success, end, true);

Should also be idx = 0, I think.

> +	}
> +#endif
>  }
>  #else
>  static inline void vdso_futex_robust_unlock_update_ips(enum vdso_abi abi, struct mm_struct *mm) { }
> diff --git a/arch/arm64/kernel/vdso32/Makefile b/arch/arm64/kernel/vdso32/Makefile
> index 2775843e53cd..cc4248539bec 100644
> --- a/arch/arm64/kernel/vdso32/Makefile
> +++ b/arch/arm64/kernel/vdso32/Makefile
> @@ -97,7 +97,7 @@ VDSO_LDFLAGS += --orphan-handling=$(CONFIG_LD_ORPHAN_WARN_LEVEL)
>  munge := ../../../arm/vdso/vdsomunge
>  hostprogs := $(munge)
>  
> -c-obj-vdso := note.o
> +c-obj-vdso := note.o vfutex.o

#ifdef CONFIG_FUTEX_ROBUST_UNLOCK

>  c-obj-vdso-gettimeofday := vgettimeofday.o
>  
>  ifneq ($(c-gettimeofday-y),)
> diff --git a/arch/arm64/kernel/vdso32/vdso.lds.S b/arch/arm64/kernel/vdso32/vdso.lds.S
> index c374fb0146f3..31e0a3770c32 100644
> --- a/arch/arm64/kernel/vdso32/vdso.lds.S
> +++ b/arch/arm64/kernel/vdso32/vdso.lds.S
> @@ -87,6 +87,11 @@ VERSION
>  		__vdso_clock_getres;
>  		__vdso_clock_gettime64;
>  		__vdso_clock_getres_time64;
> +		__vdso_futex_robust_list32_try_unlock;

#ifdef CONFIG_FUTEX_ROBUST_UNLOCK

>  	local: *;
>  	};
>  }
> +
> +VDSO_futex_list32_try_unlock_cs_success = __futex_list32_try_unlock_cs_success;
> +VDSO_futex_list32_try_unlock_cs_start = __futex_list32_try_unlock_cs_start;
> +VDSO_futex_list32_try_unlock_cs_end = __futex_list32_try_unlock_cs_end;

When support for 32-bit robust lists will be added to the 64-bit vDSO
then both vDSOs will have these symbols and they will conflict.
Maybe add VDSO32_SYMBOL() which uses a different namespace than the
regular VDSO_SYMBOL(). And teach gen_vdso_offsets.sh to use that
namespace.

(...)


Thomas


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

end of thread, other threads:[~2026-06-02  8:30 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-29 16:33 [PATCH v3 0/5] arm64: vdso: Implement __vdso_futex_robust_try_unlock() André Almeida
2026-05-29 16:33 ` [PATCH v3 1/5] arm64: vdso: Prepare for robust futex unlock support André Almeida
2026-05-29 17:16   ` Thomas Weißschuh
2026-06-01 16:17     ` André Almeida
2026-05-29 16:33 ` [PATCH v3 2/5] arm64: vdso: Implement __vdso_futex_robust_try_unlock() André Almeida
2026-05-29 17:18   ` Thomas Weißschuh
2026-05-29 17:47   ` Mathieu Desnoyers
2026-06-01 16:22     ` André Almeida
2026-05-29 16:33 ` [PATCH v3 3/5] selftests: futex: Add support for aarch64 in robust_list_critical André Almeida
2026-05-29 16:33 ` [PATCH v3 4/5] arm64: vdso32: Bring vdso32-offsets.h back André Almeida
2026-05-29 16:33 ` [PATCH v3 5/5] arm64: vdso32: Implement __vdso_futex_robust_try_unlock() André Almeida
2026-05-29 19:15   ` Mathieu Desnoyers
2026-06-02  8:30   ` Thomas Weißschuh

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