linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Mihai Carabas <mihai.carabas@oracle.com>
To: linux-kernel@vger.kernel.org
Cc: bp@alien8.de, ashok.raj@intel.com, boris.ostrovsky@oracle.com,
	konrad.wilk@oracle.com, patrick.colp@oracle.com,
	kanth.ghatraju@oracle.com, Jon.Grimm@amd.com,
	Thomas.Lendacky@amd.com, mihai.carabas@oracle.com
Subject: [PATCH] x86/microcode: Update microcode for all cores in parallel
Date: Thu, 22 Aug 2019 23:43:47 +0300	[thread overview]
Message-ID: <1566506627-16536-2-git-send-email-mihai.carabas@oracle.com> (raw)
In-Reply-To: <1566506627-16536-1-git-send-email-mihai.carabas@oracle.com>

From: Ashok Raj <ashok.raj@intel.com>

Microcode update was changed to be serialized due to restrictions after
Spectre days. Updating serially on a large multi-socket system can be
painful since we do this one CPU at a time. Cloud customers have expressed
discontent as services disappear for a prolonged time. The restriction is
that only one core goes through the update while other cores are quiesced.
The update is now done only on the first thread of each core while other
siblings simply wait for this to complete.

Signed-off-by: Ashok Raj <ashok.raj@intel.com>
Signed-off-by: Mihai Carabas <mihai.carabas@oracle.com>
---
 arch/x86/kernel/cpu/microcode/core.c  | 44 ++++++++++++++++++++++++-----------
 arch/x86/kernel/cpu/microcode/intel.c | 14 ++++-------
 2 files changed, 36 insertions(+), 22 deletions(-)

diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
index cb0fdca..577b223 100644
--- a/arch/x86/kernel/cpu/microcode/core.c
+++ b/arch/x86/kernel/cpu/microcode/core.c
@@ -63,11 +63,6 @@
  */
 static DEFINE_MUTEX(microcode_mutex);
 
-/*
- * Serialize late loading so that CPUs get updated one-by-one.
- */
-static DEFINE_RAW_SPINLOCK(update_lock);
-
 struct ucode_cpu_info		ucode_cpu_info[NR_CPUS];
 
 struct cpu_info_ctx {
@@ -566,9 +561,23 @@ static int __reload_late(void *info)
 	if (__wait_for_cpus(&late_cpus_in, NSEC_PER_SEC))
 		return -1;
 
-	raw_spin_lock(&update_lock);
-	apply_microcode_local(&err);
-	raw_spin_unlock(&update_lock);
+	/*
+	 * Update just on the first CPU in the core. Other siblings
+	 * get the update automatically according to Intel SDM 9.11.6.3
+	 * Update in a System Supporting Intel Hyper-Threading Technology
+	 * Intel Hyper-Threading Technology has implications on the loading of the
+	 * microcode update. The update must be loaded for each core in a physical
+	 * processor. Thus, for a processor supporting Intel Hyper-Threading
+	 * Technology, only one logical processor per core is required to load the
+	 * microcode update. Each individual logical processor can independently
+	 * load the update. However, MP initialization must provide some mechanism
+	 * (e.g. a software semaphore) to force serialization of microcode update
+	 * loads and to prevent simultaneous load attempts to the same core.
+	 */
+	if (cpumask_first(topology_sibling_cpumask(cpu)) == cpu)
+		apply_microcode_local(&err);
+	else
+		goto wait_for_siblings;
 
 	/* siblings return UCODE_OK because their engine got updated already */
 	if (err > UCODE_NFOUND) {
@@ -578,15 +587,24 @@ static int __reload_late(void *info)
 		ret = 1;
 	}
 
+wait_for_siblings:
 	/*
-	 * Increase the wait timeout to a safe value here since we're
-	 * serializing the microcode update and that could take a while on a
-	 * large number of CPUs. And that is fine as the *actual* timeout will
-	 * be determined by the last CPU finished updating and thus cut short.
+	 * Since we are doing all cores in parallel, and the other
+	 * sibling threads just do a rev update, there is no need to
+	 * increase the timeout
 	 */
-	if (__wait_for_cpus(&late_cpus_out, NSEC_PER_SEC * num_online_cpus()))
+	if (__wait_for_cpus(&late_cpus_out, NSEC_PER_SEC))
 		panic("Timeout during microcode update!\n");
 
+	/*
+	 * At least one thread has completed update in each core.
+	 * For others, simply call the update to make sure the
+	 * per-cpu cpuinfo can be updated with right microcode
+	 * revision.
+	 */
+	 if (cpumask_first(topology_sibling_cpumask(cpu)) != cpu)
+		apply_microcode_local(&err);
+
 	return ret;
 }
 
diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c
index ce799cf..884d02d 100644
--- a/arch/x86/kernel/cpu/microcode/intel.c
+++ b/arch/x86/kernel/cpu/microcode/intel.c
@@ -793,7 +793,6 @@ static enum ucode_state apply_microcode_intel(int cpu)
 	struct cpuinfo_x86 *c = &cpu_data(cpu);
 	struct microcode_intel *mc;
 	enum ucode_state ret;
-	static int prev_rev;
 	u32 rev;
 
 	/* We should bind the task to the CPU */
@@ -836,14 +835,11 @@ static enum ucode_state apply_microcode_intel(int cpu)
 		return UCODE_ERROR;
 	}
 
-	if (rev != prev_rev) {
-		pr_info("updated to revision 0x%x, date = %04x-%02x-%02x\n",
-			rev,
-			mc->hdr.date & 0xffff,
-			mc->hdr.date >> 24,
-			(mc->hdr.date >> 16) & 0xff);
-		prev_rev = rev;
-	}
+	pr_info_once("updated to revision 0x%x, date = %04x-%02x-%02x\n",
+		rev,
+		mc->hdr.date & 0xffff,
+		mc->hdr.date >> 24,
+		(mc->hdr.date >> 16) & 0xff);
 
 	ret = UCODE_UPDATED;
 
-- 
1.8.3.1


  reply	other threads:[~2019-08-22 21:11 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-22 20:43 [PATCH] Parallel microcode update in Linux Mihai Carabas
2019-08-22 20:43 ` Mihai Carabas [this message]
2019-08-24  8:51   ` [PATCH] x86/microcode: Update microcode for all cores in parallel Borislav Petkov
2019-08-24  8:53     ` [PATCH 1/2] x86/microcode: Update late microcode " Borislav Petkov
2019-08-26 12:53       ` Boris Ostrovsky
2019-08-26 13:03         ` Borislav Petkov
2019-08-26 20:32         ` Raj, Ashok
2019-08-27 19:43           ` Boris Ostrovsky
2019-08-27 21:24             ` Boris Ostrovsky
2019-08-28 19:16               ` Borislav Petkov
2019-08-26 20:23       ` Raj, Ashok
2019-08-27 12:25         ` Borislav Petkov
2019-08-28  0:56           ` Raj, Ashok
2019-08-28 19:13             ` Borislav Petkov
2019-08-28 19:45               ` Raj, Ashok
2019-08-24  8:53     ` [PATCH 2/2] x86/microcode/intel: Issue the revision updated message only on the BSP Borislav Petkov
2019-08-26 13:34       ` Boris Ostrovsky
2019-08-26 13:45         ` Borislav Petkov
2019-10-01 17:43       ` [tip: x86/microcode] " tip-bot2 for Borislav Petkov
2019-10-01 17:43   ` [tip: x86/microcode] x86/microcode: Update late microcode in parallel tip-bot2 for Ashok Raj
2019-09-01 17:25 ` [PATCH] Parallel microcode update in Linux Pavel Machek
2019-09-02  7:27   ` Mihai Carabas
2019-09-02  7:39     ` Pavel Machek
2019-09-02 11:10       ` Mihai Carabas

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=1566506627-16536-2-git-send-email-mihai.carabas@oracle.com \
    --to=mihai.carabas@oracle.com \
    --cc=Jon.Grimm@amd.com \
    --cc=Thomas.Lendacky@amd.com \
    --cc=ashok.raj@intel.com \
    --cc=boris.ostrovsky@oracle.com \
    --cc=bp@alien8.de \
    --cc=kanth.ghatraju@oracle.com \
    --cc=konrad.wilk@oracle.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=patrick.colp@oracle.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).