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, hpa@zytor.com,
andrew.cooper3@citrix.com, arjan.van.de.ven@intel.com,
chang.seok.bae@intel.com
Subject: [PATCH RFC 6/8] x86/microcode/intel: Apply minimum revision check to early loading
Date: Tue, 1 Sep 2026 23:16:31 +0000 [thread overview]
Message-ID: <20260901231634.714144-7-chang.seok.bae@intel.com> (raw)
In-Reply-To: <20260901231634.714144-1-chang.seok.bae@intel.com>
The minimum revision check is now generally applicable. Establish the
minimum revision check on early loading. Follow the late loading behavior
when the check fails:
* Load but taint the kernel if not enforced, or
* Reject the loading if enforced.
Adjust the check function so that the early path can pass the current
revision.
With this establishment, do not reject early loading anymore when
enforced.
Suggested-by: Arjan van de Ven <arjan.van.de.ven@intel.com>
Signed-off-by: Chang S. Bae <chang.seok.bae@intel.com>
---
arch/x86/kernel/cpu/microcode/intel.c | 64 ++++++++++++---------------
1 file changed, 29 insertions(+), 35 deletions(-)
diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c
index 3247c619eaa1..ddd5b72b27a1 100644
--- a/arch/x86/kernel/cpu/microcode/intel.c
+++ b/arch/x86/kernel/cpu/microcode/intel.c
@@ -341,6 +341,29 @@ static bool is_loading_denied(struct cpu_signature *sig, u32 rev)
return false;
}
+static bool ucode_validate_minrev(u32 cur_rev, struct microcode_header_intel *mc_header)
+{
+ /*
+ * Ensure the header declares a minimum revision required to perform a
+ * load. The previously reserved field is 0 in older microcode blobs.
+ */
+ if (!mc_header->min_req_ver) {
+ pr_info("Unsafe microcode update: Microcode header does not specify a required min version\n");
+ return false;
+ }
+
+ /*
+ * Check whether the current revision is either greater or equal to
+ * the minimum revision specified in the header.
+ */
+ if (cur_rev < mc_header->min_req_ver) {
+ pr_info("Unsafe microcode update: Current revision 0x%x too old.\n", cur_rev);
+ pr_info("Current should be at 0x%x or higher. Update incrementally.\n", mc_header->min_req_ver);
+ return false;
+ }
+ return true;
+}
+
/* Scan blob for microcode matching the boot CPUs family, model, stepping */
static __init struct microcode_intel *scan_microcode(void *data, size_t size,
struct ucode_cpu_info *uci,
@@ -365,6 +388,9 @@ static __init struct microcode_intel *scan_microcode(void *data, size_t size,
if (is_loading_denied(&uci->cpu_sig, mc_header->rev))
continue;
+ if (force_minrev && !ucode_validate_minrev(uci->cpu_sig.rev, mc_header))
+ continue;
+
/*
* For saving the early microcode, find the matching revision which
* was loaded on the BSP.
@@ -786,17 +812,10 @@ void __init load_ucode_intel_bsp(struct early_load_data *ed)
uci.mc = get_microcode_blob(&uci, false);
ed->old_rev = uci.cpu_sig.rev;
- if (!uci.mc)
- return;
-
- if (force_minrev) {
- pr_warn_once("No early load: minimum revision check is not implemented.\n");
- return;
- }
-
- if (apply_microcode_early(&uci) == UCODE_UPDATED) {
+ if (uci.mc && apply_microcode_early(&uci) == UCODE_UPDATED) {
ucode_patch_va = UCODE_BSP_LOADED;
ed->new_rev = uci.cpu_sig.rev;
+ ed->is_safe = ucode_validate_minrev(ed->old_rev, uci.mc);
}
}
@@ -845,31 +864,6 @@ static enum ucode_state apply_microcode_late(int cpu)
return ret;
}
-static bool ucode_validate_minrev(struct microcode_header_intel *mc_header)
-{
- int cur_rev = boot_cpu_data.microcode;
-
- /*
- * Ensure the header declares a minimum revision required to perform a
- * load. The previously reserved field is 0 in older microcode blobs.
- */
- if (!mc_header->min_req_ver) {
- pr_info("Unsafe microcode update: Microcode header does not specify a required min version\n");
- return false;
- }
-
- /*
- * Check whether the current revision is either greater or equal to
- * to the minimum revision specified in the header.
- */
- if (cur_rev < mc_header->min_req_ver) {
- pr_info("Unsafe microcode update: Current revision 0x%x too old\n", cur_rev);
- pr_info("Current should be at 0x%x or higher. Update incrementally.\n", mc_header->min_req_ver);
- return false;
- }
- return true;
-}
-
static enum ucode_state parse_microcode_blobs(int cpu, struct iov_iter *iter)
{
struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
@@ -923,7 +917,7 @@ static enum ucode_state parse_microcode_blobs(int cpu, struct iov_iter *iter)
if (is_loading_denied(&uci->cpu_sig, mc_header.rev))
continue;
- is_safe = ucode_validate_minrev(&mc_header);
+ is_safe = ucode_validate_minrev(uci->cpu_sig.rev, &mc_header);
if (force_minrev && !is_safe)
continue;
--
2.53.0
next prev parent reply other threads:[~2026-09-01 23:43 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-01 23:16 [PATCH 0/8] x86/microcode: Address GNR errata and follow-up Chang S. Bae
2026-09-01 23:16 ` [PATCH 1/8] x86/microcode/intel: Reject problematic loading on GNR systems Chang S. Bae
2026-09-02 13:11 ` Sohil Mehta
2026-09-02 13:21 ` Van De Ven, Arjan
2026-09-02 14:23 ` Dave Hansen
2026-09-03 1:51 ` Borislav Petkov
2026-09-03 21:04 ` Chang S. Bae
2026-09-01 23:16 ` [PATCH 2/8] x86/microcode: Solidify base_rev= option parsing Chang S. Bae
2026-09-01 23:16 ` [PATCH 3/8] x86/microcode: Accept a boolean for force_minrev parameter Chang S. Bae
2026-09-01 23:16 ` [PATCH 4/8] x86/microcode: Mark early_data __initdata Chang S. Bae
2026-09-01 23:16 ` [PATCH RFC 5/8] x86/microcode: Decouple minimum revision check from late loading Chang S. Bae
2026-09-01 23:16 ` Chang S. Bae [this message]
2026-09-01 23:16 ` [PATCH RFC 7/8] x86/microcode: Introduce iterative " Chang S. Bae
2026-09-01 23:16 ` [PATCH RFC 8/8] x86/microcode/intel: Select the lowest loadable revision for iterative loading Chang S. Bae
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=20260901231634.714144-7-chang.seok.bae@intel.com \
--to=chang.seok.bae@intel.com \
--cc=andrew.cooper3@citrix.com \
--cc=arjan.van.de.ven@intel.com \
--cc=bp@alien8.de \
--cc=dave.hansen@linux.intel.com \
--cc=hpa@zytor.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®