Re: [patch 8/8] x86/vdso: Implement __vdso_futex_robust_try_unlock()
From: Thomas Weißschuh
Date: Tue Mar 17 2026 - 03:25:40 EST
On Mon, Mar 16, 2026 at 06:13:34PM +0100, Thomas Gleixner wrote:
(...)
> --- a/arch/x86/Kconfig
> +++ b/arch/x86/Kconfig
> @@ -237,6 +237,7 @@ config X86
> select HAVE_EFFICIENT_UNALIGNED_ACCESS
> select HAVE_EISA if X86_32
> select HAVE_EXIT_THREAD
> + select HAVE_FUTEX_ROBUST_UNLOCK
> select HAVE_GENERIC_TIF_BITS
> select HAVE_GUP_FAST
> select HAVE_FENTRY if X86_64 || DYNAMIC_FTRACE
> --- /dev/null
> +++ b/arch/x86/entry/vdso/common/vfutex.c
> @@ -0,0 +1,72 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +#include <vdso/futex.h>
> +
> +/*
> + * Compat enabled kernels have to take the size bit into account to support the
> + * mixed size use case of gaming emulators. Contrary to the kernel robust unlock
> + * mechanism all of this does not test for the 32-bit modifier in 32-bit VDSOs
> + * and in compat disabled kernels. User space can keep the pieces.
> + */
> +#if defined(CONFIG_X86_64) && !defined(BUILD_VDSO32_64)
#ifndef __x86_64__ ?
> +
> +#ifdef CONFIG_COMPAT
> +
> +# define ASM_CLEAR_PTR \
> + " testl $1, (%[pop]) \n" \
> + " jz .Lop64 \n" \
> + " movl $0, (%[pad]) \n" \
> + " jmp __vdso_futex_robust_try_unlock_cs_end \n" \
> + ".Lop64: \n" \
> + " movq $0, (%[pad]) \n"
> +
> +# define ASM_PAD_CONSTRAINT ,[pad] "S" (((unsigned long)pop) & ~0x1UL)
> +
> +#else /* CONFIG_COMPAT */
> +
> +# define ASM_CLEAR_PTR \
> + " movq $0, (%[pop]) \n"
> +
> +# define ASM_PAD_CONSTRAINT
> +
> +#endif /* !CONFIG_COMPAT */
> +
> +#else /* CONFIG_X86_64 && !BUILD_VDSO32_64 */
> +
> +# define ASM_CLEAR_PTR \
> + " movl $0, (%[pad]) \n"
> +
> +# define ASM_PAD_CONSTRAINT ,[pad] "S" (((unsigned long)pop) & ~0x1UL)
> +
> +#endif /* !CONFIG_X86_64 || BUILD_VDSO32_64 */
> +
> +uint32_t __vdso_futex_robust_try_unlock(uint32_t *lock, uint32_t tid, void *pop)
While uint32_t is originally a userspace type, in the kernel it also pulls in
other internal types which are problematic in the vDSO. __u32 from
uapi/linux/types.h avoid this issue.
(...)
> --- a/arch/x86/entry/vdso/vdso64/vdsox32.lds.S
> +++ b/arch/x86/entry/vdso/vdso64/vdsox32.lds.S
> @@ -22,6 +22,12 @@ VERSION {
> __vdso_getcpu;
> __vdso_time;
> __vdso_clock_getres;
> +#ifdef CONFIG_FUTEX_ROBUST_UNLOCK
> + __vdso_futex_robust_try_unlock;
> + __vdso_futex_robust_try_unlock_cs_start;
> + __vdso_futex_robust_try_unlock_cs_success;
> + __vdso_futex_robust_try_unlock_cs_end;
These three symbols are not meant to be used from outside the vDSO
implementation, so they don't need to be exported by the linkerscripts.
> +#endif
> local: *;
> };
> }
(...)