From nobody Thu Apr 9 09:02:05 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B410DC433FE for ; Thu, 3 Nov 2022 18:00:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232140AbiKCSAn (ORCPT ); Thu, 3 Nov 2022 14:00:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37680 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232072AbiKCR73 (ORCPT ); Thu, 3 Nov 2022 13:59:29 -0400 Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7107E5F97 for ; Thu, 3 Nov 2022 10:59:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1667498362; x=1699034362; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=OZimIu89EeGi5tqLMGLYWDXCZnDY709jANJn7l/dlDM=; b=Mpx6SJJZHPkR7EsUdeLIiScHl6ObAm4/NLI9wgNZcQJJcNmBFCe8Nl5u 2BsdYZMKpQ5W6VF2+kgw0xuSB6PU8Q7yb0/A3YjNHcl/lsE2Je445wBDo fBdNHNWctgZeShvO8hK3UPEyrSrYQNt7GDjO2N4zvln1rnOnzPCN5ItvN NnBK8Hch3qUxuF3B7jG33sK3oTQzsLI0A5XoSKY1NcJxNwVobsWI9gWOL 3FyjBrprcT+VRX8hZj6NAaMicXj5Wi/JaF7Zk2sH6f/NDryWx/fWQ3VKO EsV3fNZXODjIjY+YJpyvrKg5O35vjZxvZdVF4yuNAuxhrAknYLO4Y4ctd w==; X-IronPort-AV: E=McAfee;i="6500,9779,10520"; a="308476972" X-IronPort-AV: E=Sophos;i="5.96,134,1665471600"; d="scan'208";a="308476972" Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 03 Nov 2022 10:59:18 -0700 X-IronPort-AV: E=McAfee;i="6500,9779,10520"; a="809762556" X-IronPort-AV: E=Sophos;i="5.96,134,1665471600"; d="scan'208";a="809762556" Received: from araj-dh-work.jf.intel.com ([10.165.157.158]) by orsmga005-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 03 Nov 2022 10:59:18 -0700 From: Ashok Raj To: Borislav Petkov , Thomas Gleixner Cc: "LKML Mailing List" , X86-kernel , Tony Luck , Dave Hansen , Arjan van de Ven , Andy Lutomirski , Jacon Jun Pan , Tom Lendacky , Kai Huang , Andrew Cooper , Jacob Pan , Ashok Raj Subject: [v2 06/13] x86/ipi: Support sending NMI_VECTOR as self ipi Date: Thu, 3 Nov 2022 17:58:54 +0000 Message-Id: <20221103175901.164783-7-ashok.raj@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20221103175901.164783-1-ashok.raj@intel.com> References: <20221103175901.164783-1-ashok.raj@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: Jacob Pan apic->send_IPI_self() can be used to send any general vector as a self IPI. The function uses a SHORTCUT specifier, but it can't be used to send a vector with delivery mode as NMI. Chapter 10, Advanved Programmable Interrupt Controller (APIC) Table 10-3 indicates that the shortcut isn't a legal combination for NMI delivery. The same is true for x2apic implementations as well, the self IPI MSR can only specify the vector number, but no delivery mode. The helper adds proper handling if the vector is NMI_VECTOR. Suggested-by: Ashok Raj Signed-off-by: Jacob Pan Co-developed-by: Ashok Raj Reviewed-by: Tony Luck Signed-off-by: Ashok Raj --- arch/x86/kernel/apic/ipi.c | 6 +++++- arch/x86/kernel/apic/x2apic_phys.c | 6 +++++- arch/x86/kernel/nmi_selftest.c | 32 ++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/apic/ipi.c b/arch/x86/kernel/apic/ipi.c index 2a6509e8c840..e967c49609ef 100644 --- a/arch/x86/kernel/apic/ipi.c +++ b/arch/x86/kernel/apic/ipi.c @@ -239,7 +239,11 @@ void default_send_IPI_all(int vector) =20 void default_send_IPI_self(int vector) { - __default_send_IPI_shortcut(APIC_DEST_SELF, vector); + if (unlikely(vector =3D=3D NMI_VECTOR)) + apic->send_IPI_mask(cpumask_of(smp_processor_id()), + NMI_VECTOR); + else + __default_send_IPI_shortcut(APIC_DEST_SELF, vector); } =20 #ifdef CONFIG_X86_32 diff --git a/arch/x86/kernel/apic/x2apic_phys.c b/arch/x86/kernel/apic/x2ap= ic_phys.c index 6bde05a86b4e..cf187f1906b2 100644 --- a/arch/x86/kernel/apic/x2apic_phys.c +++ b/arch/x86/kernel/apic/x2apic_phys.c @@ -149,7 +149,11 @@ int x2apic_phys_pkg_id(int initial_apicid, int index_m= sb) =20 void x2apic_send_IPI_self(int vector) { - apic_write(APIC_SELF_IPI, vector); + if (unlikely(vector =3D=3D NMI_VECTOR)) + apic->send_IPI_mask(cpumask_of(smp_processor_id()), + NMI_VECTOR); + else + apic_write(APIC_SELF_IPI, vector); } =20 static struct apic apic_x2apic_phys __ro_after_init =3D { diff --git a/arch/x86/kernel/nmi_selftest.c b/arch/x86/kernel/nmi_selftest.c index a1a96df3dff1..f4b813821208 100644 --- a/arch/x86/kernel/nmi_selftest.c +++ b/arch/x86/kernel/nmi_selftest.c @@ -105,6 +105,36 @@ static void __init local_ipi(void) test_nmi_ipi(to_cpumask(nmi_ipi_mask)); } =20 +static void __init self_nmi_test(void) +{ + unsigned long timeout; + + cpumask_clear(to_cpumask(nmi_ipi_mask)); + cpumask_set_cpu(smp_processor_id(), to_cpumask(nmi_ipi_mask)); + + if (register_nmi_handler(NMI_LOCAL, test_nmi_ipi_callback, + NMI_FLAG_FIRST, "nmi_selftest", __initdata)) { + nmi_fail =3D FAILURE; + return; + } + + /* sync above data before sending NMI */ + wmb(); + + apic->send_IPI_self(NMI_VECTOR); + + /* Don't wait longer than a second */ + timeout =3D USEC_PER_SEC; + while (!cpumask_empty(to_cpumask(nmi_ipi_mask)) && --timeout) + udelay(1); + + /* What happens if we timeout, do we still unregister?? */ + unregister_nmi_handler(NMI_LOCAL, "nmi_selftest"); + + if (!timeout) + nmi_fail =3D TIMEOUT; +} + static void __init reset_nmi(void) { nmi_fail =3D 0; @@ -157,6 +187,8 @@ void __init nmi_selftest(void) print_testname("local IPI"); dotest(local_ipi, SUCCESS); printk(KERN_CONT "\n"); + print_testname("Self NMI IPI"); + dotest(self_nmi_test, SUCCESS); =20 cleanup_nmi_testsuite(); =20 --=20 2.34.1