From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8702337BE87 for ; Mon, 11 May 2026 12:25:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778502319; cv=none; b=C4sqYwPnOSlKL7PNWSbdxu9fg81G867QFeNB8Lx6fJ3KU1ZlMK1AmC6jRtJtNmaXReffcQ8ZXYcH1pEokHlyJBxpuwvAHt9ydId3LPBgidcCv1P9Yfi87q+beROslswlPsmuPpiyXBM3Nw6swIvNsKQnU+GRN6r48RfvQ3BlWAg= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778502319; c=relaxed/simple; bh=GXpHMM9QguAeMwvFebblRjdG4EzpLyRNvhYKfhMKMfU=; h=From:To:Cc:Subject:In-Reply-To:References:Date:Message-ID: MIME-Version:Content-Type; b=A6JKRo1Bzctn1MqjUH6VF7J83LzGmbUZF+IJvuqKs9DiquSMjHGlbMZGfbHIftG+w/fHYhGq1qMp+/DW2Nm1zjfQ2ud2xdAzCVPmrVWo4qxI5H65ql8ASxRd7QKr566Kg6TH1yrBJ8TG1wH1eSSdvOIzgna8M45Q+vBQ8AR2a+4= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=n2A1PSne; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="n2A1PSne" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5AF80C2BCB0; Mon, 11 May 2026 12:25:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1778502319; bh=GXpHMM9QguAeMwvFebblRjdG4EzpLyRNvhYKfhMKMfU=; h=From:To:Cc:Subject:In-Reply-To:References:Date:From; b=n2A1PSned1PBiJDa2MXJtEccTSJl0elZdVVGZuytfvK2j8uS5IXpltKRDHuPtqvod 22tAS3GcUtg7fSA3V9khpl+DoNy2KB9YZr/Uy5wOoZUQVjO7UzJfnw6bygMl16lnD/ p4EBR1CqXNIirwWOzEZiecJg0/E6SlbYGgdm4ajHqR/akmdWjQ74BwGDIKGP8DXgvE ZY6XwY2bskve1z8mlMIiGWBJlNmEGJxGXzYteberlQ409pbhDOm51b6WYw19QT6HoG Kk3sAR/r9CGMZmVr0G7PxCeNa+9+F7YNPWgb6wNQStQTTCPh/8KhE3kno4idL2KoQK Pe6RUpR1DEStQ== From: Thomas Gleixner To: Alexander Potapenko , Dmitry Vyukov , Mark Rutland Cc: syzbot , kasan-dev , linux-kernel@vger.kernel.org, luto@kernel.org, peterz@infradead.org, syzkaller-bugs@googlegroups.com, ruanjinjie@huawei.com Subject: Re: [syzbot] [kernel?] upstream test error: KMSAN: uninit-value in irqentry_exit_to_kernel_mode_preempt In-Reply-To: References: <69e7ee1f.a00a0220.17a17.001d.GAE@google.com> Date: Mon, 11 May 2026 14:25:15 +0200 Message-ID: <87v7cu876c.ffs@tglx> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable On Wed, Apr 29 2026 at 10:09, Alexander Potapenko wrote: > On Wed, Apr 29, 2026 at 8:29=E2=80=AFAM Dmitry Vyukov wrote: > > I believe Mark's recent changes introduced this. I don't believe any of this. I prefer facts. > irqentry_exit_to_kernel_mode_preempt() is now checking for both `regs` > and `state`. > Because there is a lot of non-instrumented code around, we fail to > initialize these variables. > Instead, irqentry_enter_from_kernel_mode() explicitly calls > kmsan_unpoison_entry_regs(regs) to take care of the registers, but not > the state. > We should probably call `kmsan_unpoison_memory(&state, sizeof(state))` > at the same place. Good luck with unpoisoning 'state'. 'state' is not memory to begin with. 'state' is composed in irqentry_enter_from_kernel_mode() and returned from there to the caller as value in RAX. That returned value is then provided as function argument to irqentry_exit() and subsequently to the inlines invoked from there. See the deeper ASM analysis below. Aside of that the whole splat makes no sense at all due to this: >> > Uninit was created at: >> > slab_post_alloc_hook mm/slub.c:4576 [inline] >> > slab_alloc_node mm/slub.c:4898 [inline] >> > __do_kmalloc_node mm/slub.c:5294 [inline] >> > __kmalloc_node_track_caller_noprof+0x4f6/0x1750 mm/slub.c:5403 >> > kmalloc_reserve net/core/skbuff.c:635 [inline] >> > __alloc_skb+0x90d/0x1190 net/core/skbuff.c:713 >> > alloc_skb include/linux/skbuff.h:1383 [inline] >> > nsim_dev_trap_skb_build drivers/net/netdevsim/dev.c:819 [inline] >> > nsim_dev_trap_report drivers/net/netdevsim/dev.c:876 [inline] >> > nsim_dev_trap_report_work+0x3f2/0x1430 drivers/net/netdevsim/dev.c:922 How can irqentry_exit_to_kernel_mode_preempt() "touch" an uninitialized SKB which was allocated by the interrupted code, when it only evaluates regs->eflags and the rcu_exit portion of the register supplied 'state' argument? >> > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D >> > BUG: KMSAN: uninit-value in irqentry_exit_to_kernel_mode_preempt+0xb0/= 0xc0 include/linux/irq-entry-common.h:472 >> > irqentry_exit_to_kernel_mode_preempt+0xb0/0xc0 include/linux/irq-entr= y-common.h:472 >> > irqentry_exit_to_kernel_mode include/linux/irq-entry-common.h:547 [in= line] >> > irqentry_exit+0x7b/0x760 kernel/entry/common.c:164 >> > sysvec_apic_timer_interrupt+0x52/0x90 arch/x86/kernel/apic/apic.c:1061 >> > asm_sysvec_apic_timer_interrupt+0x1f/0x30 arch/x86/include/asm/idtent= ry.h:697 >> > __sanitizer_cov_trace_pc+0x5/0x70 kernel/kcov.c:210 >> > nsim_dev_trap_skb_build drivers/net/netdevsim/dev.c:842 [inline] >> > nsim_dev_trap_report drivers/net/netdevsim/dev.c:876 [inline] >> > nsim_dev_trap_report_work+0x8c0/0x1430 drivers/net/netdevsim/dev.c:922 So I got the vmlinux and disassembled the related code parts: ffffffff81da7240 : ffffffff81da7240: 55 push %rbp ffffffff81da7241: 48 89 e5 mov %rsp,%rbp ffffffff81da7244: 41 57 push %r15 ffffffff81da7246: 41 56 push %r14 ffffffff81da7248: 41 55 push %r13 ffffffff81da724a: 41 54 push %r12 ffffffff81da724c: 53 push %rbx ffffffff81da724d: 41 89 f6 mov %esi,%r14d // Save '= state' in r14 ffffffff81da7250: 49 89 ff mov %rdi,%r15 // = Save 'regs' in r15 ffffffff81da7253: e8 08 84 d4 00 call ffffffff82aef660 <__= msan_get_context_state> ffffffff81da7258: 44 0f b6 68 08 movzbl 0x8(%rax),%r13d // = Read magic value into r13d (related to 'state') ffffffff81da725d: 8b 98 90 0c 00 00 mov 0xc90(%rax),%ebx // = Read magic value into ebx (related to 'regs') ffffffff81da7263: 4d 8b a7 90 00 00 00 mov 0x90(%r15),%r12 // = Read regs->eflags into r12 ffffffff81da726a: 49 81 c7 90 00 00 00 add $0x90,%r15 // Add ef= lags offset to r15 ffffffff81da7271: 4c 89 ff mov %r15,%rdi // MSAN ch= eck for accessing regs->eflags ffffffff81da7274: e8 b7 78 d4 00 call ffffffff82aeeb30 <__= msan_metadata_ptr_for_load_8> ffffffff81da7279: 8b 08 mov (%rax),%ecx // Read = magic data from the address returned by msan ffffffff81da727b: 89 c8 mov %ecx,%eax // Transfe= r result to eax ffffffff81da727d: f7 d0 not %eax // One's compl= ement negate eax ffffffff81da727f: 41 81 e4 00 02 00 00 and $0x200,%r12d // Isol= ate eflags::IF (bit 9) ffffffff81da7286: c1 e9 09 shr $0x9,%ecx // Right s= hift the magic value by 9 (IF into bit 0) ffffffff81da7289: 0d ff fd ff ff or $0xfffffdff,%eax // = Set all bits in eax except bit 9 ffffffff81da728e: 41 85 c4 test %eax,%r12d // Logica= l compare between eax and r12d The result is in ZF: 1 when bit 9 is not set in eax and/or r12d. 0 if bit 9= is set in both. =09 ffffffff81da7291: 0f 94 c0 sete %al // If ZF=3D=3D1= AL=3D1 otherwise AL=3D0 ffffffff81da7294: 20 c8 and %cl,%al // And the = right shifted bit 9 ffffffff81da7296: 4d 85 e4 test %r12,%r12 // Check w= hether r12 is 0 ( IF set or not ) ffffffff81da7299: 41 0f 94 c7 sete %r15b // If ZF=3D= =3D1 r15b=3D1 otherwise r15b=3D0 ffffffff81da729d: 44 89 e1 mov %r12d,%ecx // Transf= er the isolated bit 9 into ecx ffffffff81da72a0: c1 e9 09 shr $0x9,%ecx // Shift i= t into bit 0 ffffffff81da72a3: 44 20 e9 and %r13b,%cl // And the= magic context state value ffffffff81da72a6: 45 08 f7 or %r14b,%r15b // Or 's= tate' on the IF result created above ffffffff81da72a9: 41 f6 d6 not %r14b // One's comp= lement negate 'state' ffffffff81da72ac: 45 08 ee or %r13b,%r14b // Or th= e above magic KMSAN value on the negated 'state' 'state' is a register argument value. So how on earth can KMSAN mangle this with information stored in the KMSAN context? See below. ffffffff81da72af: 41 0f b6 f6 movzbl %r14b,%esi // zero e= xtend the result into esi ffffffff81da72b3: 0f b6 c9 movzbl %cl,%ecx // zero ex= tend the magic result into ecx ffffffff81da72b6: 84 c0 test %al,%al // Check wh= ether al is 0 (magic IF result) ffffffff81da72b8: 0f 45 ce cmovne %esi,%ecx // = If not, move the magic mangled state result into ecx This is where the whole thing goes south because it uses the register state which was wrongfully mangled with the KMSAN state in r13b. ffffffff81da72bb: f6 c1 01 test $0x1,%cl // Check w= hether the result is 1 // If 1, jump to the kmsan warning section ffffffff81da72be: 75 1b jne ffffffff81da72db ffffffff81da72c0: 41 f6 c7 01 test $0x1,%r15b // = Check the actual condition i.e. if (regs_irqs_disabled(regs) || state.exit_rcu) ffffffff81da72c4: 75 05 jne ffffffff81da72cb ffffffff81da72c6: e8 9d f1 37 0f call ffffffff91126468 <__= SCT__irqentry_exit_cond_resched> ffffffff81da72cb: 5b pop %rbx ffffffff81da72cc: 41 5c pop %r12 ffffffff81da72ce: 41 5d pop %r13 ffffffff81da72d0: 41 5e pop %r14 ffffffff81da72d2: 41 5f pop %r15 ffffffff81da72d4: 5d pop %rbp ffffffff81da72d5: 2e e9 d5 e2 37 0f cs jmp ffffffff911255b0 <__= pi___x86_return_thunk> // KMSAN warning ffffffff81da72db: 31 c9 xor %ecx,%ecx ffffffff81da72dd: 4d 85 e4 test %r12,%r12 ffffffff81da72e0: 0f 44 d9 cmove %ecx,%ebx ffffffff81da72e3: 84 c0 test %al,%al ffffffff81da72e5: 74 02 je ffffffff81da72e9 ffffffff81da72e7: 8b 1a mov (%rdx),%ebx ffffffff81da72e9: 89 df mov %ebx,%edi ffffffff81da72eb: e8 30 83 d4 00 call ffffffff82aef620 <__= msan_warning> ffffffff81da72f0: 41 f6 c7 01 test $0x1,%r15b ffffffff81da72f4: 74 d0 je ffffffff81da72c6 ffffffff81da72f6: eb d3 jmp ffffffff81da72cb Let's look at the call sites to prove that KMSAN cannot observe 'state' as a memory access ever. noinstr sysvec_apic_timer_interrupt(regs) { // Not observable stack or register state irqentry_state_t state =3D irqentry_enter(regs); instrumentation_begin(); __sysvec_apic_timer_interrupt(regs); instrumentation_end(); irqentry_exit(regs, state); } Here is the disassembly: ffffffff910e6840 : ffffffff910e6840: f3 0f 1e fa endbr64 ffffffff910e6844: 55 push %rbp ffffffff910e6845: 48 89 e5 mov %rsp,%rbp ffffffff910e6848: 41 56 push %r14 ffffffff910e684a: 53 push %rbx ffffffff910e684b: 48 89 fb mov %rdi,%rbx /= / Saves 'regs' in rbx ffffffff910e684e: e8 ad 07 00 00 call ffffffff910e7000 // invokes irqentry_enter() ffffffff910e6853: 41 89 c6 mov %eax,%r14d = // Saves the returned 'state' in r14d ffffffff910e6856: 65 c6 05 a2 d9 7f 04 01 movb $0x1,%gs:0x47fd9a2(%= rip) # ffffffff958e4200 ffffffff910e685e: 90 nop ffffffff910e685f: f6 83 88 00 00 00 03 testb $0x3,0x88(%rbx) ffffffff910e6866: 75 0b jne ffffffff910e6873 ffffffff910e6868: 65 8a 05 c3 f7 76 04 mov %gs:0x476f7c3(%rip),= %al # ffffffff95856032 ffffffff910e686f: 84 c0 test %al,%al ffffffff910e6871: 74 29 je ffffffff910e689c ffffffff910e6873: e8 28 eb 8e f0 call ffffffff819d53a0 ffffffff910e6878: 48 89 df mov %rbx,%rdi ffffffff910e687b: e8 c0 a5 80 f0 call ffffffff818f0e40 <__= sysvec_apic_timer_interrupt> ffffffff910e6880: e8 3b ed 8e f0 call ffffffff819d55c0 ffffffff910e6885: 90 nop ffffffff910e6886: 41 0f b6 f6 movzbl %r14b,%esi // Move= s the saved 'state' into esi ffffffff910e688a: 48 89 df mov %rbx,%rdi // Moves= the saved 'regs' into rdi ffffffff910e688d: e8 4e 08 00 00 call ffffffff910e70e0 // Invokes irqentry_exit() ffffffff910e6892: 5b pop %rbx ffffffff910e6893: 41 5e pop %r14 ffffffff910e6895: 5d pop %rbp ffffffff910e6896: 2e e9 14 ed 03 00 cs jmp ffffffff911255b0 <__= pi___x86_return_thunk> ffffffff910e689c: 65 c6 05 8e f7 76 04 01 movb $0x1,%gs:0x476f78e(%= rip) # ffffffff95856032 ffffffff910e68a4: 65 4c 8b 1d 54 f7 76 04 mov %gs:0x476f754(%rip),= %r11 # ffffffff95856000 ffffffff910e68ac: 49 89 23 mov %rsp,(%r11) ffffffff910e68af: 4c 89 dc mov %r11,%rsp ffffffff910e68b2: e8 e9 ea 8e f0 call ffffffff819d53a0 ffffffff910e68b7: 48 89 df mov %rbx,%rdi ffffffff910e68ba: e8 81 a5 80 f0 call ffffffff818f0e40 <__= sysvec_apic_timer_interrupt> ffffffff910e68bf: e8 fc ec 8e f0 call ffffffff819d55c0 ffffffff910e68c4: 5c pop %rsp ffffffff910e68c5: 65 c6 05 65 f7 76 04 00 movb $0x0,%gs:0x476f765(%= rip) # ffffffff95856032 ffffffff910e68cd: eb b6 jmp ffffffff910e6885 ffffffff910e68cf: 90 nop Purely register state in a function which is not instrumented to begin with. Now let's look at irqentry_enter(): noinstr irqentry_enter(regs) { // Not observable stack or register state irqentry_state_t state =3D ....; .... return state; } ffffffff910e7000 : ffffffff910e7000: f3 0f 1e fa endbr64 ffffffff910e7004: 55 push %rbp ffffffff910e7005: 48 89 e5 mov %rsp,%rbp ffffffff910e7008: 53 push %rbx ffffffff910e7009: f6 87 88 00 00 00 03 testb $0x3,0x88(%rdi) /= / check for kernel entry ffffffff910e7010: 74 59 je ffffffff910e706b // branch taken=20 ... ffffffff910e706b: 65 48 8b 05 95 ef 76 04 mov %gs:0x476ef95(%rip),= %rax # ffffffff95856008 ffffffff910e7073: f6 40 2c 02 testb $0x2,0x2c(%rax) = // is_idle_task()? ffffffff910e7077: 75 0b jne ffffffff910e7084 =09 ffffffff910e7079: 90 nop ffffffff910e707a: e8 91 99 a0 f1 call ffffffff82af0a10 // Unpoisons regs ffffffff910e707f: 90 nop ffffffff910e7080: 31 c0 xor %eax,%eax = // state =3D 0 ffffffff910e7082: eb 14 jmp ffffffff910e7098 // return ffffffff910e7084: 48 89 fb mov %rdi,%rbx = // Preserve 'regs'=09=20=20 ffffffff910e7087: e8 44 0c 00 00 call ffffffff910e7cd0 ffffffff910e708c: 90 nop ffffffff910e708d: 48 89 df mov %rbx,%rdi /= / Restore 'regs' ffffffff910e7090: e8 7b 99 a0 f1 call ffffffff82af0a10 // Unpoisons 'regs' ffffffff910e7095: 90 nop ffffffff910e7096: b0 01 mov $0x1,%al /= / state =3D 1 ffffffff910e7098: 5b pop %rbx // re= turn ffffffff910e7099: 5d pop %rbp ffffffff910e709a: 2e e9 10 e5 03 00 cs jmp ffffffff911255b0 <__= pi___x86_return_thunk> As this just returns state constants in RAX, there is zero related KMSAN me= mory state, right? Now irqentry_exit: noinstr irqentry_exit(regs, state) { .... irqentry_exit_to_kernel_mode_preempt(regs, state); } ffffffff910e70e0 : ffffffff910e70e0: f3 0f 1e fa endbr64 ffffffff910e70e4: 55 push %rbp ffffffff910e70e5: 48 89 e5 mov %rsp,%rbp ffffffff910e70e8: 41 57 push %r15 ffffffff910e70ea: 41 56 push %r14 ffffffff910e70ec: 41 55 push %r13 ffffffff910e70ee: 41 54 push %r12 ffffffff910e70f0: 53 push %rbx ffffffff910e70f1: 48 83 ec 68 sub $0x68,%rsp ffffffff910e70f5: 49 89 fe mov %rdi,%r14 // Save 'r= egs' ffffffff910e70f8: f6 87 88 00 00 00 03 testb $0x3,0x88(%rdi) // r= eturn to kernel mode ffffffff910e70ff: 74 4c je ffffffff910e714d // branch taken ... ffffffff910e714d: 89 f3 mov %esi,%ebx // Save 's= tate' ffffffff910e714f: 90 nop ffffffff910e7150: 0f b6 f3 movzbl %bl,%esi ffffffff910e7153: 4c 89 f7 mov %r14,%rdi ffffffff910e7156: e8 e5 00 cc f0 call ffffffff81da7240 ffffffff910e715b: 90 nop Again. 'state' is a pure register value, which is handed to irqentry_exit() and irqentry_exit_to_kernel_mode_preempt(). But KMSAN magically associates a memory access which it and then claims it belongs to a SKB which was allocated in the interrupted code. What Mark's change actually does is to make the register value 'state' observable in an instrumented function, while before that 'state' was always confined in the non instrumentable code. But as that 'state' argument of irqentry_exit_to_kernel_mode_preempt() is a pure register value, which could be even a constant supplied by the caller of irqentry_exit(), KMSAN has _ZERO_ business to fiddle with it. I just built the same .config with clang-19 and it is hallucinating in the same way, though the actual assembly is more readable than the syzbot clang-21 variant: 0000000000002710 : 2710: 55 push %rbp 2711: 48 89 e5 mov %rsp,%rbp 2714: 41 57 push %r15 2716: 41 56 push %r14 2718: 41 55 push %r13 271a: 41 54 push %r12 271c: 53 push %rbx 271d: 89 f3 mov %esi,%ebx // save 'state' in= EBX 271f: 49 89 ff mov %rdi,%r15 // save 'regs' in = R15 2722: e8 00 00 00 00 call 2727 2723: R_X86_64_PLT32 __msan_get_context_state-0x4 2727: 44 0f b6 60 08 movzbl 0x8(%rax),%r12d // Magic K= MSAN data related to 'state' 272c: 44 8b b0 90 0c 00 00 mov 0xc90(%rax),%r14d // Magic = KMSAN data related to 'regs::eflags' 2733: 4d 8b af 90 00 00 00 mov 0x90(%r15),%r13 // Read th= e actual regs->eflags 273a: 49 81 c7 90 00 00 00 add $0x90,%r15 // Adjust point= er to regs::eflags 2741: 4c 89 ff mov %r15,%rdi 2744: e8 00 00 00 00 call 2749 2745: R_X86_64_PLT32 __msan_metadata_ptr_for_load_8= -0x4 2749: 48 8b 00 mov (%rax),%rax // Read the KM= SAN state 274c: 25 00 02 00 00 and $0x200,%eax // Isolat= e bit 9 (IF?) 2751: 41 81 e5 00 02 00 00 and $0x200,%r13d // Isolate IF= in the actual value 2758: 48 85 c0 test %rax,%rax // Test whether = the KMSAN IF state is 0 275b: 74 07 je 2764 // Not zero 275d: f7 d0 not %eax // negate the KMSAN = state 275f: 44 21 e8 and %r13d,%eax // And the actu= al value (IF isolated) // If zero, goto MSAN warning 2762: 74 25 je 2789 =20=20=20=20 2764: 4d 85 ed test %r13,%r13 // Check whether= IF is set // If not, return 2767: 74 10 je 2779 2769: 41 f6 c4 01 test $0x1,%r12b // Check the ma= gic KMSAN state (related to 'state') // If not zero, goto MSAN warning=20=20=20 276d: 75 28 jne 2797 276f: f6 c3 01 test $0x1,%bl // Check state.r= cu_exit // If not, return 2772: 75 05 jne 2779 2774: e8 00 00 00 00 call 2779 2775: R_X86_64_PLT32 __SCT__irqentry_exit_cond_resc= hed-0x4 2779: 5b pop %rbx 277a: 41 5c pop %r12 277c: 41 5d pop %r13 277e: 41 5e pop %r14 2780: 41 5f pop %r15 2782: 5d pop %rbp 2783: 2e e9 00 00 00 00 cs jmp 2789 2785: R_X86_64_PLT32 __x86_return_thunk-0x4 2789: 8b 3a mov (%rdx),%edi 278b: e8 00 00 00 00 call 2790 278c: R_X86_64_PLT32 __msan_warning-0x4 2790: 4d 85 ed test %r13,%r13 2793: 75 d4 jne 2769 2795: eb e2 jmp 2779 2797: 44 89 f7 mov %r14d,%edi 279a: e8 00 00 00 00 call 279f 279b: R_X86_64_PLT32 __msan_warning-0x4 279f: f6 c3 01 test $0x1,%bl 27a2: 74 d0 je 2774 27a4: eb d3 jmp 2779 The compiler _cannot_ assume anything about the 'state' argument as that's handed in as value in RSI from a completely different compilation unit. Something is wrong in KMSAN/compiler land or do you still believe that you just need to unpoison the non existing memory 'state'? Thanks, tglx