Re: kprobes broken since 0d00449c7a28 ("x86: Replace ist_enter() with nmi_enter()")

From: Peter Zijlstra
Date: Tue Feb 02 2021 - 13:33:26 EST


On Tue, Feb 02, 2021 at 11:56:23AM -0500, Steven Rostedt wrote:

> NMIs are special, and they always have been. They shouldn't be doing much
> anyway. If they are, then that's a problem.

There is a fair amount of NMI level code these days, and it seems to be
ever increasing...

> My question wasn't to have them do it, I was simply asking if they do. I
> was assuming that they do not.

per nmi_enter() we do:

__preempt_count_add(NMI_OFFSET + HARDIRQ_OFFSET); \

> > But it doesn't help with:
> >
> > spin_lock_irq(&foo); // task context
> > #DB
> > spin_lock_irq(&foo); // interrupt context per your above
>
> The statement above said:
>
> "If #DB and #BP do not change the in_interrupt() context"
>
> Which would make the above be in the same context and the handler would
> not be called for the #DB case.

But then replace the above #DB with __fentry__ and explain how it is
fundamentally different? And consider that direct call into god knows
what code option you have. That doesn't go past any recursion checks
IIRC.

> I'm fine with #DB and #BP being a "in_nmi()", as they are probably even
> more special than NMIs.

That does mean that kprobes are then fundamentally running from
in_nmi(), which is what started all this.

Sure, the opt-probes and ftrace-probes don't actually have in_nmi() set
today (because they don't trigger an exception), but given that that is
all optional, any kprobe handler had better be in_nmi() clean.