]> xenbits.xensource.com Git - people/aperard/linux.git/commitdiff
x86/nmi: Fix the inverse "in NMI handler" check
authorBreno Leitao <leitao@debian.org>
Wed, 7 Feb 2024 16:52:35 +0000 (08:52 -0800)
committerThomas Gleixner <tglx@linutronix.de>
Mon, 26 Feb 2024 22:41:30 +0000 (23:41 +0100)
Commit 344da544f177 ("x86/nmi: Print reasons why backtrace NMIs are
ignored") creates a super nice framework to diagnose NMIs.

Every time nmi_exc() is called, it increments a per_cpu counter
(nsp->idt_nmi_seq). At its exit, it also increments the same counter.  By
reading this counter it can be seen how many times that function was called
(dividing by 2), and, if the function is still being executed, by checking
the idt_nmi_seq's least significant bit.

On the check side (nmi_backtrace_stall_check()), that variable is queried
to check if the NMI is still being executed, but, there is a mistake in the
bitwise operation. That code wants to check if the least significant bit of
the idt_nmi_seq is set or not, but does the opposite, and checks for all
the other bits, which will always be true after the first exc_nmi()
executed successfully.

This appends the misleading string to the dump "(CPU currently in NMI
handler function)"

Fix it by checking the least significant bit, and if it is set, append the
string.

Fixes: 344da544f177 ("x86/nmi: Print reasons why backtrace NMIs are ignored")
Signed-off-by: Breno Leitao <leitao@debian.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Paul E. McKenney <paulmck@kernel.org>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/20240207165237.1048837-1-leitao@debian.org
arch/x86/kernel/nmi.c

index d23867901186648d5fe27f624c8bb6067e947494..c95dc1ba1d27b84b5c3895865e924771c95b5c24 100644 (file)
@@ -639,7 +639,7 @@ void nmi_backtrace_stall_check(const struct cpumask *btp)
                        msgp = nmi_check_stall_msg[idx];
                        if (nsp->idt_ignored_snap != READ_ONCE(nsp->idt_ignored) && (idx & 0x1))
                                modp = ", but OK because ignore_nmis was set";
-                       if (nmi_seq & ~0x1)
+                       if (nmi_seq & 0x1)
                                msghp = " (CPU currently in NMI handler function)";
                        else if (nsp->idt_nmi_seq_snap + 1 == nmi_seq)
                                msghp = " (CPU exited one NMI handler function)";