Re: [PATCH v5 4/9] x86/nmi: Assign and register NMI-source vectors
From: Peter Zijlstra <peterz@infradead.org>
Date: 2025-05-07 08:22:41
Also in:
kvm, linux-edac, linux-perf-users, linux-pm, lkml
On Tue, May 06, 2025 at 06:21:40PM -0700, Sohil Mehta wrote:
quoted hunk ↗ jump to hunk
diff --git a/arch/x86/include/asm/nmi.h b/arch/x86/include/asm/nmi.h index f0a577bf7bba..b9beb216f2d0 100644 --- a/arch/x86/include/asm/nmi.h +++ b/arch/x86/include/asm/nmi.h@@ -57,6 +57,38 @@ struct nmiaction { u8 source_vector; }; +/** + * NMI-source vectors are used to identify the origin of an NMI and to + * route the NMI directly to the appropriate handler. + * + * On CPUs that support NMI-source reporting with FRED, receiving an NMI + * with a valid vector sets the corresponding bit in the NMI-source + * bitmap. The bitmap is delivered as FRED event data on the stack. + * Multiple NMIs are coalesced in the NMI-source bitmap until the next + * NMI delivery. + * + * If an NMI is received without a vector or beyond the defined range, + * the CPU sets bit 0 of the NMI-source bitmap. + * + * Vector 2 is reserved for external NMIs related to the Local APIC - + * LINT1. Some third-party chipsets may send NMI messages with a + * hardcoded vector of 2, which would result in bit 2 being set in the + * NMI-source bitmap. + * + * The vectors are in no particular priority order. Add new vector + * assignments sequentially in the list below. + */ +#define NMIS_VECTOR_NONE 0 /* Reserved - Set for all unidentified sources */ +#define NMIS_VECTOR_TEST 1 /* NMI selftest */ +#define NMIS_VECTOR_EXTERNAL 2 /* Reserved - Match External NMI vector 2 */ +#define NMIS_VECTOR_SMP_STOP 3 /* Panic stop CPU */ +#define NMIS_VECTOR_BT 4 /* CPU backtrace */ +#define NMIS_VECTOR_KGDB 5 /* Kernel debugger */ +#define NMIS_VECTOR_MCE 6 /* MCE injection */ +#define NMIS_VECTOR_PMI 7 /* PerfMon counters */ + +#define NMIS_VECTORS_MAX 16 /* Maximum number of NMI-source vectors */
Are these really independent NMI vectors, or simply NMI source reporting bits? Because if they are not NMI vectors, naming them such is confusing. Specifically, is there a latch per source?
quoted hunk ↗ jump to hunk
diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c index be93ec7255bf..a1d672dcb6f0 100644 --- a/arch/x86/kernel/nmi.c +++ b/arch/x86/kernel/nmi.c@@ -184,6 +184,11 @@ int __register_nmi_handler(unsigned int type, struct nmiaction *action) raw_spin_lock_irqsave(&desc->lock, flags); + WARN_ON_ONCE(action->source_vector >= NMIS_VECTORS_MAX); + + if (!cpu_feature_enabled(X86_FEATURE_NMI_SOURCE) || type != NMI_LOCAL) + action->source_vector = 0;
How about: WARN_ON_ONCE(type != NMI_LOCAL && action->source_vector); instead?