mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Chang S. Bae" <chang.seok.bae@intel.com>
To: linux-kernel@vger.kernel.org
Cc: x86@kernel.org, tglx@kernel.org, mingo@redhat.com, bp@alien8.de,
	dave.hansen@linux.intel.com, kevin.shu@intel.com,
	chang.seok.bae@intel.com
Subject: [PATCH RFC v1 8/8] x86/microcode/intel: Enable uniform loading
Date: Sat, 12 Sep 2026 00:08:14 +0000	[thread overview]
Message-ID: <20260912000815.997720-9-chang.seok.bae@intel.com> (raw)
In-Reply-To: <20260912000815.997720-1-chang.seok.bae@intel.com>

Uniform scopes are now available for both early- and late-loading paths.
This feature simplifies the loading process by reducing the number of
update triggers.

Ignoring the CPU's uniform scope results in more triggers than necessary.
While this behavior is acceptable, it can increase update latency,
particularly for the late-loading path. Enable the feature.

Certain invalid states, such as incomplete firmware configuration or an
unknown loading scope, can leave the update mechanism unreliable. Detect
those conditions early and disable the loader before any update occurs.

Module, tile, and die scopes are also possible, but currently reserved
for future implementations. Treat them as equivalent to the default
per-core scope.

Signed-off-by: Chang S. Bae <chang.seok.bae@intel.com>
---
 arch/x86/include/asm/microcode.h      |  2 +
 arch/x86/include/asm/msr-index.h      | 10 ++++
 arch/x86/kernel/cpu/microcode/core.c  |  5 ++
 arch/x86/kernel/cpu/microcode/intel.c | 69 +++++++++++++++++++++++++++
 4 files changed, 86 insertions(+)

diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h
index 645e65ac1586..710b79aa03ec 100644
--- a/arch/x86/include/asm/microcode.h
+++ b/arch/x86/include/asm/microcode.h
@@ -21,11 +21,13 @@ void load_ucode_bsp(void);
 void load_ucode_ap(void);
 void microcode_bsp_resume(void);
 bool __init microcode_loader_disabled(void);
+void __init microcode_disable_loader(void);
 #else
 static inline void load_ucode_bsp(void)	{ }
 static inline void load_ucode_ap(void) { }
 static inline void microcode_bsp_resume(void) { }
 static inline bool __init microcode_loader_disabled(void) { return false; }
+static inline bool __init microcode_disable_loader(void) { }
 #endif
 
 extern unsigned long initrd_start_early;
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 3a8e51a0c9e8..6a412371e02f 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -975,7 +975,17 @@
 #define MSR_IA32_UCODE_WRITE		0x00000079
 
 #define MSR_IA32_MCU_ENUMERATION	0x0000007b
+#define MCU_UNIFORM_AVAIL		BIT(0)
+#define MCU_UNIFORM_CONFIG_REQD		BIT(1)
+#define MCU_UNIFORM_CONFIG_COMPLETE	BIT(2)
 #define MCU_STAGING			BIT(4)
+#define MCU_UNIFORM_SCOPE		GENMASK(15, 8)
+#define MCU_UNIFORM_SCOPE_CORE		0x02
+#define MCU_UNIFORM_SCOPE_MODULE	0x03
+#define MCU_UNIFORM_SCOPE_TILE		0x04
+#define MCU_UNIFORM_SCOPE_DIE		0x05
+#define MCU_UNIFORM_SCOPE_PACKAGE	0x80
+#define MCU_UNIFORM_SCOPE_PLATFORM	0xc0
 
 #define MSR_IA32_UCODE_REV		0x0000008b
 
diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
index ed547f2b4601..887ffdc814de 100644
--- a/arch/x86/kernel/cpu/microcode/core.c
+++ b/arch/x86/kernel/cpu/microcode/core.c
@@ -111,6 +111,11 @@ static bool amd_check_current_patch_level(void)
 	return false;
 }
 
+void __init microcode_disable_loader(void)
+{
+	dis_ucode_ldr = true;
+}
+
 bool __init microcode_loader_disabled(void)
 {
 	if (dis_ucode_ldr)
diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c
index 6178bddb7f60..e6c2b693f30b 100644
--- a/arch/x86/kernel/cpu/microcode/intel.c
+++ b/arch/x86/kernel/cpu/microcode/intel.c
@@ -23,6 +23,7 @@
 #include <linux/uio.h>
 #include <linux/io.h>
 #include <linux/mm.h>
+#include <linux/bitfield.h>
 
 #include <asm/cpu_device_id.h>
 #include <asm/cpuid/api.h>
@@ -69,6 +70,8 @@ static const char ucode_path[] = "kernel/x86/microcode/GenuineIntel.bin";
 
 #define MBOX_XACTION_TIMEOUT_MS	(10 * MSEC_PER_SEC)
 
+#define CPUID_EDX_ARCH_CAP	BIT(29)
+
 /* Current microcode patch used in early patching on the APs. */
 static struct microcode_intel *ucode_patch_va __read_mostly;
 static struct microcode_intel *ucode_patch_late __read_mostly;
@@ -737,11 +740,21 @@ static int __init save_builtin_microcode(void)
 }
 early_initcall(save_builtin_microcode);
 
