Re: [PATCH] x86/mm: fix objtool failure with KMSAN enabled

Dmitry Voytik <[email protected]> Thu, 2 Jul 2026 12:41:09 +0200
Newsgroups org.kernel.vger.linux-toolchains,dev.linux.lists.llvm,org.kernel.vger.linux-kernel
Message-ID <CAAX90H0V-=Gy1FyBT9qop2=RvhBxbOPLu6+DYpPH2pTehT=nRw@mail.gmail.com>
Hi Borislav,

On Thu, Jul 2, 2026 at 4:54=E2=80=AFAM Borislav Petkov <[email protected]> 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=3D1 defconfig
> >   ./scripts/config -e CONFIG_KMSAN \
> >     -e CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT
> >   make LLVM=3D1 olddefconfig
> >   make LLVM=3D1 -j(nproc) vmlinux
> >   ...
> >     LD      vmlinux.o
> >   vmlinux.o: warning: objtool: folio_zero_user+0x801: undefined stack s=
tate
> >   vmlinux.o: error: objtool: folio_zero_user+0x801: unknown CFA base re=
g -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=3D1 OBJTOOL_VERBOSE=3D1 -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_un=
rol
> >
> > 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+0x=
817>
> >
> > 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 f=
irst
> 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=3Dmain 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 =3D 0;

    __asm__ __volatile__ ( "call func\n\t" : "=3Da" (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, "=3Da" (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" : "=3Da" (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