Re: [PATCH v8 4/4] arm64: vdso32: Implement __vdso_futex_robust_try_unlock()
From: André Almeida
Date: Wed Sep 16 2026 - 21:12:01 EST
Em 16/09/2026 11:28, Mark Rutland escreveu:
On Fri, Aug 21, 2026 at 06:50:45PM -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 and the compare result value
at r3.
Before we add this to the compat vdso, we'll need to implement this on
arch/arm/.
Otherwise, my comments on the patch for the native vdso functions apply
here too.
Right, and the compat entry point at arch/arm64/ would point to the __vdso_futex_robust_list32_try_unlock implementation at arch/arm/?
Mark.
Signed-off-by: André Almeida <andrealmeid@xxxxxxxxxx>
---
v7:
- The store needs to be a release store, so s/strex/stlex/
- result reg clobber modified to "=&r" to make sure the compiler don't use
the r3 reg for something else
- pop_reg will be read after the execution so it should be an output
parameter with "+Q"
---
arch/arm64/kernel/vdso.c | 15 ++++++++++++++-
arch/arm64/kernel/vdso32/Makefile | 4 ++++
arch/arm64/kernel/vdso32/vdso.lds.S | 9 +++++++++
arch/arm64/kernel/vdso32/vfutex.c | 34 ++++++++++++++++++++++++++++++++++
4 files changed, 61 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
index dc6b582736d0..5cae9c17ec72 100644
--- a/arch/arm64/kernel/vdso.c
+++ b/arch/arm64/kernel/vdso.c
@@ -78,11 +78,19 @@ static inline void vdso_futex_update_ips(struct mm_struct *mm)
VDSO_SYMBOL(vdso, futex_list64_try_unlock_cs_end));
}
+static inline void aarch32_vdso_futex_update_ips(struct mm_struct *mm)
+{
+ unsigned long vdso = (unsigned long) mm->context.vdso;
+
+ __vdso_futex_update_ips(mm, true,
+ VDSO_SYMBOL(vdso, futex_list32_try_unlock_cs_start),
+ VDSO_SYMBOL(vdso, futex_list32_try_unlock_cs_end));
+}
#else
static inline void vdso_futex_update_ips(struct mm_struct *mm) {}
+static inline void aarch32_vdso_futex_update_ips(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)
{
@@ -195,6 +203,8 @@ static int aarch32_mremap(const struct vm_special_mapping *sm,
{
current->mm->context.vdso = (void *)new_vma->vm_start;
+ aarch32_vdso_futex_update_ips(current->mm);
+
return 0;
}
@@ -327,6 +337,7 @@ static int aarch32_sigreturn_setup(struct mm_struct *mm)
return PTR_ERR_OR_ZERO(ret);
}
+
int aarch32_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
{
struct mm_struct *mm = current->mm;
@@ -347,6 +358,8 @@ int aarch32_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
}
ret = aarch32_sigreturn_setup(mm);
+
+ aarch32_vdso_futex_update_ips(mm);
out:
mmap_write_unlock(mm);
return ret;
diff --git a/arch/arm64/kernel/vdso32/Makefile b/arch/arm64/kernel/vdso32/Makefile
index 4bd60f059f4a..f3190125c68b 100644
--- a/arch/arm64/kernel/vdso32/Makefile
+++ b/arch/arm64/kernel/vdso32/Makefile
@@ -97,6 +97,10 @@ munge := ../../../arm/vdso/vdsomunge
hostprogs := $(munge)
c-obj-vdso := note.o
+ifdef CONFIG_FUTEX_ROBUST_UNLOCK
+ c-obj-vdso += vfutex.o
+endif
+
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 12bfc39e8aab..52ced27d6045 100644
--- a/arch/arm64/kernel/vdso32/vdso.lds.S
+++ b/arch/arm64/kernel/vdso32/vdso.lds.S
@@ -89,6 +89,15 @@ VERSION
#endif /* CONFIG_COMPAT_32BIT_TIME */
__vdso_clock_gettime64;
__vdso_clock_getres_time64;
+#ifdef CONFIG_FUTEX_ROBUST_UNLOCK
+ __vdso_futex_robust_list32_try_unlock;
+#endif
local: *;
};
}
+
+#ifdef CONFIG_FUTEX_ROBUST_UNLOCK
+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;
+#endif
diff --git a/arch/arm64/kernel/vdso32/vfutex.c b/arch/arm64/kernel/vdso32/vfutex.c
new file mode 100644
index 000000000000..0d9080b17965
--- /dev/null
+++ b/arch/arm64/kernel/vdso32/vfutex.c
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include <linux/stringify.h>
+#include <vdso/futex.h>
+
+__u32 __vdso_futex_robust_list32_try_unlock(__u32 *lock, __u32 tid, __u32 *pop)
+{
+ register __u32 *pop_reg asm("r2") = pop, result_reg asm("r3") = 0;
+ __u32 val, zero = 0;
+
+ asm volatile (
+ ".globl "
+ "__futex_list32_try_unlock_cs_start, "
+ "__futex_list32_try_unlock_cs_success, "
+ "__futex_list32_try_unlock_cs_end \n"
+
+ "retry: \n"
+ " ldrex %[val], %[lock] \n"
+ " cmp %[tid], %[val] \n"
+ " bne __futex_list32_try_unlock_cs_end \n"
+ " stlex %[result], %[zero], %[lock] \n"
+ "__futex_list32_try_unlock_cs_start: \n"
+ " cmp %[result], #0 \n"
+ " bne retry \n"
+ "__futex_list32_try_unlock_cs_success: \n"
+ " str %[zero], %[pop_reg] \n"
+ "__futex_list32_try_unlock_cs_end: \n"
+
+ : [val] "=&r" (val), [result] "=&r" (result_reg), [pop_reg] "+Q" (*pop_reg)
+ : [tid] "r" (tid), [lock] "Q" (*lock), [zero] "r" (zero)
+ : "cc", "memory"
+ );
+
+ return val;
+}
--
2.55.0