All of lore.kernel.org
 help / color / mirror / Atom feed
From: "tip-bot2 for Thomas Gleixner" <tip-bot2@linutronix.de>
To: linux-tip-commits@vger.kernel.org
Cc: Thomas Gleixner <tglx@linutronix.de>,
	"Borislav Petkov (AMD)" <bp@alien8.de>,
	x86@kernel.org, linux-kernel@vger.kernel.org
Subject: [tip: x86/microcode] x86/microcode: Handle "nosmt" correctly
Date: Fri, 20 Oct 2023 11:37:51 -0000	[thread overview]
Message-ID: <169780187198.3135.3109001374595114314.tip-bot2@tip-bot2> (raw)
In-Reply-To: <20231002115903.087472735@linutronix.de>

The following commit has been merged into the x86/microcode branch of tip:

Commit-ID:     00627f647ad560222dd9475c194e5bcfd3c6cd30
Gitweb:        https://git.kernel.org/tip/00627f647ad560222dd9475c194e5bcfd3c6cd30
Author:        Thomas Gleixner <tglx@linutronix.de>
AuthorDate:    Mon, 02 Oct 2023 13:59:56 +02:00
Committer:     Borislav Petkov (AMD) <bp@alien8.de>
CommitterDate: Thu, 19 Oct 2023 15:54:42 +02:00

x86/microcode: Handle "nosmt" correctly

On CPUs where microcode loading is not NMI-safe the SMT siblings which
are parked in one of the play_dead() variants still react to NMIs.

So if an NMI hits while the primary thread updates the microcode the
resulting behaviour is undefined. The default play_dead() implementation on
modern CPUs is using MWAIT which is not guaranteed to be safe against
a microcode update which affects MWAIT.

Take the cpus_booted_once_mask into account to detect this case and
refuse to load late if the vendor specific driver does not advertise
that late loading is NMI safe.

AMD stated that this is safe, so mark the AMD driver accordingly.

This requirement will be partially lifted in later changes.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Link: https://lore.kernel.org/r/20231002115903.087472735@linutronix.de
---
 arch/x86/Kconfig                         |  2 +-
 arch/x86/kernel/cpu/microcode/amd.c      |  9 ++--
 arch/x86/kernel/cpu/microcode/core.c     | 51 ++++++++++++++---------
 arch/x86/kernel/cpu/microcode/internal.h | 13 ++----
 4 files changed, 44 insertions(+), 31 deletions(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 011cb7f..db75120 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1320,7 +1320,7 @@ config MICROCODE_INITRD32
 config MICROCODE_LATE_LOADING
 	bool "Late microcode loading (DANGEROUS)"
 	default n
-	depends on MICROCODE
+	depends on MICROCODE && SMP
 	help
 	  Loading microcode late, when the system is up and executing instructions
 	  is a tricky business and should be avoided if possible. Just the sequence
diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c
index 99aa5a8..102aebc 100644
--- a/arch/x86/kernel/cpu/microcode/amd.c
+++ b/arch/x86/kernel/cpu/microcode/amd.c
@@ -917,10 +917,11 @@ static void microcode_fini_cpu_amd(int cpu)
 }
 
 static struct microcode_ops microcode_amd_ops = {
-	.request_microcode_fw             = request_microcode_amd,
-	.collect_cpu_info                 = collect_cpu_info_amd,
-	.apply_microcode                  = apply_microcode_amd,
-	.microcode_fini_cpu               = microcode_fini_cpu_amd,
+	.request_microcode_fw	= request_microcode_amd,
+	.collect_cpu_info	= collect_cpu_info_amd,
+	.apply_microcode	= apply_microcode_amd,
+	.microcode_fini_cpu	= microcode_fini_cpu_amd,
+	.nmi_safe		= true,
 };
 
 struct microcode_ops * __init init_amd_microcode(void)
diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
index e306fee..7af1b60 100644
--- a/arch/x86/kernel/cpu/microcode/core.c
+++ b/arch/x86/kernel/cpu/microcode/core.c
@@ -254,23 +254,6 @@ static struct platform_device	*microcode_pdev;
  */
 #define SPINUNIT 100 /* 100 nsec */
 
-static int check_online_cpus(void)
-{
-	unsigned int cpu;
-
-	/*
-	 * Make sure all CPUs are online.  It's fine for SMT to be disabled if
-	 * all the primary threads are still online.
-	 */
-	for_each_present_cpu(cpu) {
-		if (topology_is_primary_thread(cpu) && !cpu_online(cpu)) {
-			pr_err("Not all CPUs online, aborting microcode update.\n");
-			return -EINVAL;
-		}
-	}
-
-	return 0;
-}
 
 static atomic_t late_cpus_in;
 static atomic_t late_cpus_out;
