return (patch_size <= max_size);
}
+static bool check_final_patch_levels(const struct cpu_signature *sig)
+{
+ /*
+ * The 'final_levels' of patch ids have been obtained empirically.
+ * Refer bug https://bugzilla.suse.com/show_bug.cgi?id=913996
+ * for details of the issue. The short version is that people
+ * using certain Fam10h systems noticed system hang issues when
+ * trying to update microcode levels beyond the patch IDs below.
+ * From internal discussions, we gathered that OS/hypervisor
+ * cannot reliably perform microcode updates beyond these levels
+ * due to hardware issues. Therefore, we need to abort microcode
+ * update process if we hit any of these levels.
+ */
+ static const unsigned int final_levels[] = {
+ 0x01000098,
+ 0x0100009f,
+ 0x010000af,
+ };
+ unsigned int i;
+
+ if ( boot_cpu_data.x86 != 0x10 )
+ return false;
+
+ for ( i = 0; i < ARRAY_SIZE(final_levels); i++ )
+ if ( sig->rev == final_levels[i] )
+ return true;
+
+ return false;
+}
+
static bool_t find_equiv_cpu_id(const struct equiv_cpu_entry *equiv_cpu_table,
unsigned int current_cpu_id,
unsigned int *equiv_cpu_id)
if ( !match_cpu(patch) )
return -EINVAL;
+ if ( check_final_patch_levels(sig) )
+ {
+ printk(XENLOG_ERR
+ "microcode: CPU%u current rev %#x unsafe to update\n",
+ cpu, sig->rev);
+ return -ENXIO;
+ }
+
hdr = patch->mpb;
hw_err = wrmsr_safe(MSR_AMD_PATCHLOADER, (unsigned long)hdr);
return 0;
}
-/*
- * The 'final_levels' of patch ids have been obtained empirically.
- * Refer bug https://bugzilla.suse.com/show_bug.cgi?id=913996
- * for details of the issue. The short version is that people
- * using certain Fam10h systems noticed system hang issues when
- * trying to update microcode levels beyond the patch IDs below.
- * From internal discussions, we gathered that OS/hypervisor
- * cannot reliably perform microcode updates beyond these levels
- * due to hardware issues. Therefore, we need to abort microcode
- * update process if we hit any of these levels.
- */
-static const unsigned int final_levels[] = {
- 0x01000098,
- 0x0100009f,
- 0x010000af
-};
-
-static bool_t check_final_patch_levels(unsigned int cpu)
-{
- /*
- * Check the current patch levels on the cpu. If they are equal to
- * any of the 'final_levels', then we should not update the microcode
- * patch on the cpu as system will hang otherwise.
- */
- const struct cpu_signature *sig = &per_cpu(cpu_sig, cpu);
- unsigned int i;
-
- if ( boot_cpu_data.x86 != 0x10 )
- return 0;
-
- for ( i = 0; i < ARRAY_SIZE(final_levels); i++ )
- if ( sig->rev == final_levels[i] )
- return 1;
-
- return 0;
-}
-
static struct microcode_patch *cpu_request_microcode(const void *buf,
size_t bufsize)
{
goto out;
}
- if ( check_final_patch_levels(cpu) )
- {
- printk(XENLOG_INFO
- "microcode: Cannot update microcode patch on the cpu as we hit a final level\n");
- error = -EPERM;
- goto out;
- }
-
mc_amd = xzalloc(struct microcode_amd);
if ( !mc_amd )
{