From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 024CCC44501 for ; Sun, 5 Jul 2026 17:58:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Cc:To:In-Reply-To:References :Message-Id:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=T+8wRAcb2eccitxW8rAQEkvMWfsSNItqwrLGuKFXS/I=; b=q810+priW+teFpKRJBSFYUrGzU tFNum7jQWW1WwcHXgq9XBP53HepbhOlwmUvAvDkX/HAZk1sInc6c0ReQMNXZdoNwBjfZZ6vyQViXW EHtcunH39FFcsDU2jDH236A5EkEze3qvvk5su9VDsPZaJtQanMyw7x+mfDFIdC5e2eWizB/5F+d/t HT/bAcOdFMsCGwh2sSkjtMwC5Xvmo4cMRzZUDxdYlTSuSPqzyYfX/lN2IJEr/tDfvZy0tXJfn349B mvrcy8fnWAMU5xYzAHG4SGtv+1VkiLHpLC8X2/nLC00XIEXUfX6BODywrh6Khet8RJRk7F+CDUPjS HsLVkufw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.99.1 #2 (Red Hat Linux)) id 1wgR6S-00000009XUC-3d7c; Sun, 05 Jul 2026 17:58:04 +0000 Received: from fanzine2.igalia.com ([213.97.179.56]) by bombadil.infradead.org with esmtps (Exim 4.99.1 #2 (Red Hat Linux)) id 1wgR6P-00000009XRi-0A12 for linux-arm-kernel@lists.infradead.org; Sun, 05 Jul 2026 17:58:03 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Cc:To:In-Reply-To:References:Message-Id: Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date:From:Sender: Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender :Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=T+8wRAcb2eccitxW8rAQEkvMWfsSNItqwrLGuKFXS/I=; b=RS124gISO+uxmfr8Gww+vhBdJ9 RtSET59E45upcZwkum8v6qhgmhcySB0wPvPCkpC/DYx7aZx/pc54azDK2JEWK7Hymh6M/YskQURm+ m6jJWlCIVdo3NeY6+Zig/TzyqoXsYKk8xjoBHJ/hXGb4hFKgtOKZTnhDmlznF5urDeSR5n/x/4gfx SOvK61Sp4xfeUnrlf9GS9q6cvQ5U400PFCMBMXHZQEcyjZfUZ0g/pYFccQ55B+g/mk/HflYjjoT+r jOXP88jPfngRi2+2asVeDPeIEt/y/Qtb1vCDccuvxwW1hTkgXFfNtoOk6jZYIjZ9rNbhIIQgmOWFE Fvg6Zs8A==; Received: from 201-69-111-23.dial-up.telesp.net.br ([201.69.111.23] 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 1wgR5s-009PnY-MM; Sun, 05 Jul 2026 19:57:28 +0200 From: =?utf-8?q?Andr=C3=A9_Almeida?= Date: Sun, 05 Jul 2026 14:56:53 -0300 Subject: [PATCH v4 3/5] arm64: vdso: Implement __vdso_futex_robust_try_unlock() MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 8bit Message-Id: <20260705-tonyk-robust_arm-v4-3-e0fd0fa259d3@igalia.com> References: <20260705-tonyk-robust_arm-v4-0-e0fd0fa259d3@igalia.com> In-Reply-To: <20260705-tonyk-robust_arm-v4-0-e0fd0fa259d3@igalia.com> 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 , Uros Bizjak , =?utf-8?q?Thomas_Wei=C3=9Fschuh?= , "Liam R. Howlett" 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 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.9.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20260705_105801_080397_17432B29 X-CRM114-Status: GOOD ( 16.07 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Based on the x86 implementation, implement the vDSO function for unlocking a robust futex correctly. Commit a2274cc0091e ("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 w3, wzr, [x0] // Try to zero *futex __vdso_futex_list64_try_unlock_cs_start: cbnz w3, 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 w3 register: return (regs->user_regs[3]) ? NULL : (void __user *) regs->user_regs.regs[2]; If it's zero, that means that the exclusive store worked and the kernel should clear op_pending (if userspace didn't managed to) stored at x2. Signed-off-by: André Almeida --- Notes: - Only LL/SC for now but I can add LSE later if this looks good 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 zero flag v3: - Managed to get pop to always be stored at x2 --- arch/arm64/Kconfig | 1 + arch/arm64/include/asm/futex_robust.h | 19 +++++++++++++++++++ arch/arm64/kernel/vdso/Makefile | 10 ++++++++++ arch/arm64/kernel/vdso/vfutex.c | 35 +++++++++++++++++++++++++++++++++++ 4 files changed, 65 insertions(+) diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index b3afe0688919..0582172811d9 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -221,6 +221,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..64f22166756a --- /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(struct pt_regs *regs) +{ + /* + * w3 is 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. + */ + 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/Makefile b/arch/arm64/kernel/vdso/Makefile 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 obj-vdso := vgettimeofday.o note.o sigreturn.o vgetrandom.o vgetrandom-chacha.o +ifdef CONFIG_FUTEX_ROBUST_UNLOCK + obj-vdso += vfutex.o +endif + # Build rules targets := $(obj-vdso) vdso.so vdso.so.dbg obj-vdso := $(addprefix $(obj)/, $(obj-vdso)) @@ -45,9 +49,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 +63,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..cce5ca8ce609 --- /dev/null +++ b/arch/arm64/kernel/vdso/vfutex.c @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +#include +#include + +#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; + register __u32 result_reg asm("w3") = 0; + __u32 val; + + 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" + LABEL(start, 64)": \n" + " cbnz %w[result], retry \n" + LABEL(success, 64)": \n" + " str xzr, %[pop_reg] \n" + LABEL(end, 64)": \n" + + : [val] "=&r" (val), [result] "=&r" (result_reg) + : [tid] "r" (tid), [lock] "Q" (*lock), [pop_reg] "Q" (*pop_reg) + : "memory" + ); + + return val; +} -- 2.54.0