arch/x86/include/asm/vdso/gettimeofday.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
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@gmail.com>
---
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)
On February 15, 2026 6:28:34 AM PST, "Marcel W. Wysocki" <maci.stgn@gmail.com> 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@gmail.com> >--- > 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.
© 2016 - 2026 Red Hat, Inc.