+static __init void setup_uniform(void);
+
 /* Load microcode on BSP from initrd or builtin blobs */
 void __init load_ucode_intel_bsp(struct early_load_data *ed)
 {
 	struct ucode_cpu_info uci;
 
+	/*
+	 * The loader could be disabled during the uniform setup if any firmware
+	 * misconfiguration is found.
+	 */
+	setup_uniform();
+	if (microcode_loader_disabled())
+		return;
+
 	uci.mc = get_microcode_blob(&uci, false);
 	ed->old_rev = uci.cpu_sig.rev;
 
@@ -989,6 +1002,62 @@ static __init bool staging_available(void)
 	return !!(val & MCU_STAGING);
 }
 
+static __init void setup_uniform(void)
+{
+	u64 val;
+
+	if (native_cpuid_eax(0) < 7)
+		return;
+
+	if (!(native_cpuid_edx(7) & CPUID_EDX_ARCH_CAP))
+		return;
+
+	if (!(native_rdmsrq(MSR_IA32_ARCH_CAPABILITIES) & ARCH_CAP_MCU_ENUM))
+		return;
+
+	val = native_rdmsrq(MSR_IA32_MCU_ENUMERATION);
+	if (!(val & MCU_UNIFORM_AVAIL))
+		return;
+
+	/*
+	 * Ensure that the firmware did all the necessary steps. Any improper
+	 * configuration makes the update mechanism unusable.
+	 */
+	if (val & MCU_UNIFORM_CONFIG_REQD && !(val & MCU_UNIFORM_CONFIG_COMPLETE)) {
+		microcode_disable_loader();
+		pr_err("loading disabled: incomplete firmware configuration.\n");
+		return;
+	}
+
+	/*
+	 * Configure the uniform scope accordingly. To make it simple, treat all
+	 * scopes narrower than the package scope as per-core scope.
+	 */
+	switch (FIELD_GET(MCU_UNIFORM_SCOPE, val)) {
+	case MCU_UNIFORM_SCOPE_MODULE:
+	case MCU_UNIFORM_SCOPE_TILE:
+	case MCU_UNIFORM_SCOPE_DIE:
+		pr_info("Uniform scope is narrower than package, using core scope.\n");
+		fallthrough;
+	case MCU_UNIFORM_SCOPE_CORE:
+		microcode_intel_ops.uniform_scope = UNIFORM_CORE;
+		break;
+	case MCU_UNIFORM_SCOPE_PACKAGE:
+		microcode_intel_ops.uniform_scope = UNIFORM_PKG;
+		break;
+	case MCU_UNIFORM_SCOPE_PLATFORM:
+		microcode_intel_ops.uniform_scope = UNIFORM_SYS;
+		break;
+	default:
+		microcode_disable_loader();
+		pr_err("loading disabled: unknown uniform scope.\n");
+		return;
+	}
+
+	microcode_intel_ops.use_uniform = true;
+	pr_info("Enabled uniform feature.\n");
+}
+
 bool __init intel_primary_aware(void)
 {
 	if (!microcode_intel_ops.use_uniform)
-- 
2.53.0


  parent reply	other threads:[~2026-09-12  0:35 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-12  0:08 [PATCH RFC v1 0/8] x86/microcode: Enable uniform feature Chang S. Bae
2026-09-12  0:08 ` [PATCH RFC v1 1/8] cpu/hotplug: Allow architecture-specific primary CPU bringup Chang S. Bae
2026-09-12  0:08 ` [PATCH RFC v1 2/8] x86/hotplug: Implement SMT-primary selection for parallel bringup Chang S. Bae
2026-09-12  0:08 ` [PATCH RFC v1 3/8] x86/cpu/topology: Introduce primary core mask Chang S. Bae
2026-09-12  0:08 ` [PATCH RFC v1 4/8] x86/microcode: Extend struct microcode_ops for uniform loading Chang S. Bae
2026-09-12  0:08 ` [PATCH RFC v1 5/8] x86/microcode: Clarify online enforcement with " Chang S. Bae
2026-09-12  0:08 ` [PATCH RFC v1 6/8] x86/microcode: Support uniform scope for late loading Chang S. Bae
2026-09-12  0:08 ` [PATCH RFC v1 7/8] x86/microcode/intel: Support uniform scope for early loading Chang S. Bae
2026-09-12  0:08 ` Chang S. Bae [this message]
2026-09-16  0:45 ` [PATCH RFC v1 0/8] x86/microcode: Enable uniform feature 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=20260912000815.997720-9-chang.seok.bae@intel.com \
    --to=chang.seok.bae@intel.com \
    --cc=bp@alien8.de \
    --cc=dave.hansen@linux.intel.com \
    --cc=kevin.shu@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=tglx@kernel.org \
    --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

all inboxes | Powered by JetHome®