Re: [PATCH v2 4/6] x86/irq: Process nmi sources in NMI handler

From: H. Peter Anvin
Date: Tue Jun 11 2024 - 14:44:30 EST


On 6/11/24 09:54, Jacob Pan wrote:
+
+ source_bitmask = fred_event_data(regs);
+ if (!source_bitmask) {
+ pr_warn_ratelimited("NMI without source information! Disable source reporting.\n");
+ setup_clear_cpu_cap(X86_FEATURE_NMI_SOURCE);
+ return 0;
+ }

Is setup_clear_cpu_cap() even meaningful here?

+
+ /*
+ * Per NMI source specification, there is no guarantee that a valid
+ * NMI vector is always delivered, even when the source specified
+ * one. It is software's responsibility to check all available NMI
+ * sources when bit 0 is set in the NMI source bitmap. i.e. we have
+ * to call every handler as if we have no NMI source.
+ * On the other hand, if we do get non-zero vectors, we know exactly
+ * what the sources are. So we only call the handlers with the bit set.
+ */
+ if (source_bitmask & BIT(NMI_SOURCE_VEC_UNKNOWN)) {
+ pr_warn_ratelimited("NMI received with unknown source\n");
+ return 0;
+ }
+

You can still dispatch the known NMI handlers early before doing the polling.

+ rcu_read_lock();
+ /* Bit 0 is for unknown NMI sources, skip it. */
+ for_each_set_bit_from(vec, &source_bitmask, NR_NMI_SOURCE_VECTORS) {
+ a = rcu_dereference(nmiaction_src_table[vec]);
+ if (!a) {
+ pr_warn_ratelimited("NMI received %d no handler", vec);
+ continue;
+ }
+ handled += do_handle_nmi(a, regs, type);
+ }
+ rcu_read_unlock();
+ return handled;
+}
+

That would mean that you would also need to return a bitmask of which source vectors need to be handled with polling.

-hpa