public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Thomas Gleixner <tglx@linutronix.de>
To: LKML <linux-kernel@vger.kernel.org>
Cc: x86@kernel.org, Nadav Amit <namit@vmware.com>,
	Ricardo Neri <ricardo.neri-calderon@linux.intel.com>,
	Stephane Eranian <eranian@google.com>,
	Feng Tang <feng.tang@intel.com>
Subject: [patch 15/18] x86/apic: Add static key to Control IPI shorthands
Date: Wed, 03 Jul 2019 12:54:46 +0200	[thread overview]
Message-ID: <20190703105916.951339398@linutronix.de> (raw)
In-Reply-To: 20190703105431.096822793@linutronix.de

The IPI shorthand functionality delivers IPI/NMI broadcasts to all CPUs in
the system. This can have similar side effects as the MCE broadcasting when
CPUs are waiting in the BIOS or are offlined.

The kernel tracks already the state of offlined CPUs whether they have been
brought up at least once so that the CR4 MCE bit is set to make sure that
MCE broadcasts can't brick the machine.

Utilize that information and compare it to the cpu_present_mask. If all
present CPUs have been brought up at least once then the broadcast side
effect is mitigated by disabling regular interrupt/IPI delivery in the APIC
itself and by the cpu_ignore_nmi check at the begin of the NMI handler.

Use a static key to switch between broadcasting via shorthands or sending
the IPI/NMI one by one.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/include/asm/apic.h  |    2 ++
 arch/x86/kernel/apic/ipi.c   |   24 +++++++++++++++++++++++-
 arch/x86/kernel/apic/local.h |    6 ++++++
 arch/x86/kernel/cpu/common.c |    2 ++
 4 files changed, 33 insertions(+), 1 deletion(-)

--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -505,8 +505,10 @@ extern int default_check_phys_apicid_pre
 
 #ifdef CONFIG_SMP
 bool apic_id_is_primary_thread(unsigned int id);
+void apic_smt_update(void);
 #else
 static inline bool apic_id_is_primary_thread(unsigned int id) { return false; }
+static inline void apic_smt_update(void) { }
 #endif
 
 extern void irq_enter(void);
--- a/arch/x86/kernel/apic/ipi.c
+++ b/arch/x86/kernel/apic/ipi.c
@@ -5,6 +5,8 @@
 
 #include "local.h"
 
+DEFINE_STATIC_KEY_FALSE(apic_use_ipi_shorthand);
+
 #ifdef CONFIG_SMP
 #ifdef CONFIG_HOTPLUG_CPU
 #define DEFAULT_SEND_IPI	(1)
@@ -28,7 +30,27 @@ static int __init print_ipi_mode(void)
 	return 0;
 }
 late_initcall(print_ipi_mode);
-#endif
+
+void apic_smt_update(void)
+{
+	/*
+	 * Do not switch to broadcast mode if:
+	 * - Disabled on the command line
+	 * - Only a single CPU is online
+	 * - Not all present CPUs have been at least booted once
+	 *
+	 * The latter is important as the local APIC might be in some
+	 * random state and a broadcast might cause havoc. That's
+	 * especially true for NMI broadcasting.
+	 */
+	if (apic_ipi_shorthand_off || num_online_cpus() == 1 ||
+	    !cpumask_equal(cpu_present_mask, &cpus_booted_once_mask)) {
+		static_branch_disable(&apic_use_ipi_shorthand);
+	} else {
+		static_branch_enable(&apic_use_ipi_shorthand);
+	}
+}
+#endif /* CONFIG_SMP */
 
 static inline int __prepare_ICR2(unsigned int mask)
 {
--- a/arch/x86/kernel/apic/local.h
+++ b/arch/x86/kernel/apic/local.h
@@ -7,6 +7,9 @@
  * (c) 1998-99, 2000 Ingo Molnar <mingo@redhat.com>
  * (c) 2002,2003 Andi Kleen, SuSE Labs.
  */
+
+#include <linux/jump_label.h>
+
 #include <asm/apic.h>
 
 /* APIC flat 64 */
@@ -22,6 +25,9 @@ int x2apic_phys_pkg_id(int initial_apici
 void x2apic_send_IPI_self(int vector);
 
 /* IPI */
+
+DECLARE_STATIC_KEY_FALSE(apic_use_ipi_shorthand);
+
 static inline unsigned int __prepare_ICR(unsigned int shortcut, int vector,
 					 unsigned int dest)
 {
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -1888,4 +1888,6 @@ void arch_smt_update(void)
 {
 	/* Handle the speculative execution misfeatures */
 	cpu_bugs_smt_update();
+	/* Check whether IPI broadcasting can be enabled */
+	apic_smt_update();
 }



  parent reply	other threads:[~2019-07-03 11:04 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-07-03 10:54 [patch 00/18] x86/apic: Support for IPI shorthands Thomas Gleixner
2019-07-03 10:54 ` [patch 01/18] x86/apic: Invoke perf_events_lapic_init() after enabling APIC Thomas Gleixner
2019-07-03 10:54 ` [patch 02/18] x86/apic: Soft disable APIC before initializing it Thomas Gleixner
2019-07-03 10:54 ` [patch 03/18] x86/apic: Make apic_pending_intr_clear() more robust Thomas Gleixner
2019-07-03 10:54 ` [patch 04/18] x86/apic: Move IPI inlines into ipi.c Thomas Gleixner
2019-07-03 10:54 ` [patch 05/18] x86/apic: Cleanup the include maze Thomas Gleixner
2019-07-03 10:54 ` [patch 06/18] x86/apic: Move ipi header into apic directory Thomas Gleixner
2019-07-03 10:54 ` [patch 07/18] x86/apic: Move apic_flat_64 " Thomas Gleixner
2019-07-03 10:54 ` [patch 08/18] x86/apic: Consolidate the apic local headers Thomas Gleixner
2019-07-03 10:54 ` [patch 09/18] smp/hotplug: Track booted once CPUs in a cpumask Thomas Gleixner
2019-07-03 10:54 ` [patch 10/18] x86/cpu: Move arch_smt_update() to a neutral place Thomas Gleixner
2019-07-03 10:54 ` [patch 11/18] x86/hotplug: Silence APIC and NMI when CPU is dead Thomas Gleixner
2019-07-03 10:54 ` [patch 12/18] x86/apic: Remove dest argument from __default_send_IPI_shortcut() Thomas Gleixner
2019-07-03 10:54 ` [patch 13/18] x86/apic: Add NMI_VECTOR wait to IPI shorthand Thomas Gleixner
2019-07-03 10:54 ` [patch 14/18] x86/apic: Move no_ipi_broadcast() out of 32bit Thomas Gleixner
2019-07-03 10:54 ` Thomas Gleixner [this message]
2019-07-03 10:54 ` [patch 16/18] x86/apic: Convert 32bit to IPI shorthand static key Thomas Gleixner
2019-07-03 18:06   ` Nadav Amit
2019-07-03 20:34     ` Thomas Gleixner
2019-07-03 21:14       ` Nadav Amit
2019-07-03 21:30         ` Thomas Gleixner
2019-07-03 10:54 ` [patch 17/18] x86/apic/flat64: Add conditional IPI shorthands support Thomas Gleixner
2019-07-03 10:54 ` [patch 18/18] x86/apic/x2apic: " Thomas Gleixner

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=20190703105916.951339398@linutronix.de \
    --to=tglx@linutronix.de \
    --cc=eranian@google.com \
    --cc=feng.tang@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=namit@vmware.com \
    --cc=ricardo.neri-calderon@linux.intel.com \
    --cc=x86@kernel.org \
    /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