mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
x86/ucode: Work around Granite Rapids erraturm GNR98
Block loads which are known to hang the system. Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> Reviewed-by: Teddy Astie <teddy.astie@vates.tech> Reviewed-by: Roger Pau Monné <roger@xenproject.org> Acked-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
1 parent
f3a525c259
commit
70cbd9a08d
1 file changed
+40
@@ -27,6 +27,7 @@
|
||||
#include <xen/string.h>
|
||||
#include <xen/xmalloc.h>
|
||||
|
||||
#include <asm/intel-family.h>
|
||||
#include <asm/msr.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/system.h>
|
||||
@@ -273,6 +274,44 @@ static bool microcode_fits_cpu(const struct microcode_patch *mc)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool microcode_safe_to_load(const struct microcode_patch *mc)
|
||||
{
|
||||
const struct cpu_signature *cpu_sig = &this_cpu(cpu_sig);
|
||||
|
||||
/*
|
||||
* Treat pre-production as always safe - anyone using pre-production
|
||||
* microcode knows what they are doing, and can keep any resulting pieces.
|
||||
*/
|
||||
if ( (int)cpu_sig->rev < 0 || mc->rev < 0 )
|
||||
return true;
|
||||
|
||||
/*
|
||||
* GNR98 states that Granite Rapids systems hang when loading new ucode on
|
||||
* sufficiently old firmware. GNR101 retroactively states that one ucode
|
||||
* had an incorrect minimum revision field, in light of discovering GNR98.
|
||||
*
|
||||
* Both are incomplete statements of the problem.
|
||||
*
|
||||
* At the time of writing (August 2026), the believed safe sequence is:
|
||||
* previous -> [0x01000380...0x010003f3] -> 0x01000405 -> any later
|
||||
*
|
||||
* Disallow known-unsafe loads while permitting believed-safe loads. For
|
||||
* GNR, this allows multi-hop loading to get up to the latest.
|
||||
*/
|
||||
if ( boot_cpu_data.vfm == INTEL_GRANITERAPIDS_X &&
|
||||
boot_cpu_data.stepping == 1 && (cpu_sig->pf & 0x95) &&
|
||||
((cpu_sig->rev < 0x01000380 && mc->rev >= 0x01000405) ||
|
||||
(cpu_sig->rev < 0x01000405 && mc->rev > 0x01000405)) )
|
||||
{
|
||||
printk_once(XENLOG_WARNING "microcode: Granite Rapids erratum GNR98 detected. Skipping ucode 0x%08x\n"
|
||||
XENLOG_WARNING "microcode: Firmware update recommended\n",
|
||||
mc->rev);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int cf_check intel_compare(
|
||||
const struct microcode_patch *old, const struct microcode_patch *new)
|
||||
{
|
||||
@@ -365,6 +404,7 @@ static struct microcode_patch *cf_check intel_ucode_parse(
|
||||
* one with higher revision.
|
||||
*/
|
||||
if ( microcode_fits_cpu(mc) &&
|
||||
microcode_safe_to_load(mc) &&
|
||||
(!saved || compare_revisions(saved->rev, mc->rev) == NEW_UCODE) )
|
||||
saved = mc;
|
||||
|
||||
|
||||