Re: [patch V3 00/14] futex: Address the robust futex unlock race for real

Mark Rutland
2026-03-31T14:12:26Z

On Mon, Mar 30, 2026 at 09:36:44PM +0200, Thomas Gleixner wrote:
> On Mon, Mar 30 2026 at 14:45, Mark Rutland wrote:
> > On Mon, Mar 30, 2026 at 02:01:58PM +0200, Thomas Gleixner wrote:
> >> User space can't solve this problem without help from the kernel. This
> >> series provides the kernel side infrastructure to help it along:
> [ 6 more citation lines. Click/Enter to show. ]
> >>
> >> 1) Combined unlock, pointer clearing, wake-up for the contended case
> >>
> >> 2) VDSO based unlock and pointer clearing helpers with a fix-up function
> >> in the kernel when user space was interrupted within the critical
> >> section.
> >
> > I see the vdso bits in this series are specific to x86. Do other
> > architectures need something here?
>
> Yes.

Cool. Thanks for confirming!

> > I might be missing some context; I'm not sure whether that's not
> > necessary or just not implemented by this series, and so I'm not sure
> > whether arm64 folk and other need to go dig into this.
>
> The VDSO functions __vdso_futex_robust_list64_try_unlock() and
> __vdso_futex_robust_list32_try_unlock() are architecture specific.
>
> The scheme in x86 ASM is:
>
> mov %esi,%eax // Load TID into EAX
> xor %ecx,%ecx // Set ECX to 0
> lock cmpxchg %ecx,(%rdi) // Try the TID -> 0 transition
> .Lstart:
> jnz .Lend
> movq %rcx,(%rdx) // Clear list_op_pending
> .Lend:
> ret
>
> .Lstart is the start of the critical section, .Lend the end. These two
> addresses need to be retrieved from the VDSO when the VDSO is mapped to
> user space and stored in mm::futex:unlock::cs_ranges[]. See patch 11/14.
>
> If the cmpxchg was successful, then the pending pointer has to be
> cleared when user space was interrupted before reaching .Lend.
>
> So .Lstart has to be immediately after the instruction which did the try
> compare exchange and the architecture needs to have their ASM variant
> and the helper function which tells the generic code whether the pointer
> has to be cleared or not. On x86 that is:
>
> return regs->flags & X86_EFLAGS_ZF ? (void __user *)regs->dx : NULL;
>
> as the result of CMPXCHG is in the Zero Flag and the pointer is in
> [ER]DX. The former is defined by the ISA, the latter is enforced by the
> ASM constraints and has to be kept in sync between the VDSO ASM and the
> evaluation helper.
>
> Do you see a problem with that on AARGH64?

I think something like that should be possible.

The one pain point I see immediately is how to work with LL/SC and LSE
atomics. For LL/SC atomics, we need to retry even if the value hasn't
changed; I think that just makes the critical section and helper a bit
more complicated. LL/SC and LSE atomics indicate success differently,
but again that's probably just some additional logic in the helper
function, and special care when laying out the asm for patching.

Mark.