From nobody Mon Sep 28 12:34:49 2026 Received: from fanzine2.igalia.com (fanzine2.igalia.com [213.97.179.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 38B0E34D4E9; Fri, 21 Aug 2026 21:51:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.97.179.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787349092; cv=none; b=j70k58r78z86+9fHryCiuhpbyMXUZ210CvhD0tK9V/7+9IWuSfvleOA8PiDCkDhyGctJWfNU1s8b/pYoTMENSyxPPCy0WWSkUmFhr5YZgHHvE/8JhKhFT8vSKabHMlvoVX+zQnSCpieFqg8nKgsuVkmhJ8d4HvlhwuSbqXd1f+E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787349092; c=relaxed/simple; bh=+T7csHINHcHFGCq5A5xDC1oiI6yT4G1aDR9CDDjMxwU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=r9hPhNtTlLp8t8MDWJHwVRKzdpaN9lQKSFofe6E8GkNF+zeOrh7IDXkUU1XfbLEMjVVpRn1JbesxlfBLmmhYBnq7YMvH+k9kUAplzYVkH2V8hYJ6xYuSHXJA8CWRjJSFsURs89NR5CieWgr6tEq7IfKzPp75KIhM8no4GANkxAA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=igalia.com; spf=pass smtp.mailfrom=igalia.com; dkim=pass (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b=SyNyY6Tr; arc=none smtp.client-ip=213.97.179.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=igalia.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=igalia.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b="SyNyY6Tr" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Cc:To:Message-Id:Content-Transfer-Encoding:Content-Type: MIME-Version:Subject:Date:From:From:Reply-To; bh=ptmo/42mb6OleOo3WAUeI3RlL5iqmYR87B2SI/srVQA=; b=SyNyY6TrNbjpqoBnarW2weQip9 9pScg9uIs9k8PbRUuNemliDYClkPqev7BEMciKBdyB9FC6T+YS6hBJFYy7b/9yocyAx/aiNqbZNjz tCfaOr/P6UbhY/j43Eg6tr+ccLuJDQhMKYiWchBeceAbMH85fDdDLLerhltFGYsQzSFyD4bX9JgWb Yau0WySzYJD6xrcw3yb80R6CBT7+GvQJ8V9LOC+pAAtY38uLlfEsbLwxKdhAivGhRV91kjh4k1Ke1 bVkFv6Y31NzwfBxQspZAomsMMJpbAB13rvY3l5lI06JdLH19Navt5lMerNo9ExbU4+JlAPMO9W+EW UZm5o6yA==; Received: from [177.139.22.20] (helo=[192.168.15.100]) by fanzine2.igalia.com with esmtpsa (Cipher TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim) id 1wxX8Z-007ErF-Na; Fri, 21 Aug 2026 23:50:55 +0200 From: =?utf-8?q?Andr=C3=A9_Almeida?= Date: Fri, 21 Aug 2026 18:50:42 -0300 Subject: [PATCH v8 1/4] arm64: vdso: Prepare for robust futex unlock support Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260821-tonyk-robust_arm-v8-1-077707b6f1c7@igalia.com> References: <20260821-tonyk-robust_arm-v8-0-077707b6f1c7@igalia.com> In-Reply-To: <20260821-tonyk-robust_arm-v8-0-077707b6f1c7@igalia.com> To: Catalin Marinas , Will Deacon , Thomas Gleixner , Mark Rutland , Mathieu Desnoyers , Sebastian Andrzej Siewior , Peter Zijlstra , Florian Weimer , Darren Hart , Ingo Molnar , Davidlohr Bueso , Arnd Bergmann , Uros Bizjak , =?utf-8?q?Thomas_Wei=C3=9Fschuh?= Cc: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org, kernel-dev@igalia.com, LKML , =?utf-8?q?Andr=C3=A9_Almeida?= X-Mailer: b4 0.15.2 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=C3=A9 Almeida --- 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 | 19 +++++++++++++++++++ arch/arm64/kernel/vdso.c | 27 ++++++++++++++++++++++++++- 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/arch/arm64/include/asm/futex_robust.h b/arch/arm64/include/asm= /futex_robust.h new file mode 100644 index 000000000000..4ff783bb2dc3 --- /dev/null +++ b/arch/arm64/include/asm/futex_robust.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_ARM64_FUTEX_ROBUST_H +#define _ASM_ARM64_FUTEX_ROBUST_H + +#include + +static __always_inline void __user *arm64_futex_robust_unlock_get_pop(stru= ct pt_regs *regs) +{ + /* + * 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 cle= ared. + */ + return (regs->user_regs.regs[3]) ? NULL : (void __user *) regs->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 592dd8668de4..3ef331b5b240 100644 --- a/arch/arm64/kernel/vdso.c +++ b/arch/arm64/kernel/vdso.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -57,6 +58,22 @@ static struct vdso_abi_info vdso_info[] __ro_after_init = =3D { #endif /* CONFIG_COMPAT_VDSO */ }; =20 +#ifdef CONFIG_FUTEX_ROBUST_UNLOCK +static inline void __vdso_futex_update_ips(struct mm_struct *mm, bool is_3= 2bit, void *startp, + void *endp) +{ + unsigned long start =3D (unsigned long) startp; + unsigned long end =3D (unsigned long) endp; + struct futex_mm_data *fd =3D &mm->futex; + + futex_set_vdso_cs_range(fd, is_32bit ? 1 : 0, start, end, is_32bit); +} + +#else +static inline void __vdso_futex_update_ips(struct mm_struct *mm, bool is_3= 2bit, 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) { @@ -162,6 +179,14 @@ static int aarch32_sigpage_mremap(const struct vm_spec= ial_mapping *sm, return 0; } =20 +static int aarch32_mremap(const struct vm_special_mapping *sm, + struct vm_area_struct *new_vma) +{ + current->mm->context.vdso =3D (void *)new_vma->vm_start; + + return 0; +} + static struct vm_special_mapping aarch32_vdso_maps[] =3D { [AA32_MAP_VECTORS] =3D { .name =3D "[vectors]", /* ABI */ @@ -174,7 +199,7 @@ static struct vm_special_mapping aarch32_vdso_maps[] = =3D { }, [AA32_MAP_VDSO] =3D { .name =3D "[vdso]", - .mremap =3D vdso_mremap, + .mremap =3D aarch32_mremap, }, }; =20 --=20 2.55.0 From nobody Mon Sep 28 12:34:49 2026 Received: from fanzine2.igalia.com (fanzine2.igalia.com [213.97.179.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5E9723D88F2; Fri, 21 Aug 2026 21:51:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.97.179.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787349092; cv=none; b=hATh3tO59fvdX0M6JIyMZTJJYS/mEsBCU5diu2ISV2ioXce+OC5Vxn/8+36ESj4488FjVsl6p7FSFA5uhCW81JVIiuE1gEWdwZPwiC0fJoW72U/ceQa+sfiKUsJDnFVUC1ltYHzyWGvgu3sy8E4OI+slVU97Fpn7KbnHfpmCYyg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787349092; c=relaxed/simple; bh=ZBrpW4jK1OkQ1DEf+xQUgS1jw/jYOnDsZXjOtuI+Bug=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=bv4OE697flMviO3Uhs6qrf4AoH3KixfoXNrpw4QPTklEYBXS/EeExpNkH8Vy1xmWDKd0EdQYOIg5oDwL9DGtjNviHQnB/wouLcuB4P4+py3VXZ3ahj3cP76Ccto5RWoouRG1DnRZEcXj2knlI7nau5hWXgw2h9wBALfMmpJkixU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=igalia.com; spf=pass smtp.mailfrom=igalia.com; dkim=pass (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b=f1Z+2Fw7; arc=none smtp.client-ip=213.97.179.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=igalia.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=igalia.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b="f1Z+2Fw7" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Cc:To:Message-Id:Content-Transfer-Encoding:Content-Type: MIME-Version:Subject:Date:From:From:Reply-To; bh=30mW0l/i5s/S/5rb50fobVW5omWORcNu4TBznSp6YSM=; b=f1Z+2Fw7/oai02h0xy8ZNG2zOy 0y3fzvRJLr8taBx579rmv5si89SikI7ITEouzkAlKNlhGgGb46n4miFyltrOAKMxWKnPWCcAKBldg 2tAUFkw/vL2ezp95EGJHHX8f4Vai58kP2kPQihKsQlKEyglXeRm8suK23sBfd9acE+cmLhr39q5ek UVWFe4b2ulufx2MWo9eBvu124SgTxWzta6odW2Ckuk9STe+N/Ao9cp2tvNaB7/nibQxY/fjAHAO3h +pCQlPnxjQrBNPgjec3SnaBP9r2qc4l5dAUwmXUwRUwbzBuZ3uk3/Pb1Kw2ta+MTIn+L+w0F0uo9a TXEFqjtw==; Received: from [177.139.22.20] (helo=[192.168.15.100]) by fanzine2.igalia.com with esmtpsa (Cipher TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim) id 1wxX8e-007ErF-Jq; Fri, 21 Aug 2026 23:51:00 +0200 From: =?utf-8?q?Andr=C3=A9_Almeida?= Date: Fri, 21 Aug 2026 18:50:43 -0300 Subject: [PATCH v8 2/4] arm64: vdso: Implement __vdso_futex_robust_try_unlock() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260821-tonyk-robust_arm-v8-2-077707b6f1c7@igalia.com> References: <20260821-tonyk-robust_arm-v8-0-077707b6f1c7@igalia.com> In-Reply-To: <20260821-tonyk-robust_arm-v8-0-077707b6f1c7@igalia.com> To: Catalin Marinas , Will Deacon , Thomas Gleixner , Mark Rutland , Mathieu Desnoyers , Sebastian Andrzej Siewior , Peter Zijlstra , Florian Weimer , Darren Hart , Ingo Molnar , Davidlohr Bueso , Arnd Bergmann , Uros Bizjak , =?utf-8?q?Thomas_Wei=C3=9Fschuh?= Cc: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org, kernel-dev@igalia.com, LKML , =?utf-8?q?Andr=C3=A9_Almeida?= X-Mailer: b4 0.15.2 The futex's robust list uAPI has a struct robust_list_head::list_op_pending pointer used by userspace as a temporary variable while the mutex unlock is happening. User sets it to the futex address that's about to be released and removed from the robust list, and list_op_pending is cleared after. After a thread dies, the kernel checks it's list_op_pending and wakes the mutex in that address, to prevent starvation, and flip a bit in the mutex word (FUTEX_OWNER_DIED). However, there's a critical section where the user thread dies after the mutex is released but before list_op_pending is cleared. If that happens, another thread can wake up, use the lock, release it, and free its memory. Now, if the robust list cleanup happens after this, the killed thread's list_op_pending becomes a dandling pointer. The kernel wrongly treats this address as a mutex, calls a futex_wake() on it and flips a bit, causing a memory corruption. To avoid using the dangling pointer, implement __vdso_futex_robust_try_unlock() for arm64. Make the VDSO release the mutex and clear the list_op_pending fields, just as is done in userspace right now. But having it in a VDSO means that, in the case of a killed user thread, the kernel can know exactly in which part of the release process the thread was interrupt, check the registers for the operation success and clears the list_op_pending on behalf of the user thread to prevent the use-after-free bug. The need for checking the instructions addresses and the register makes this mechanism arch-dependent. Implement it using LL/SC semantics. If the user instruction pointer is between the labels __futex_list64_try_unlock_cs_start and __futex_list64_try_unlock_cs_end, the critical section was interrupted. The kernel checks for the result register (always w3) of the stlxr instruction used for atomically releasing the mutex. If it's 0, the release happened and the kernel should clear the list_op_pending field (always stored at x2). Signed-off-by: Andr=C3=A9 Almeida --- v7: - Typo in message: success result for stlex is 0, not 1 - pop_reg is read afterwards so define it as an output parameter "+Q" v6: - Complete reword of commit message to make it clear - Better commit split, only the specific aarch64 things here - Use explicity labels instead of macros v4: - Guard makefile for vfutex.o with ifdef - Moved _start label one instruction above - Use results register (w3) to check for store success instead of using ze= ro flag v3: - Managed to get pop to always be stored at x2 --- arch/arm64/Kconfig | 1 + arch/arm64/kernel/vdso.c | 17 +++++++++++++++-- arch/arm64/kernel/vdso/Makefile | 10 ++++++++++ arch/arm64/kernel/vdso/vdso.lds.S | 9 +++++++++ arch/arm64/kernel/vdso/vfutex.c | 35 +++++++++++++++++++++++++++++++++++ 5 files changed, 70 insertions(+), 2 deletions(-) diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index a269f73b7653..55932c0cd109 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -222,6 +222,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/kernel/vdso.c b/arch/arm64/kernel/vdso.c index 3ef331b5b240..dc6b582736d0 100644 --- a/arch/arm64/kernel/vdso.c +++ b/arch/arm64/kernel/vdso.c @@ -69,16 +69,27 @@ static inline void __vdso_futex_update_ips(struct mm_st= ruct *mm, bool is_32bit, futex_set_vdso_cs_range(fd, is_32bit ? 1 : 0, start, end, is_32bit); } =20 +static inline void vdso_futex_update_ips(struct mm_struct *mm) +{ + unsigned long vdso =3D (unsigned long) mm->context.vdso; + + __vdso_futex_update_ips(mm, false, + VDSO_SYMBOL(vdso, futex_list64_try_unlock_cs_start), + VDSO_SYMBOL(vdso, futex_list64_try_unlock_cs_end)); +} + #else -static inline void __vdso_futex_update_ips(struct mm_struct *mm, bool is_3= 2bit, void *startp, - void *endp) +static inline void vdso_futex_update_ips(struct mm_struct *mm) {} #endif /* CONFIG_FUTEX_ROBUST_UNLOCK */ =20 + static int vdso_mremap(const struct vm_special_mapping *sm, struct vm_area_struct *new_vma) { current->mm->context.vdso =3D (void *)new_vma->vm_start; =20 + vdso_futex_update_ips(current->mm); + return 0; } =20 @@ -366,5 +377,7 @@ int arch_setup_additional_pages(struct linux_binprm *bp= rm, int uses_interp) ret =3D __setup_additional_pages(VDSO_ABI_AA64, mm, bprm, uses_interp); mmap_write_unlock(mm); =20 + vdso_futex_update_ips(mm); + return ret; } diff --git a/arch/arm64/kernel/vdso/Makefile b/arch/arm64/kernel/vdso/Makef= ile index 7dec05dd33b7..985346c7a0bb 100644 --- a/arch/arm64/kernel/vdso/Makefile +++ b/arch/arm64/kernel/vdso/Makefile @@ -11,6 +11,10 @@ include $(srctree)/lib/vdso/Makefile.include =20 obj-vdso :=3D vgettimeofday.o note.o sigreturn.o vgetrandom.o vgetrandom-c= hacha.o =20 +ifdef CONFIG_FUTEX_ROBUST_UNLOCK + obj-vdso +=3D vfutex.o +endif + # Build rules targets :=3D $(obj-vdso) vdso.so vdso.so.dbg obj-vdso :=3D $(addprefix $(obj)/, $(obj-vdso)) @@ -45,9 +49,11 @@ CC_FLAGS_ADD_VDSO :=3D -O2 -mcmodel=3Dtiny -fasynchronou= s-unwind-tables =20 CFLAGS_REMOVE_vgettimeofday.o =3D $(CC_FLAGS_REMOVE_VDSO) CFLAGS_REMOVE_vgetrandom.o =3D $(CC_FLAGS_REMOVE_VDSO) +CFLAGS_REMOVE_vfutex.o =3D $(CC_FLAGS_REMOVE_VDSO) =20 CFLAGS_vgettimeofday.o =3D $(CC_FLAGS_ADD_VDSO) CFLAGS_vgetrandom.o =3D $(CC_FLAGS_ADD_VDSO) +CFLAGS_vfutex.o =3D $(CC_FLAGS_ADD_VDSO) =20 ifneq ($(c-gettimeofday-y),) CFLAGS_vgettimeofday.o +=3D -include $(c-gettimeofday-y) @@ -57,6 +63,10 @@ ifneq ($(c-getrandom-y),) CFLAGS_vgetrandom.o +=3D -include $(c-getrandom-y) endif =20 +ifneq ($(c-futex-y),) + CFLAGS_vfutex.o +=3D -include $(c-futex-y) +endif + targets +=3D vdso.lds CPPFLAGS_vdso.lds +=3D -P -C -U$(ARCH) =20 diff --git a/arch/arm64/kernel/vdso/vdso.lds.S b/arch/arm64/kernel/vdso/vds= o.lds.S index 52314be29191..225f59bb81d1 100644 --- a/arch/arm64/kernel/vdso/vdso.lds.S +++ b/arch/arm64/kernel/vdso/vdso.lds.S @@ -104,6 +104,9 @@ VERSION __kernel_clock_gettime; __kernel_clock_getres; __kernel_getrandom; +#ifdef CONFIG_FUTEX_ROBUST_UNLOCK + __vdso_futex_robust_list64_try_unlock; +#endif local: *; }; } @@ -112,3 +115,9 @@ VERSION * Make the sigreturn code visible to the kernel. */ VDSO_sigtramp =3D __kernel_rt_sigreturn; + +#ifdef CONFIG_FUTEX_ROBUST_UNLOCK +VDSO_futex_list64_try_unlock_cs_start =3D __futex_list64_try_unlock_cs_sta= rt; +VDSO_futex_list64_try_unlock_cs_success =3D __futex_list64_try_unlock_cs_s= uccess; +VDSO_futex_list64_try_unlock_cs_end =3D __futex_list64_try_unlock_cs_end; +#endif diff --git a/arch/arm64/kernel/vdso/vfutex.c b/arch/arm64/kernel/vdso/vfute= x.c new file mode 100644 index 000000000000..ae7b653c1554 --- /dev/null +++ b/arch/arm64/kernel/vdso/vfutex.c @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +#include +#include + +__u32 __vdso_futex_robust_list64_try_unlock(__u32 *lock, __u32 tid, __u64 = *pop) +{ + register __u64 *pop_reg asm("x2") =3D pop; + register __u32 result_reg asm("w3") =3D 0; + __u32 val; + + asm volatile ( + ".globl " + "__futex_list64_try_unlock_cs_start, " + "__futex_list64_try_unlock_cs_success, " + "__futex_list64_try_unlock_cs_end \n" + + " prfm pstl1strm, %[lock] \n" + "retry: \n" + " ldxr %w[val], %[lock] \n" + " cmp %w[tid], %w[val] \n" + " bne __futex_list64_try_unlock_cs_end \n" + " stlxr %w[result], wzr, %[lock] \n" + "__futex_list64_try_unlock_cs_start: \n" + " cbnz %w[result], retry \n" + "__futex_list64_try_unlock_cs_success: \n" + " str xzr, %[pop_reg] \n" + "__futex_list64_try_unlock_cs_end: \n" + + : [val] "=3D&r" (val), [result] "=3D&r" (result_reg), [pop_reg] "+Q" (*p= op_reg) + : [tid] "r" (tid), [lock] "Q" (*lock) + : "cc", "memory" + ); + + return val; +} --=20 2.55.0 From nobody Mon Sep 28 12:34:49 2026 Received: from fanzine2.igalia.com (fanzine2.igalia.com [213.97.179.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C22503DAABD; Fri, 21 Aug 2026 21:51:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.97.179.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787349093; cv=none; b=TcQtbZ/2ta1skfa/RXJQBfB+O1p4fXloySHCoCuaPTpl2XVM/7hC7YQ7he03tiZV+19VrFWP0ei3KrGHIyv1VgDHH3urKpMIdWkphX9mfNW4sHcdYMmvQOoRseGhvMtPjco4CtrV9d+mxPLZOPRZ4rbf7sAf1/LzlsrjrszGLNw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787349093; c=relaxed/simple; bh=poYqrUsi500s0fQyhLYCsmsHf0i//77QFNaIOGes8ek=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=FVpULjBBPXKy9nibtNZDgxbYR87rbSBER7yB4shm8syUHpSMi9TvlobyWI9tdpgjc0xJVsoRxVwaNoKWpSsYgoXtKnspZZGWuFr//fHfN7g0txyRc9UYlKKDCwTpDk4jg10FJBIs0zImmqy9R6vxNnrL9ojlvWLAHKbfzjnYS1s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=igalia.com; spf=pass smtp.mailfrom=igalia.com; dkim=pass (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b=TKnRsP7X; arc=none smtp.client-ip=213.97.179.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=igalia.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=igalia.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b="TKnRsP7X" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Cc:To:Message-Id:Content-Transfer-Encoding:Content-Type: MIME-Version:Subject:Date:From:From:Reply-To; bh=K8kjW1mgVYNAmXTDHsHgs1H1Tp7aKYu9ZJKgbwnVZzM=; b=TKnRsP7X7H3y02V8UmAz/WwPpX 17JcJivtbx3NC0va4VyxWitpgKW+kMDqCzPtRPqFYWvYeie9iGjDZlcpGvnc9zqViX1oJGBwigeHs jd4L9fl6LfFgCsrDRat6oMjVtoSEbkn8Nq2cQsfX6YVHj7nKkDOfJvrmams4QxJTcpiGKEBkjkzXI kfZRWdWIr526DFvhIc59RkmYQS99MmY3ur5po5gty6L2EOHv/DHK96ExuDseYJHjw9ZVDmVwO8lV5 5sQA8o8xorERN+kLqu621OLVlHzpUx5JFzLU966W6LnwX3FnPCF3fPBIz3otBVnMjRs86MqV744r0 m7Zh95eQ==; Received: from [177.139.22.20] (helo=[192.168.15.100]) by fanzine2.igalia.com with esmtpsa (Cipher TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim) id 1wxX8j-007ErF-G8; Fri, 21 Aug 2026 23:51:05 +0200 From: =?utf-8?q?Andr=C3=A9_Almeida?= Date: Fri, 21 Aug 2026 18:50:44 -0300 Subject: [PATCH v8 3/4] arm64: vdso32: Bring vdso32-offsets.h back Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260821-tonyk-robust_arm-v8-3-077707b6f1c7@igalia.com> References: <20260821-tonyk-robust_arm-v8-0-077707b6f1c7@igalia.com> In-Reply-To: <20260821-tonyk-robust_arm-v8-0-077707b6f1c7@igalia.com> To: Catalin Marinas , Will Deacon , Thomas Gleixner , Mark Rutland , Mathieu Desnoyers , Sebastian Andrzej Siewior , Peter Zijlstra , Florian Weimer , Darren Hart , Ingo Molnar , Davidlohr Bueso , Arnd Bergmann , Uros Bizjak , =?utf-8?q?Thomas_Wei=C3=9Fschuh?= Cc: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org, kernel-dev@igalia.com, LKML , =?utf-8?q?Andr=C3=A9_Almeida?= X-Mailer: b4 0.15.2 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=C3=A9 Almeida --- 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 6b005c8fef70..265716644193 100644 --- a/arch/arm64/Makefile +++ b/arch/arm64/Makefile @@ -211,7 +211,7 @@ vdso_prepare: prepare0 include/generated/vdso-offsets.h arch/arm64/kernel/vdso/vdso.so ifdef CONFIG_COMPAT_VDSO $(Q)$(MAKE) $(build)=3Darch/arm64/kernel/vdso32 \ - arch/arm64/kernel/vdso32/vdso.so + include/generated/vdso32-offsets.h arch/arm64/kernel/vdso32/vdso.so endif endif =20 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__ =20 #include +#ifdef CONFIG_COMPAT_VDSO +#include +#endif =20 #define VDSO_SYMBOL(base, name) \ ({ \ diff --git a/arch/arm64/kernel/vdso32/Makefile b/arch/arm64/kernel/vdso32/M= akefile index bea3675fa668..4bd60f059f4a 100644 --- a/arch/arm64/kernel/vdso32/Makefile +++ b/arch/arm64/kernel/vdso32/Makefile @@ -135,6 +135,14 @@ $(c-obj-vdso-gettimeofday): %.o: %.c FORCE $(asm-obj-vdso): %.o: %.S FORCE $(call if_changed_dep,vdsoas) =20 +# Generate VDSO offsets using helper script +gen-vdsosym :=3D $(src)/../vdso/gen_vdso_offsets.sh +quiet_cmd_vdsosym =3D VDSOSYM $@ + cmd_vdsosym =3D $(NM) $< | $(gen-vdsosym) | LC_ALL=3DC sort > $@ + +include/generated/vdso32-offsets.h: $(obj)/vdso32.so.dbg FORCE + $(call if_changed,vdsosym) + # Actual build commands quiet_cmd_vdsold_and_vdso_check =3D LD32 $@ cmd_vdsold_and_vdso_check =3D $(cmd_vdsold); $(cmd_vdso_check) --=20 2.55.0 From nobody Mon Sep 28 12:34:49 2026 Received: from fanzine2.igalia.com (fanzine2.igalia.com [213.97.179.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5EA0C3DAABA; Fri, 21 Aug 2026 21:51:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.97.179.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787349092; cv=none; b=oI9zu86yMla5+mxu1o23BeuMVbZbGmDHeDf4eG3/c1AoB4xjOIPL5WzLN5qwQC+v0kXcpE3uPPH2Wv1NjyTW55ii/WP/fdnOAggD/Tx1iSK4YyE59EhMb4F7WIDdkfOqAvDIVv21dfh0+xQIZ6RmvdylfpFDwzQC06/Q50a8Mwg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787349092; c=relaxed/simple; bh=Iwqq5ncuU7P6F3YarLQ2g5UgC1L1Mr7eYKUCkXFBrQg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=mk/lrs9AFcc3LpLErg2m6xpGAT1g/2hALMYX8PqpS+d/iidhCHeHRVH7KYKow5uukmQg9O5US9uc5GoZXqiQIlk+W8JQW9SPh9Hrxl+jwA3Hj8xjAOgwFbNbR9ix8TEYbdBTXjWofyvTpMdfByG0LS09fjnphZOhRGEtrUxf4rU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=igalia.com; spf=pass smtp.mailfrom=igalia.com; dkim=pass (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b=liZAiCoC; arc=none smtp.client-ip=213.97.179.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=igalia.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=igalia.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b="liZAiCoC" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Cc:To:Message-Id:Content-Transfer-Encoding:Content-Type: MIME-Version:Subject:Date:From:From:Reply-To; bh=gRq+qzopR5CZIo+DD/Zd0DVuepZBIeDP3cju5ARGMHc=; b=liZAiCoCP4ol9dukgTEARohKuc brmBSIKeQBGXhO7xh6NtcNaVQTR9Z256F6uu6m02+LYAHT36HrMKJ2zy9FhHH4EvzFd92X/QXrVts ODngfqA5Jp5npblw++iUdeKB1dmlOetDy+FD3D58IsWrOTYuPnPPZLfZrxOsd8DTpzTWTQE3RbznC awfbMDnFApzKn0JXwmCN77kNK5iPM2tYYaMSDcOMnAXIkSmlIzuP1l9MRPvW0005blI30fXtasGU8 kL9hoJmxc94oeyIRi6ONhn2U223CdtiEFT/sjUlFLUKiaDp6VxRtbFN/KusSQhxRMnCoYJOYIFy+t fFaQi9Tg==; Received: from [177.139.22.20] (helo=[192.168.15.100]) by fanzine2.igalia.com with esmtpsa (Cipher TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim) id 1wxX8o-007ErF-CK; Fri, 21 Aug 2026 23:51:10 +0200 From: =?utf-8?q?Andr=C3=A9_Almeida?= Date: Fri, 21 Aug 2026 18:50:45 -0300 Subject: [PATCH v8 4/4] arm64: vdso32: Implement __vdso_futex_robust_try_unlock() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260821-tonyk-robust_arm-v8-4-077707b6f1c7@igalia.com> References: <20260821-tonyk-robust_arm-v8-0-077707b6f1c7@igalia.com> In-Reply-To: <20260821-tonyk-robust_arm-v8-0-077707b6f1c7@igalia.com> To: Catalin Marinas , Will Deacon , Thomas Gleixner , Mark Rutland , Mathieu Desnoyers , Sebastian Andrzej Siewior , Peter Zijlstra , Florian Weimer , Darren Hart , Ingo Molnar , Davidlohr Bueso , Arnd Bergmann , Uros Bizjak , =?utf-8?q?Thomas_Wei=C3=9Fschuh?= Cc: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org, kernel-dev@igalia.com, LKML , =?utf-8?q?Andr=C3=A9_Almeida?= X-Mailer: b4 0.15.2 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. Signed-off-by: Andr=C3=A9 Almeida --- v7: - The store needs to be a release store, so s/strex/stlex/ - result reg clobber modified to "=3D&r" to make sure the compiler don't u= se 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_stru= ct *mm) VDSO_SYMBOL(vdso, futex_list64_try_unlock_cs_end)); } =20 +static inline void aarch32_vdso_futex_update_ips(struct mm_struct *mm) +{ + unsigned long vdso =3D (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 */ =20 - 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_mappi= ng *sm, { current->mm->context.vdso =3D (void *)new_vma->vm_start; =20 + aarch32_vdso_futex_update_ips(current->mm); + return 0; } =20 @@ -327,6 +337,7 @@ static int aarch32_sigreturn_setup(struct mm_struct *mm) return PTR_ERR_OR_ZERO(ret); } =20 + int aarch32_setup_additional_pages(struct linux_binprm *bprm, int uses_int= erp) { struct mm_struct *mm =3D current->mm; @@ -347,6 +358,8 @@ int aarch32_setup_additional_pages(struct linux_binprm = *bprm, int uses_interp) } =20 ret =3D 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/M= akefile index 4bd60f059f4a..f3190125c68b 100644 --- a/arch/arm64/kernel/vdso32/Makefile +++ b/arch/arm64/kernel/vdso32/Makefile @@ -97,6 +97,10 @@ munge :=3D ../../../arm/vdso/vdsomunge hostprogs :=3D $(munge) =20 c-obj-vdso :=3D note.o +ifdef CONFIG_FUTEX_ROBUST_UNLOCK + c-obj-vdso +=3D vfutex.o +endif + c-obj-vdso-gettimeofday :=3D vgettimeofday.o =20 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 =3D __futex_list32_try_unlock_cs_s= uccess; +VDSO_futex_list32_try_unlock_cs_start =3D __futex_list32_try_unlock_cs_sta= rt; +VDSO_futex_list32_try_unlock_cs_end =3D __futex_list32_try_unlock_cs_end; +#endif diff --git a/arch/arm64/kernel/vdso32/vfutex.c b/arch/arm64/kernel/vdso32/v= futex.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 +#include + +__u32 __vdso_futex_robust_list32_try_unlock(__u32 *lock, __u32 tid, __u32 = *pop) +{ + register __u32 *pop_reg asm("r2") =3D pop, result_reg asm("r3") =3D 0; + __u32 val, zero =3D 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] "=3D&r" (val), [result] "=3D&r" (result_reg), [pop_reg] "+Q" (*p= op_reg) + : [tid] "r" (tid), [lock] "Q" (*lock), [zero] "r" (zero) + : "cc", "memory" + ); + + return val; +} --=20 2.55.0