x86/microcode/intel: Reject problematic loading on Granite Rapids systems

Microcode updates can usually jump revisions. However, there is an erratum on
Granite Rapids systems. If they "jump over" revision 0x1000405, they result in
an #MC. Avoid it.

Signed-off-by: Chang S. Bae <chang.seok.bae@intel.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Reviewed-by: Dave Hansen <dave.hansen@linux.intel.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260916225939.1144524-1-chang.seok.bae@intel.com
This commit is contained in:
Chang S. Bae 2026-09-16 22:59:39 +00:00 committed by Borislav Petkov (AMD)
parent 27600805e6
commit e7d3e2f46d

View File

@ -309,6 +309,26 @@ static void save_microcode_patch(struct microcode_intel *patch)
pr_err("Unable to allocate microcode memory size: %u\n", size);
}
static bool revision_is_safe(struct cpu_signature *sig, u32 rev)
{
u32 vfm = IFM(x86_family(sig->sig), x86_model(sig->sig));
/*
* Erratum GNR98 can cause #MCs if "jumping over" revision 0x1000405.
* Avoid the jumps.
*/
if (vfm == INTEL_GRANITERAPIDS_X &&
x86_stepping(sig->sig) == 1 &&
sig->pf & 0x95 &&
sig->rev < 0x1000405 &&
rev > 0x1000405) {
pr_err_once("Erratum GNR98: skipping revision 0x%x.\n", rev);
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,
@ -330,6 +350,9 @@ static __init struct microcode_intel *scan_microcode(void *data, size_t size,
if (!intel_find_matching_signature(data, &uci->cpu_sig))
continue;
if (!revision_is_safe(&uci->cpu_sig, mc_header->rev))
continue;
/*
* For saving the early microcode, find the matching revision which
* was loaded on the BSP.
@ -878,6 +901,9 @@ static enum ucode_state parse_microcode_blobs(int cpu, struct iov_iter *iter)
if (!intel_find_matching_signature(mc, &uci->cpu_sig))
continue;
if (!revision_is_safe(&uci->cpu_sig, mc_header.rev))
continue;
is_safe = ucode_validate_minrev(&mc_header);
if (force_minrev && !is_safe)
continue;