Re: [PATCH v3 1/2] x86/uaccess: Extend CMPXCHG user helpers to 128-bit operands

From: Uros Bizjak

Date: Wed Aug 26 2026 - 09:24:54 EST


On Wed, Aug 26, 2026 at 2:30 PM Dave Hansen <dave.hansen@xxxxxxxxx> wrote:
>
> On 8/26/26 00:00, Sairaj Kodilkar wrote:
> > Extend the existing user CMPXCHG helpers to support 16-byte operands on
> > x86-64, using LOCK_PREFIX "cmpxchg16b". This mirrors the existing
> > __try_cmpxchg64_user_asm() / cmpxchg8b path provided for 32-bit kernels,
> > where KVM needs an atomic compare-exchange wider than the generic
> > cmpxchg helper can provide.
>
> Please take a good look at the Sashiko review:
>
> https://sashiko.dev/#/patchset/20260826070004.8100-2-sarunkod%40amd.com
>
> It looks like the "A" constraint isn't one that you can cleanly mirror
> from cmpxchg8b => cmpxchg16b.

Actually, "+A" will work for 64bit targets, as long as the variable is
128-bit. The comment in asm.h applies to 64-bit values, where on
32-bit targets they fit in eax *and* edx, while on 64-bit targets, the
64-bit values fit into rax *or* rdx.

This is documented in GCC documentation:

‘A’
The ‘a’ and ‘d’ registers. This class is used for
instructions that return double word results in the ‘ax:dx’
register pair. Single word values will be allocated either in
‘ax’ or ‘dx’.

And can be confirmed with e.g.:

__int128 val;

void foo (void)
{
__int128 _v = val;
asm volatile ("" : "+A" (_v));
val = _v;
}

which will fail compilation with -ffixed-rax or -ffixed-rdx.

That said, the approach with union of two 64-bit halves can lead to
slightly better code, because the compiler splits the value earlier in
the compilation pipeline.

> Uros, any chance you can give these a good once-over? This seems to be
> just the kind of thing you've been fixing up lately. It would be nice to
> get them right the first time.

Based on the above explanation, these *can* be copied from 32-bit asm
patterns. Even "q" constraint will include all integer registers on
64-bit targets.

Uros.