linux-perf-users.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jacob Pan <jacob.jun.pan@linux.intel.com>
To: X86 Kernel <x86@kernel.org>,
	Sean Christopherson <seanjc@google.com>,
	LKML <linux-kernel@vger.kernel.org>,
	Thomas Gleixner <tglx@linutronix.de>,
	Dave Hansen <dave.hansen@intel.com>,
	"H. Peter Anvin" <hpa@zytor.com>,
	"Ingo Molnar" <mingo@redhat.com>,
	"Borislav Petkov" <bp@alien8.de>, "Xin Li" <xin3.li@intel.com>,
	linux-perf-users@vger.kernel.org,
	Peter Zijlstra <peterz@infradead.org>
Cc: Paolo Bonzini <pbonzini@redhat.com>,
	Tony Luck <tony.luck@intel.com>,
	Andy Lutomirski <luto@kernel.org>,
	acme@kernel.org, kan.liang@linux.intel.com,
	Andi Kleen <andi.kleen@intel.com>,
	Nikolay Borisov <nik.borisov@suse.com>,
	"Mehta, Sohil" <sohil.mehta@intel.com>,
	Jacob Pan <jacob.jun.pan@linux.intel.com>
Subject: [PATCH v4 05/11] x86/irq: Process nmi sources in NMI handler
Date: Tue,  9 Jul 2024 07:39:00 -0700	[thread overview]
Message-ID: <20240709143906.1040477-6-jacob.jun.pan@linux.intel.com> (raw)
In-Reply-To: <20240709143906.1040477-1-jacob.jun.pan@linux.intel.com>

When NMI-source reporting is enabled, the vector 2 NMI handler can
prioritize the handling of explicitly reported sources. If the source
is unknown, it will continue with the existing processing flow, meaning
all NMI handlers will be invoked.

Signed-off-by: Jacob Pan <jacob.jun.pan@linux.intel.com>

---
v4:
   - Coding style changes (Li Xin)
   - Renamed handled_mask to partial_bitmap (Nikolay)
v3:
   - Use a static flag to disable NMIs in case of HW failure
   - Optimize the case when unknown NMIs are mixed with known NMIs(HPA)
v2:
   - Disable NMI source reporting once garbage data is given in FRED
return stack. (HPA)

process nmi

Signed-off-by: Jacob Pan <jacob.jun.pan@linux.intel.com>
---
 arch/x86/kernel/nmi.c | 83 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 82 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c
index b96667eed106..edb169289a1d 100644
--- a/arch/x86/kernel/nmi.c
+++ b/arch/x86/kernel/nmi.c
@@ -149,12 +149,89 @@ static inline int do_handle_nmi(struct nmiaction *a, struct pt_regs *regs, unsig
 	return thishandled;
 }
 
