Re: [syzbot] [kernel?] upstream test error: KMSAN: uninit-value in irqentry_exit_to_kernel_mode_preempt

From: Thomas Gleixner

Date: Thu Jun 25 2026 - 17:05:08 EST


On Tue, Jun 09 2026 at 15:34, Alexander Potapenko wrote:
>> So let me finally take a stab at it.
>
> Hi Thomas,
>
> I have a draft Clang patch implementing the following intrinsics at
> https://github.com/llvm/llvm-project/pull/202603:
> - llvm.kmsan.instrumentation.begin
> - llvm.kmsan.instrumentation.end
> - llvm.kmsan.instrumentation.update.context (to reload the context
> pointer; I am not using it yet).
>
> Below is the kernel patch that I am applying to insert these
> intrinsics into the instrumentation regions.
> I thought it would be a good idea to warn if
> llvm.kmsan.instrumentation.{begin,end} are called from functions that
> are fully instrumented or have `no_sanitize("memory")` (aka
> __no_kmsan_checks), but surprisingly, there were loads of such
> functions.
>
> It turned out that WARN() and BUG() unconditionally invoke
> instrumentation_begin() and instrumentation_end(), even for
> instrumented functions.
> Was there any long-term plan to fix that, or is my warning useless by design?

The reason why e.g. WARN() and BUG() unconditionally do that is that we
decided that getting out the WARN/BUG information has priority and IIRC
we mostly did that to shut the objtool noinstr validation up. There is a
halfways comprehensible comment in x86...bug.h:

/*
* This instrumentation_begin() is strictly speaking incorrect; but it
* suppresses the complaints from WARN()s in noinstr code. If such a WARN()
* were to trigger, we'd rather wreck the machine in an attempt to get the
* message out than not know about it.
*/

It could be fixed by having some special version of BUG/WARN() which will
be a bit of a whack a mole game, but if it helps to make the sanitizers
saner, then that's probably worth it.

> Patch follows:
> ```
> diff --git a/include/linux/instrumentation.h b/include/linux/instrumentation.h
> index bf675a8aef8ab..49a2ee638120b 100644
> --- a/include/linux/instrumentation.h
> +++ b/include/linux/instrumentation.h
> @@ -4,6 +4,7 @@
>
> #ifdef CONFIG_NOINSTR_VALIDATION
>
> +#include <linux/kmsan-checks.h>
> #include <linux/objtool.h>
> #include <linux/stringify.h>
>
> @@ -12,6 +13,7 @@
> asm volatile(__stringify(c) ": nop\n\t" \
> ANNOTATE_INSTR_BEGIN(__ASM_BREF(c)) \
> : : "i" (c)); \
> + kmsan_instrumentation_begin(); \
> })
> #define instrumentation_begin() __instrumentation_begin(__COUNTER__)
>
> @@ -47,6 +49,7 @@
> * part of the condition block and does not escape.
> */
> #define __instrumentation_end(c) ({ \
> + kmsan_instrumentation_end(); \
> asm volatile(__stringify(c) ": nop\n\t" \
> ANNOTATE_INSTR_END(__ASM_BREF(c)) \
> : : "i" (c)); \

Looks very reasonable.

Thanks for looking into this!

tglx