On Thu, Oct 27, 2022 at 1:05 AM Peter Zijlstra <peterz@xxxxxxxxxxxxx> wrote: > > On Wed, Oct 26, 2022 at 11:38:53AM -0700, Alexander Potapenko wrote: > > A bigger issue from the NMI perspective is probably > > having __msan_poison_alloca() inserted in every non-noinstr kernel > > function, because that hook may acquire the stackdepot lock. > > *urgghhh* that's broken, that must not be. There is a *TON* of NMI > functions that are non-noinstr. __msan_poison_alloca() is guarded by kmsan_in_runtime(), which is currently implemented as: static __always_inline bool kmsan_in_runtime(void) { if ((hardirq_count() >> HARDIRQ_SHIFT) > 1) return true; return kmsan_get_context()->kmsan_in_runtime; } I think the easiest way to fix the NMI situation would be adding "if in_nmi() return true"? Currently that will render kmsan_unpoison_memory() useless in NMI context, but I think we don't need a check for kmsan_in_runtime() there, because unpoisoning is self-contained and normally does not recurse (guess we can tolerate a pr_err() on the rare assertion violation path?) > What's worse, it seems to do a memory allocation as well, and that's out > the window with PREEMPT_RT where you can't do even GFP_ATOMIC from > regular IRQ context. Yes, there's a lazy call to alloc_pages() in lib/stackdepot.c that is done when we run out of storage space. It would be a pity to ignore everything that is happening inside regular IRQs (by making kmsan_in_runtime() bail out on in_irq()) - I think we occasionally see errors from there, e.g. https://syzkaller.appspot.com/bug?id=233563e79a8e00f86412eb3d2fb4eb1f425e70c3 We could make stackdepot avoid allocating memory in IRQs/NMIs and hope that calls to __msan_poison_alloca() from regular contexts keep up with draining the storage from interrupts. Another option would be to preallocate a very big chunk of memory for stackdepot and never do allocations again. These tricks won't however save us from acquiring depot_lock from lib/stackdepot.c every time we want to create a new origin. But that should not be a problem by itself, because we always do kmsan_enter_runtime() before accessing the stack depot - i.e. it won't be taken recursively. Given that PREEMPT_RT is not the default at the moment, shall we make KMSAN incompatible with it for the time being? > That function is wholly unacceptable to be added to every kernel > function. > -- Alexander Potapenko Software Engineer Google Germany GmbH Erika-Mann-Straße, 33 80636 München Geschäftsführer: Paul Manicle, Liana Sebastian Registergericht und -nummer: Hamburg, HRB 86891 Sitz der Gesellschaft: Hamburg