linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: tip-bot for Thomas Gleixner <tipbot@zytor.com>
To: linux-tip-commits@vger.kernel.org
Cc: tglx@linutronix.de, linux-kernel@vger.kernel.org,
	mingo@kernel.org, hpa@zytor.com, peterz@infradead.org
Subject: [tip:x86/apic] x86/hotplug: Silence APIC and NMI when CPU is dead
Date: Thu, 25 Jul 2019 07:29:02 -0700	[thread overview]
Message-ID: <tip-60dcaad5736faff5a6b1abba5a292499f57197fe@git.kernel.org> (raw)
In-Reply-To: <alpine.DEB.2.21.1907241723290.1791@nanos.tec.linutronix.de>

Commit-ID:  60dcaad5736faff5a6b1abba5a292499f57197fe
Gitweb:     https://git.kernel.org/tip/60dcaad5736faff5a6b1abba5a292499f57197fe
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Wed, 24 Jul 2019 17:25:52 +0200
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Thu, 25 Jul 2019 16:11:59 +0200

x86/hotplug: Silence APIC and NMI when CPU is dead

In order to support IPI/NMI broadcasting via the shorthand mechanism side
effects of shorthands need to be mitigated:

 Shorthand IPIs and NMIs hit all CPUs including unplugged CPUs

Neither of those can be handled on unplugged CPUs for obvious reasons.

It would be trivial to just fully disable the APIC via the enable bit in
MSR_APICBASE. But that's not possible because clearing that bit on systems
based on the 3 wire APIC bus would require a hardware reset to bring it
back as the APIC would lose track of bus arbitration. On systems with FSB
delivery APICBASE could be disabled, but it has to be guaranteed that no
interrupt is sent to the APIC while in that state and it's not clear from
the SDM whether it still responds to INIT/SIPI messages.

Therefore stay on the safe side and switch the APIC into soft disabled mode
so it won't deliver any regular vector to the CPU.

NMIs are still propagated to the 'dead' CPUs. To mitigate that add a check
for the CPU being offline on early nmi entry and if so bail.

Note, this cannot use the stop/restart_nmi() magic which is used in the
alternatives code. A dead CPU cannot invoke nmi_enter() or anything else
due to RCU and other reasons.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/alpine.DEB.2.21.1907241723290.1791@nanos.tec.linutronix.de

---
 arch/x86/include/asm/apic.h |  1 +
 arch/x86/kernel/apic/apic.c | 35 ++++++++++++++++++++++++-----------
 arch/x86/kernel/nmi.c       |  3 +++
 arch/x86/kernel/smpboot.c   |  7 ++++++-
 4 files changed, 34 insertions(+), 12 deletions(-)

diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index f53eda2c986b..cae7e0d02476 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -136,6 +136,7 @@ extern int lapic_get_maxlvt(void);
 extern void clear_local_APIC(void);
 extern void disconnect_bsp_APIC(int virt_wire_setup);
 extern void disable_local_APIC(void);
+extern void apic_soft_disable(void);
 extern void lapic_shutdown(void);
 extern void sync_Arb_IDs(void);
 extern void init_bsp_APIC(void);
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index fe30d1854a4e..831274e3c09f 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -1182,25 +1182,38 @@ void clear_local_APIC(void)
 }
 
 /**
- * disable_local_APIC - clear and disable the local APIC
+ * apic_soft_disable - Clears and software disables the local APIC on hotplug
+ *
+ * Contrary to disable_local_APIC() this does not touch the enable bit in
+ * MSR_IA32_APICBASE. Clearing that bit on systems based on the 3 wire APIC
+ * bus would require a hardware reset as the APIC would lose track of bus
+ * arbitration. On systems with FSB delivery APICBASE could be disabled,
+ * but it has to be guaranteed that no interrupt is sent to the APIC while
+ * in that state and it's not clear from the SDM whether it still responds
+ * to INIT/SIPI messages. Stay on the safe side and use software disable.
  */
