Re: [PATCH] x86/vdso: use calll mnemonic for 32-bit vdso calls
From: H. Peter Anvin
Date: Tue Feb 17 2026 - 04:09:21 EST
On February 15, 2026 6:28:34 AM PST, "Marcel W. Wysocki" <maci.stgn@xxxxxxxxx> wrote:
>The VDSO32 fallback functions use unsuffixed "call" in inline asm
>that is compiled in 32-bit mode (-m32). In AT&T syntax, the
>unsuffixed "call" is ambiguous -- the assembler must infer the
>operand size from context.
>
>While both GNU as and the standard LLVM integrated assembler handle
>this correctly in practice, the unsuffixed form is inconsistent with
>other 32-bit assembly in the kernel tree (arch/x86/boot/header.S,
>arch/x86/boot/copy.S, arch/x86/realmode/rm/wakeup_asm.S) which
>already uses the explicit "calll" mnemonic.
>
>More importantly, alternative LLVM-based toolchains (e.g. zig cc)
>contain a separate assembler implementation that rejects unsuffixed
>"call" in 32-bit inline asm context, preventing VDSO32 compilation
>entirely.
>
>Use "calll" -- the canonical AT&T mnemonic for a 32-bit near call
>-- to match existing kernel convention and ensure compatibility
>with all LLVM-based assemblers.
>
>No object code change: "call" and "calll" produce identical machine
>code (opcode E8h with 32-bit relative displacement) on all tested
>assemblers (GNU as, LLVM 21, LLVM 20).
>
>Signed-off-by: Marcel W. Wysocki <maci.stgn@xxxxxxxxx>
>---
> arch/x86/include/asm/vdso/gettimeofday.h | 10 +++++-----
> 1 file changed, 5 insertions(+), 5 deletions(-)
>
>diff --git a/arch/x86/include/asm/vdso/gettimeofday.h b/arch/x86/include/asm/vdso/gettimeofday.h
>--- a/arch/x86/include/asm/vdso/gettimeofday.h
>+++ b/arch/x86/include/asm/vdso/gettimeofday.h
>@@ -101,7 +101,7 @@
> asm (
> "mov %%ebx, %%edx \n"
> "mov %[clock], %%ebx \n"
>- "call __kernel_vsyscall \n"
>+ "calll __kernel_vsyscall \n"
> "mov %%edx, %%ebx \n"
> : "=a" (ret), "=m" (*_ts)
> : "0" (__NR_clock_gettime64), [clock] "g" (_clkid), "c" (_ts)
>@@ -118,7 +118,7 @@
> asm (
> "mov %%ebx, %%edx \n"
> "mov %[clock], %%ebx \n"
>- "call __kernel_vsyscall \n"
>+ "calll __kernel_vsyscall \n"
> "mov %%edx, %%ebx \n"
> : "=a" (ret), "=m" (*_ts)
> : "0" (__NR_clock_gettime), [clock] "g" (_clkid), "c" (_ts)
>@@ -136,7 +136,7 @@
> asm(
> "mov %%ebx, %%edx \n"
> "mov %2, %%ebx \n"
>- "call __kernel_vsyscall \n"
>+ "calll __kernel_vsyscall \n"
> "mov %%edx, %%ebx \n"
> : "=a" (ret)
> : "0" (__NR_gettimeofday), "g" (_tv), "c" (_tz)
>@@ -153,7 +153,7 @@
> asm (
> "mov %%ebx, %%edx \n"
> "mov %[clock], %%ebx \n"
>- "call __kernel_vsyscall \n"
>+ "calll __kernel_vsyscall \n"
> "mov %%edx, %%ebx \n"
> : "=a" (ret), "=m" (*_ts)
> : "0" (__NR_clock_getres_time64), [clock] "g" (_clkid), "c" (_ts)
>@@ -170,7 +170,7 @@
> asm (
> "mov %%ebx, %%edx \n"
> "mov %[clock], %%ebx \n"
>- "call __kernel_vsyscall \n"
>+ "calll __kernel_vsyscall \n"
> "mov %%edx, %%ebx \n"
> : "=a" (ret), "=m" (*_ts)
> : "0" (__NR_clock_getres), [clock] "g" (_clkid), "c" (_ts)
The "calll" instances you are pointing at are in *16-bit* code, which therefore need the extra l suffix.