@@ -387,6 +370,35 @@ static int microcode_reload_late(void)
 	return ret;
 }
 
+/*
+ *  Ensure that all required CPUs which are present and have been booted
+ *  once are online.
+ *
+ *    To pass this check, all primary threads must be online.
+ *
+ *    If the microcode load is not safe against NMI then all SMT threads
+ *    must be online as well because they still react to NMIs when they are
+ *    soft-offlined and parked in one of the play_dead() variants. So if a
+ *    NMI hits while the primary thread updates the microcode the resulting
+ *    behaviour is undefined. The default play_dead() implementation on
+ *    modern CPUs uses MWAIT, which is also not guaranteed to be safe
+ *    against a microcode update which affects MWAIT.
+ */
+static bool ensure_cpus_are_online(void)
+{
+	unsigned int cpu;
+
+	for_each_cpu_and(cpu, cpu_present_mask, &cpus_booted_once_mask) {
+		if (!cpu_online(cpu)) {
+			if (topology_is_primary_thread(cpu) || !microcode_ops->nmi_safe) {
+				pr_err("CPU %u not online\n", cpu);
+				return false;
+			}
+		}
+	}
+	return true;
+}
+
 static ssize_t reload_store(struct device *dev,
 			    struct device_attribute *attr,
 			    const char *buf, size_t size)