+static int nmi_handle_src(unsigned int type, struct pt_regs *regs, unsigned long *partial_bitmap)
+{
+	static bool nmi_source_disabled;
+	bool has_unknown_src = false;
+	unsigned long source_bitmap;
+	struct nmiaction *a;
+	int handled = 0;
+	int vec;
+
+	if (!cpu_feature_enabled(X86_FEATURE_NMI_SOURCE) || type != NMI_LOCAL || nmi_source_disabled)
+		return 0;
+
+	source_bitmap = fred_event_data(regs);
+	if (unlikely(!source_bitmap)) {
+		pr_warn("Buggy hardware! Disable NMI-source handling.\n");
+		nmi_source_disabled = true;
+		return 0;
+	}
+
+	/*
+	 * There is no guarantee that a valid NMI-source vector is always
+	 * delivered, even when the originator specified one. It is software's
+	 * responsibility to check all available NMI sources when bit 0 is set
+	 * in the NMI-source reporting bitmap. I.e. we have to call every
+	 * handler as if there is no NMI-source reporting feature enabled.
+	 *
+	 * In this case, handlers for the known NMI sources will be called
+	 * first, followed by the remaining handlers, which are called
+	 * during the subsequent polling code.
+	 *
+	 * Conversely, if non-zero vectors appear in the source bitmap, we
+	 * can precisely identify the sources. Therefore, we only invoke the
+	 * handlers for which the corresponding bits are set.
+	 */
+	if (unlikely(source_bitmap & BIT(NMI_SOURCE_VEC_UNKNOWN))) {
+		pr_warn_ratelimited("NMI received with unknown sources\n");
+		has_unknown_src = true;
+	}
+
+	rcu_read_lock();
+
+	/* Bit 0 is for unknown NMI sources, skip it. */
+	vec = 1;
+	for_each_set_bit_from(vec, &source_bitmap, NR_NMI_SOURCE_VECTORS) {
+		a = rcu_dereference(nmiaction_src_table[vec]);
+		if (!a) {
+			pr_warn_ratelimited("NMI-source vector %d has no handler!", vec);
+			continue;
+		}
+
+		handled += do_handle_nmi(a, regs, type);
+
+		/*
+		 * Needs polling if the unknown source bit is set.
+		 * partial_bitmap is used to tell the polling code which
+		 * NMIs have already been handled based on explicit source
+		 * thus can be skipped.
+		 */
+		if (has_unknown_src)
+			*partial_bitmap |= BIT(vec);
+	}
+
+	rcu_read_unlock();
+
+	return handled;
+}
+
 static int nmi_handle(unsigned int type, struct pt_regs *regs)
 {
 	struct nmi_desc *desc = nmi_to_desc(type);
+	unsigned long partial_bitmap = 0;
 	struct nmiaction *a;
 	int handled=0;
 
+	/*
+	 * Check if the NMI source handling is complete, otherwise polling is
+	 * still required. partial_bitmap is non-zero if NMI source handling is
+	 * partial due to unknown NMI sources.
+	 */
+	handled = nmi_handle_src(type, regs, &partial_bitmap);
+	if (handled && !partial_bitmap)
+		return handled;
+
 	rcu_read_lock();
 
 	/*
@@ -163,8 +240,12 @@ static int nmi_handle(unsigned int type, struct pt_regs *regs)
 	 * can be latched at any given time.  Walk the whole list
 	 * to handle those situations.
 	 */
-	list_for_each_entry_rcu(a, &desc->head, list)
+	list_for_each_entry_rcu(a, &desc->head, list) {
+		/* Skip NMIs handled earlier with source info */
+		if (BIT(a->source_vec) & partial_bitmap)
+			continue;
 		handled += do_handle_nmi(a, regs, type);
+	}
 
 	rcu_read_unlock();
 
-- 
2.25.1


  parent reply	other threads:[~2024-07-09 14:33 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-07-09 14:38 [PATCH v4 00/11] Add support for NMI-source reporting Jacob Pan
2024-07-09 14:38 ` [PATCH v4 01/11] x86/irq: Add enumeration of NMI source reporting CPU feature Jacob Pan
2024-07-09 14:38 ` [PATCH v4 02/11] x86/irq: Define NMI source vectors Jacob Pan
2024-07-09 14:38 ` [PATCH v4 03/11] x86/irq: Extend NMI handler registration interface to include source Jacob Pan
2024-07-09 14:38 ` [PATCH v4 04/11] x86/irq: Factor out common NMI handling code Jacob Pan
2024-07-09 14:39 ` Jacob Pan [this message]
2024-07-09 14:39 ` [PATCH v4 06/11] KVM: VMX: Expand FRED kvm entry with event data Jacob Pan
2024-08-16 14:12   ` Sean Christopherson
2024-07-09 14:39 ` [PATCH v4 07/11] KVM: VMX: Handle NMI Source report in VM exit Jacob Pan
2024-08-16 14:05   ` Sean Christopherson
2024-07-09 14:39 ` [PATCH v4 08/11] perf/x86: Enable NMI source reporting for perfmon Jacob Pan
2024-07-09 15:04   ` Liang, Kan
2024-07-09 14:39 ` [PATCH v4 09/11] x86/irq: Enable NMI source on IPIs delivered as NMI Jacob Pan
2024-08-16 13:45   ` Sean Christopherson
2024-07-09 14:39 ` [PATCH v4 10/11] x86/irq: Move __prepare_ICR to x86 common header Jacob Pan
2024-07-09 14:39 ` [PATCH v4 11/11] KVM: X86: Use common code for PV IPIs in linux guest Jacob Pan
2024-08-16 13:52   ` Sean Christopherson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240709143906.1040477-6-jacob.jun.pan@linux.intel.com \
    --to=jacob.jun.pan@linux.intel.com \
    --cc=acme@kernel.org \
    --cc=andi.kleen@intel.com \
    --cc=bp@alien8.de \
    --cc=dave.hansen@intel.com \
    --cc=hpa@zytor.com \
    --cc=kan.liang@linux.intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=mingo@redhat.com \
    --cc=nik.borisov@suse.com \
    --cc=pbonzini@redhat.com \
    --cc=peterz@infradead.org \
    --cc=seanjc@google.com \
    --cc=sohil.mehta@intel.com \
    --cc=tglx@linutronix.de \
    --cc=tony.luck@intel.com \
    --cc=x86@kernel.org \
    --cc=xin3.li@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).