[PATCH v9 2/3] arm64: vdso: Prepare for robust futex unlock support
From: André Almeida <andrealmeid@igalia.com>
Date: 2026-09-18 00:27:33
Also in:
linux-arch, lkml
Subsystem:
arm64 port (aarch64 architecture), the rest · Maintainers:
Catalin Marinas, Will Deacon, Linus Torvalds
To solve the robust futex's list_pending_op clearing race condition, prepare for implement __vdso_futex_robust_try_unlock() for arm64 with the following steps: - Create a helper function that sets the struct futex_mm_data with the VDSO's labels addresses. The robust futex fixup mechanism needs to compare the current instruction pointer to the VDSO instructions range. - Split vdso_mremap() in vdso_mremap() and aarch32_mremap(), this allows the VDSO to be setup correctly regarding the instructions addresses for both ABIs when a mremap happens. - Implement arch_futex_robust_unlock_get_pop() for arm64, checking for r2 and r3 registers values for the fixup function. The role of this registers is explained in the commit that implement the assembly portion of the VDSO. Signed-off-by: André Almeida <andrealmeid@igalia.com> --- v9: - Simplify arm64_futex_robust_unlock_get_pop by using regs->regs[] and if instead of ternary operation - Split mremap changes into other patch v6: - Restructured this commit. Move the arch bits away, kept just the generic/helper functions. v4: - Guard symbols from vdso.lds.S with ifdef - drop update_ips() from sigpage remap function 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/include/asm/futex_robust.h | 24 ++++++++++++++++++++++++ arch/arm64/kernel/vdso.c | 17 +++++++++++++++++ 2 files changed, 41 insertions(+)
diff --git a/arch/arm64/include/asm/futex_robust.h b/arch/arm64/include/asm/futex_robust.h
new file mode 100644
index 000000000000..389ce2a9484d
--- /dev/null
+++ b/arch/arm64/include/asm/futex_robust.h@@ -0,0 +1,24 @@ +/* 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) +{ + /* + * In the asm for __vdso_futex_robust_list{64,32}_try_unlock(), w3 + * stores the result of the stlxr instruction. If it's zero, the then + * the ll/sc cmpxchg succeeded and the pending op pointer needs to be + * cleared. + */ + if (regs->regs[3]) + return NULL; + + return (void __user *)regs->regs[2]; +} + +#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.c b/arch/arm64/kernel/vdso.c
index 089a70d96220..95162061cd82 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,6 +58,22 @@ static struct vdso_abi_info vdso_info[] __ro_after_init = { #endif /* CONFIG_COMPAT_VDSO */ }; +#ifdef CONFIG_FUTEX_ROBUST_UNLOCK +static inline void __vdso_futex_update_ips(struct mm_struct *mm, bool is_32bit, void *startp, + void *endp) +{ + unsigned long start = (unsigned long)startp; + unsigned long end = (unsigned long)endp; + struct futex_mm_data *fd = &mm->futex; + + futex_set_vdso_cs_range(fd, 0, start, end, is_32bit); +} + +#else +static inline void __vdso_futex_update_ips(struct mm_struct *mm, bool is_32bit, void *startp, + void *endp) +#endif /* CONFIG_FUTEX_ROBUST_UNLOCK */ + static int vdso_mremap(const struct vm_special_mapping *sm, struct vm_area_struct *new_vma) {
--
2.55.0