@@ -402,9 +414,10 @@ static ssize_t reload_store(struct device *dev,
 
 	cpus_read_lock();
 
-	ret = check_online_cpus();
-	if (ret)
+	if (!ensure_cpus_are_online()) {
+		ret = -EBUSY;
 		goto put;
+	}
 
 	tmp_ret = microcode_ops->request_microcode_fw(bsp, &microcode_pdev->dev);
 	if (tmp_ret != UCODE_NEW)
diff --git a/arch/x86/kernel/cpu/microcode/internal.h b/arch/x86/kernel/cpu/microcode/internal.h
index 4bef216..07aa5f8 100644
--- a/arch/x86/kernel/cpu/microcode/internal.h
+++ b/arch/x86/kernel/cpu/microcode/internal.h
@@ -20,18 +20,17 @@ enum ucode_state {
 
 struct microcode_ops {
 	enum ucode_state (*request_microcode_fw)(int cpu, struct device *dev);
-
 	void (*microcode_fini_cpu)(int cpu);
 
 	/*
-	 * The generic 'microcode_core' part guarantees that
-	 * the callbacks below run on a target cpu when they
-	 * are being called.
+	 * The generic 'microcode_core' part guarantees that the callbacks
+	 * below run on a target CPU when they are being called.
 	 * See also the "Synchronization" section in microcode_core.c.
 	 */
-	enum ucode_state (*apply_microcode)(int cpu);
-	int (*collect_cpu_info)(int cpu, struct cpu_signature *csig);
-	void (*finalize_late_load)(int result);
+	enum ucode_state	(*apply_microcode)(int cpu);
+	int			(*collect_cpu_info)(int cpu, struct cpu_signature *csig);
+	void			(*finalize_late_load)(int result);
+	unsigned int		nmi_safe	: 1;
 };
 
 extern struct ucode_cpu_info ucode_cpu_info[];

  parent reply	other threads:[~2023-10-20 11:39 UTC|newest]

Thread overview: 102+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-10-02 11:59 [patch V4 00/30] x86/microcode: Cleanup and late loading enhancements Thomas Gleixner
2023-10-02 11:59 ` [patch V4 01/30] x86/microcode/32: Move early loading after paging enable Thomas Gleixner
2023-10-02 11:59 ` [patch V4 02/30] x86/boot/32: Disable stackprotector and tracing for mk_early_pgtbl_32() Thomas Gleixner
2023-10-09 12:29   ` [tip: x86/microcode] " tip-bot2 for Thomas Gleixner
2023-10-20 11:38   ` tip-bot2 for Thomas Gleixner
2023-10-02 11:59 ` [patch V4 03/30] x86/microcode/intel: Rip out mixed stepping support for Intel CPUs Thomas Gleixner
2023-10-09 12:29   ` [tip: x86/microcode] " tip-bot2 for Ashok Raj
2023-10-02 11:59 ` [patch V4 04/30] x86/microcode/intel: Simplify scan_microcode() Thomas Gleixner
2023-10-09 12:29   ` [tip: x86/microcode] " tip-bot2 for Thomas Gleixner
2023-10-20 11:38   ` tip-bot2 for Thomas Gleixner
2023-10-02 11:59 ` [patch V4 05/30] x86/microcode/intel: Simplify and rename generic_load_microcode() Thomas Gleixner
2023-10-09 12:29   ` [tip: x86/microcode] " tip-bot2 for Thomas Gleixner
2023-10-20 11:38   ` tip-bot2 for Thomas Gleixner
2023-10-02 11:59 ` [patch V4 06/30] x86/microcode/intel: Cleanup code further Thomas Gleixner
2023-10-09 12:29   ` [tip: x86/microcode] " tip-bot2 for Thomas Gleixner
2023-10-20 11:38   ` tip-bot2 for Thomas Gleixner
2023-10-02 11:59 ` [patch V4 07/30] x86/microcode/intel: Simplify early loading Thomas Gleixner
2023-10-09 12:29   ` [tip: x86/microcode] " tip-bot2 for Thomas Gleixner
2023-10-02 11:59 ` [patch V4 08/30] x86/microcode/intel: Save the microcode only after a successful late-load Thomas Gleixner
2023-10-09 12:29   ` [tip: x86/microcode] " tip-bot2 for Thomas Gleixner
2023-10-20 11:37   ` tip-bot2 for Thomas Gleixner
2023-10-24 13:21   ` tip-bot2 for Thomas Gleixner
2023-10-02 11:59 ` [patch V4 09/30] x86/microcode/intel: Switch to kvmalloc() Thomas Gleixner
2023-10-09 12:29   ` [tip: x86/microcode] " tip-bot2 for Thomas Gleixner
2023-10-20 11:37   ` tip-bot2 for Thomas Gleixner
2023-10-24 13:21   ` tip-bot2 for Thomas Gleixner
2023-10-02 11:59 ` [patch V4 10/30] x86/microcode/intel: Unify microcode apply() functions Thomas Gleixner
2023-10-09 12:29   ` [tip: x86/microcode] " tip-bot2 for Thomas Gleixner
2023-10-02 11:59 ` [patch V4 11/30] x86/microcode/intel: Rework intel_cpu_collect_info() Thomas Gleixner
2023-10-09 12:29   ` [tip: x86/microcode] " tip-bot2 for Thomas Gleixner
2023-10-02 11:59 ` [patch V4 12/30] x86/microcode/intel: Reuse intel_cpu_collect_info() Thomas Gleixner
2023-10-09 12:29   ` [tip: x86/microcode] " tip-bot2 for Thomas Gleixner
2023-10-20 11:37   ` tip-bot2 for Thomas Gleixner
2023-10-24 13:21   ` tip-bot2 for Thomas Gleixner
2023-10-02 11:59 ` [patch V4 13/30] x86/microcode/intel: Rework intel_find_matching_signature() Thomas Gleixner
2023-10-09 12:29   ` [tip: x86/microcode] " tip-bot2 for Thomas Gleixner
2023-10-20 11:37   ` tip-bot2 for Thomas Gleixner
2023-10-24 13:21   ` tip-bot2 for Thomas Gleixner
2023-10-02 11:59 ` [patch V4 14/30] x86/microcode/amd: Read revision from hardware in collect_cpu_info_amd() Thomas Gleixner
2023-10-04  8:32   ` Borislav Petkov
2023-10-02 11:59 ` [patch V4 15/30] x86/microcode: Remove pointless apply() invocation Thomas Gleixner
2023-10-06 13:26   ` Borislav Petkov
2023-10-09 12:29   ` [tip: x86/microcode] " tip-bot2 for Thomas Gleixner
2023-10-02 11:59 ` [patch V4 16/30] x86/microcode: Get rid of the schedule work indirection Thomas Gleixner
2023-10-09 12:29   ` [tip: x86/microcode] " tip-bot2 for Thomas Gleixner
2023-10-02 11:59 ` [patch V4 17/30] x86/microcode: Clean up mc_cpu_down_prep() Thomas Gleixner
2023-10-09 12:29   ` [tip: x86/microcode] " tip-bot2 for Thomas Gleixner
2023-10-20 11:37   ` tip-bot2 for Thomas Gleixner
2023-10-24 13:20   ` tip-bot2 for Thomas Gleixner
2023-10-02 11:59 ` [patch V4 18/30] x86/microcode: Handle "nosmt" correctly Thomas Gleixner
2023-10-09 12:29   ` [tip: x86/microcode] " tip-bot2 for Thomas Gleixner
2023-10-20 11:37   ` tip-bot2 for Thomas Gleixner [this message]
2023-10-24 13:20   ` tip-bot2 for Thomas Gleixner
2023-10-02 11:59 ` [patch V4 19/30] x86/microcode: Clarify the late load logic Thomas Gleixner
2023-10-09 12:29   ` [tip: x86/microcode] " tip-bot2 for Thomas Gleixner
2023-10-20 11:37   ` tip-bot2 for Thomas Gleixner
2023-10-24 13:20   ` tip-bot2 for Thomas Gleixner
2023-10-02 11:59 ` [patch V4 20/30] x86/microcode: Sanitize __wait_for_cpus() Thomas Gleixner
2023-10-09 12:29   ` [tip: x86/microcode] " tip-bot2 for Thomas Gleixner
2023-10-20 11:37   ` tip-bot2 for Thomas Gleixner
2023-10-24 13:20   ` tip-bot2 for Thomas Gleixner
2023-10-02 12:00 ` [patch V4 21/30] x86/microcode: Add per CPU result state Thomas Gleixner
2023-10-09 12:29   ` [tip: x86/microcode] " tip-bot2 for Thomas Gleixner
2023-10-02 12:00 ` [patch V4 22/30] x86/microcode: Add per CPU control field Thomas Gleixner
2023-10-09 12:29   ` [tip: x86/microcode] " tip-bot2 for Thomas Gleixner
2023-10-20 11:37   ` tip-bot2 for Thomas Gleixner
2023-10-24 13:20   ` tip-bot2 for Thomas Gleixner
2023-10-02 12:00 ` [patch V4 23/30] x86/microcode: Provide new control functions Thomas Gleixner
2023-10-09 12:29   ` [tip: x86/microcode] " tip-bot2 for Thomas Gleixner
2023-10-20 11:37   ` tip-bot2 for Thomas Gleixner
2023-10-24 13:20   ` tip-bot2 for Thomas Gleixner
2023-10-02 12:00 ` [patch V4 24/30] x86/microcode: Replace the all in one rendevouz handler Thomas Gleixner
2023-10-09 12:29   ` [tip: x86/microcode] x86/microcode: Replace the all-in-one rendevous handler tip-bot2 for Thomas Gleixner
2023-10-20 11:37   ` tip-bot2 for Thomas Gleixner
2023-10-24 13:20   ` tip-bot2 for Thomas Gleixner
2023-10-02 12:00 ` [patch V4 25/30] x86/microcode: Rendezvous and load in NMI Thomas Gleixner
2023-10-09 12:29   ` [tip: x86/microcode] " tip-bot2 for Thomas Gleixner
2023-10-20 11:37   ` tip-bot2 for Thomas Gleixner
2023-10-24 13:20   ` tip-bot2 for Thomas Gleixner
2023-10-02 12:00 ` [patch V4 26/30] x86/microcode: Protect against instrumentation Thomas Gleixner
2023-10-09 12:29   ` [tip: x86/microcode] " tip-bot2 for Thomas Gleixner
2023-10-20 11:37   ` tip-bot2 for Thomas Gleixner
2023-10-24 13:20   ` tip-bot2 for Thomas Gleixner
2023-10-02 12:00 ` [patch V4 27/30] x86/apic: Provide apic_force_nmi_on_cpu() Thomas Gleixner
2023-10-09 12:29   ` [tip: x86/microcode] " tip-bot2 for Thomas Gleixner
2023-10-20 11:37   ` tip-bot2 for Thomas Gleixner
2023-10-24 13:20   ` tip-bot2 for Thomas Gleixner
2023-10-02 12:00 ` [patch V4 28/30] x86/microcode: Handle "offline" CPUs correctly Thomas Gleixner
2023-10-09 12:29   ` [tip: x86/microcode] " tip-bot2 for Thomas Gleixner
2023-10-20 11:37   ` tip-bot2 for Thomas Gleixner
2023-10-24 13:20   ` tip-bot2 for Thomas Gleixner
2023-10-02 12:00 ` [patch V4 29/30] x86/microcode: Prepare for minimal revision check Thomas Gleixner
2023-10-09 12:29   ` [tip: x86/microcode] " tip-bot2 for Thomas Gleixner
2023-10-02 12:00 ` [patch V4 30/30] x86/microcode/intel: Add a minimum required revision for late-loads Thomas Gleixner
2023-10-09 12:29   ` [tip: x86/microcode] x86/microcode/intel: Add a minimum required revision for late loading tip-bot2 for Ashok Raj
2023-10-20 11:37   ` tip-bot2 for Ashok Raj
2023-10-24 13:20   ` tip-bot2 for Ashok Raj
2023-10-08  8:54 ` [patch V4 00/30] x86/microcode: Cleanup and late loading enhancements Qiuxu Zhuo
2023-10-08 13:08   ` Borislav Petkov
2023-10-09  5:03     ` Zhuo, Qiuxu
2023-10-10  8:00     ` Zhuo, Qiuxu
2023-10-10  8:11       ` Borislav Petkov

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=169780187198.3135.3109001374595114314.tip-bot2@tip-bot2 \
    --to=tip-bot2@linutronix.de \
    --cc=bp@alien8.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-tip-commits@vger.kernel.org \
    --cc=tglx@linutronix.de \
    --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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.