Re: [PATCH] x86/mm: fix objtool failure with KMSAN enabled
From: Dmitry Voytik
Date: Thu Jul 02 2026 - 07:13:28 EST
Hi Borislav,
On Thu, Jul 2, 2026 at 4:54 AM Borislav Petkov <bp@xxxxxxxxx> wrote:
>
> On Wed, Jul 01, 2026 at 02:51:51PM +0200, Dmitry Voytik wrote:
> > This patch fixes broken builds with defconfig + CONFIG_KMSAN +
> > CONFIG_DEBUG_INFO_*.
> >
> > To reproduce the issue before the fix:
> > make mrproper
> > make LLVM=1 defconfig
> > ./scripts/config -e CONFIG_KMSAN \
> > -e CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT
> > make LLVM=1 olddefconfig
> > make LLVM=1 -j(nproc) vmlinux
> > ...
> > LD vmlinux.o
> > vmlinux.o: warning: objtool: folio_zero_user+0x801: undefined stack state
> > vmlinux.o: error: objtool: folio_zero_user+0x801: unknown CFA base reg -1
> > make[2]: *** [scripts/Makefile.vmlinux_o:76: vmlinux.o] Error 255
> >
> > objtool in verbose mode shows how the frame pointer is omitted:
> > make LLVM=1 OBJTOOL_VERBOSE=1 -j(nproc) vmlinux
> > ...
> > b15a2c: folio_zero_user+0x7fc xor %eax,%eax
> > b15a2e: folio_zero_user+0x7fe mov %rcx,%rsp
> > b15a31: folio_zero_user+0x801 mov %r14,%rdi
> > b15a34: folio_zero_user+0x804 mov %rbx,%rcx
> > b15a37: folio_zero_user+0x807 call 0xb15a3c <__clear_pages_unrol
> >
> > After the fix, the frame pointer is back:
> > b15a37: 31 c0 xor %eax,%eax
> > b15a39: 48 89 ec mov %rbp,%rsp
> > b15a3c: 4c 89 f7 mov %r14,%rdi
> > b15a3f: 48 89 d9 mov %rbx,%rcx
> > b15a42: e8 00 00 00 00 call b15a47 <folio_zero_user+0x817>
> >
> > It seems the issue was introduced by
> > commit 54a6b89a3db2 ("x86/mm: simplify clear_page_*")
> >
> > The actual fix is to revert the change how ASM_CALL_CONSTRAINT is
> > positioned.
>
> Why?
>
> Where does it say that the current stack ptr dependency needs to be the first
> asm input operand?
Very good question. My uneducated guess - bugs in clang.
Out of curiosity, I compared (see below) what clang and gcc do when
ASM_CALL_CONSTRAINT moves around, and it indeed affects generated
code, which is weird.
I might just be holding it wrong, like optimization must be on, etc.
> If that were the case, we have a bunch more of those bugs around the tree.
At least, it makes objtool happy for the defconfig + KMSAN.
> Anyway, + linux-toolchains.
Thanks for looking into this.
Comparing clang and gcc:
// clang asm_clang.c -o out
// gcc asm_clang.c -o out
// objdump -d --disassemble=main out
#include <stdio.h>
int func() {
return 42;
}
#define __stringify_1(x...) #x
#define __stringify(x...) __stringify_1(x)
# define __ASM_FORM_RAW(x, ...) __stringify(x,##__VA_ARGS__)
# define __ASM_SEL_RAW(a,b) __ASM_FORM_RAW(b)
#define __ASM_REG(reg) __ASM_SEL_RAW(e##reg, r##reg)
#define _ASM_SP __ASM_REG(sp)
register unsigned long current_stack_pointer asm(_ASM_SP);
#define ASM_CALL_CONSTRAINT "+r" (current_stack_pointer)
int main() {
int output_val = 0;
__asm__ __volatile__ ( "call func\n\t" : "=a" (output_val) : :);
// clang v22.1.6
// 1142: e8 d9 ff ff ff call 1120 <func>
// 1147: 89 45 f8 mov %eax,-0x8(%rbp)
// gcc:
// 112f: e8 e5 ff ff ff call 1119 <func>
// 1134: 89 45 fc mov %eax,-0x4(%rbp)
__asm__ __volatile__ (
"call func\n\t" : ASM_CALL_CONSTRAINT, "=a" (output_val) : :);
// clang v22.1.6
// 114a: 48 89 e0 mov %rsp,%rax
// 114d: 48 89 c4 mov %rax,%rsp
// 1150: e8 cb ff ff ff call 1120 <func>
// 1155: 48 89 e1 mov %rsp,%rcx
// 1158: 48 89 cc mov %rcx,%rsp
// 115b: 89 45 f8 mov %eax,-0x8(%rbp)
// gcc:
// 1137: e8 dd ff ff ff call 1119 <func>
// 113c: 89 45 fc mov %eax,-0x4(%rbp)
__asm__ __volatile__ (
"call func\n\t" : "=a" (output_val), ASM_CALL_CONSTRAINT : :);
// clang v22.1.6
// 115e: 48 89 e0 mov %rsp,%rax
// 1161: 48 89 c4 mov %rax,%rsp
// 1164: e8 b7 ff ff ff call 1120 <func>
// 1169: 89 c1 mov %eax,%ecx
// 116b: 48 89 e0 mov %rsp,%rax
// 116e: 89 4d f8 mov %ecx,-0x8(%rbp)
// 1171: 48 89 c4 mov %rax,%rsp
// gcc:
// 113f: e8 d5 ff ff ff call 1119 <func>
// 1144: 89 45 fc mov %eax,-0x4(%rbp)
return 0;
}
> --
> Regards/Gruss,
> Boris.
>
> https://people.kernel.org/tglx/notes-about-netiquette