-void disable_local_APIC(void)
+void apic_soft_disable(void)
 {
-	unsigned int value;
-
-	/* APIC hasn't been mapped yet */
-	if (!x2apic_mode && !apic_phys)
-		return;
+	u32 value;
 
 	clear_local_APIC();
 
-	/*
-	 * Disable APIC (implies clearing of registers
-	 * for 82489DX!).
-	 */
+	/* Soft disable APIC (implies clearing of registers for 82489DX!). */
 	value = apic_read(APIC_SPIV);
 	value &= ~APIC_SPIV_APIC_ENABLED;
 	apic_write(APIC_SPIV, value);
+}
+
+/**
+ * disable_local_APIC - clear and disable the local APIC
+ */
+void disable_local_APIC(void)
+{
+	/* APIC hasn't been mapped yet */
+	if (!x2apic_mode && !apic_phys)
+		return;
+
+	apic_soft_disable();
 
 #ifdef CONFIG_X86_32
 	/*
diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c
index 4df7705022b9..e676a9916c49 100644
--- a/arch/x86/kernel/nmi.c
+++ b/arch/x86/kernel/nmi.c
@@ -512,6 +512,9 @@ NOKPROBE_SYMBOL(is_debug_stack);
 dotraplinkage notrace void
 do_nmi(struct pt_regs *regs, long error_code)
 {
+	if (IS_ENABLED(CONFIG_SMP) && cpu_is_offline(smp_processor_id()))
+		return;
+
 	if (this_cpu_read(nmi_state) != NMI_NOT_RUNNING) {
 		this_cpu_write(nmi_state, NMI_LATCHED);
 		return;
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index fdbd47ceb84d..c19f8e21b748 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -1596,7 +1596,12 @@ int native_cpu_disable(void)
 	if (ret)
 		return ret;
 
-	clear_local_APIC();
+	/*
+	 * Disable the local APIC. Otherwise IPI broadcasts will reach
+	 * it. It still responds normally to INIT, NMI, SMI, and SIPI
+	 * messages.
+	 */
+	apic_soft_disable();
 	cpu_disable_common();
 
 	return 0;

  reply	other threads:[~2019-07-25 14:29 UTC|newest]

Thread overview: 53+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-07-22 18:47 [patch V3 00/25] x86/apic: Support for IPI shorthands Thomas Gleixner
2019-07-22 18:47 ` [patch V3 01/25] x86/kgbd: Use NMI_VECTOR not APIC_DM_NMI Thomas Gleixner
2019-07-25 14:20   ` [tip:x86/apic] " tip-bot for Thomas Gleixner
2019-07-22 18:47 ` [patch V3 02/25] x86/apic: Invoke perf_events_lapic_init() after enabling APIC Thomas Gleixner
2019-07-25 14:21   ` [tip:x86/apic] " tip-bot for Thomas Gleixner
2019-07-22 18:47 ` [patch V3 03/25] x86/apic: Soft disable APIC before initializing it Thomas Gleixner
2019-07-25 14:22   ` [tip:x86/apic] " tip-bot for Thomas Gleixner
2019-07-22 18:47 ` [patch V3 04/25] x86/apic: Make apic_pending_intr_clear() more robust Thomas Gleixner
2019-07-25 14:22   ` [tip:x86/apic] " tip-bot for Thomas Gleixner
2019-07-22 18:47 ` [patch V3 05/25] x86/apic: Move IPI inlines into ipi.c Thomas Gleixner
2019-07-25 14:23   ` [tip:x86/apic] " tip-bot for Thomas Gleixner
2019-07-22 18:47 ` [patch V3 06/25] x86/apic: Cleanup the include maze Thomas Gleixner
2019-07-25 14:24   ` [tip:x86/apic] " tip-bot for Thomas Gleixner
2019-07-22 18:47 ` [patch V3 07/25] x86/apic: Move ipi header into apic directory Thomas Gleixner
2019-07-25 14:25   ` [tip:x86/apic] " tip-bot for Thomas Gleixner
2019-07-22 18:47 ` [patch V3 08/25] x86/apic: Move apic_flat_64 " Thomas Gleixner
2019-07-25 14:25   ` [tip:x86/apic] " tip-bot for Thomas Gleixner
2019-07-22 18:47 ` [patch V3 09/25] x86/apic: Consolidate the apic local headers Thomas Gleixner
2019-07-25 14:26   ` [tip:x86/apic] " tip-bot for Thomas Gleixner
2019-07-22 18:47 ` [patch V3 10/25] x86/apic/uv: Make x2apic_extra_bits static Thomas Gleixner
2019-07-25 14:27   ` [tip:x86/apic] " tip-bot for Thomas Gleixner
2019-07-22 18:47 ` [patch V3 11/25] smp/hotplug: Track booted once CPUs in a cpumask Thomas Gleixner
2019-07-25 14:10   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
2019-07-22 18:47 ` [patch V3 12/25] x86/cpu: Move arch_smt_update() to a neutral place Thomas Gleixner
2019-07-25 14:28   ` [tip:x86/apic] " tip-bot for Thomas Gleixner
2019-07-22 18:47 ` [patch V3 13/25] x86/hotplug: Silence APIC and NMI when CPU is dead Thomas Gleixner
2019-07-24 15:25   ` [patch V4 " Thomas Gleixner
2019-07-25 14:29     ` tip-bot for Thomas Gleixner [this message]
2019-07-22 18:47 ` [patch V3 14/25] x86/apic: Remove dest argument from __default_send_IPI_shortcut() Thomas Gleixner
2019-07-25 14:29   ` [tip:x86/apic] " tip-bot for Thomas Gleixner
2019-07-22 18:47 ` [patch V3 15/25] x86/apic: Add NMI_VECTOR wait to IPI shorthand Thomas Gleixner
2019-07-25 14:30   ` [tip:x86/apic] " tip-bot for Thomas Gleixner
2019-07-22 18:47 ` [patch V3 16/25] x86/apic: Move no_ipi_broadcast() out of 32bit Thomas Gleixner
2019-07-25 14:31   ` [tip:x86/apic] " tip-bot for Thomas Gleixner
2019-07-22 18:47 ` [patch V3 17/25] x86/apic: Add static key to Control IPI shorthands Thomas Gleixner
2019-07-25 14:31   ` [tip:x86/apic] " tip-bot for Thomas Gleixner
2019-07-22 18:47 ` [patch V3 18/25] x86/apic: Provide and use helper for send_IPI_allbutself() Thomas Gleixner
2019-07-25 14:32   ` [tip:x86/apic] " tip-bot for Thomas Gleixner
2019-07-22 18:47 ` [patch V3 19/25] cpumask: Implement cpumask_or_equal() Thomas Gleixner
2019-07-25 14:10   ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
2019-07-22 18:47 ` [patch V3 20/25] x86/smp: Move smp_function_call implementations into IPI code Thomas Gleixner
2019-07-25 14:33   ` [tip:x86/apic] " tip-bot for Thomas Gleixner
2019-07-22 18:47 ` [patch V3 21/25] x86/smp: Enhance native_send_call_func_ipi() Thomas Gleixner
2019-07-25 14:34   ` [tip:x86/apic] " tip-bot for Thomas Gleixner
2019-07-22 18:47 ` [patch V3 22/25] x86/apic: Remove the shorthand decision logic Thomas Gleixner
2019-07-25 14:34   ` [tip:x86/apic] " tip-bot for Thomas Gleixner
2019-07-22 18:47 ` [patch V3 23/25] x86/apic: Share common IPI helpers Thomas Gleixner
2019-07-25 14:35   ` [tip:x86/apic] " tip-bot for Thomas Gleixner
2019-07-22 18:47 ` [patch V3 24/25] x86/apic/flat64: Remove the IPI shorthand decision logic Thomas Gleixner
2019-07-25 14:36   ` [tip:x86/apic] " tip-bot for Thomas Gleixner
2019-07-22 18:47 ` [patch V3 25/25] x86/apic/x2apic: Implement IPI shorthands support Thomas Gleixner
2019-07-25 14:37   ` [tip:x86/apic] " tip-bot for Thomas Gleixner
2019-07-25 13:17 ` [patch V3 00/25] x86/apic: Support for IPI shorthands Peter Zijlstra

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=tip-60dcaad5736faff5a6b1abba5a292499f57197fe@git.kernel.org \
    --to=tipbot@zytor.com \
    --cc=hpa@zytor.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-tip-commits@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=peterz@infradead.org \
    --cc=tglx@linutronix.de \
    /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).