summaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/cpu/microcode/core.c
diff options
context:
space:
mode:
authorBorislav Petkov <bp@suse.de>2017-01-20 21:29:51 +0100
committerThomas Gleixner <tglx@linutronix.de>2017-01-23 10:02:50 +0100
commitf3ad136d6ef966c8ba9090770c2bfe7e85f18471 (patch)
tree0dc1ad8daeeff482ea918ecce926859a4432b182 /arch/x86/kernel/cpu/microcode/core.c
parent7a93a40be23e5557934d773cc89b7b3627c08097 (diff)
x86/microcode/AMD: Check patch level only on the BSP
Check final patch levels for AMD only on the BSP. This way, we decide early and only once whether to continue loading or to leave the loader disabled on such systems. Simplify a lot. Signed-off-by: Borislav Petkov <bp@suse.de> Link: http://lkml.kernel.org/r/20170120202955.4091-13-bp@alien8.de Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86/kernel/cpu/microcode/core.c')
-rw-r--r--arch/x86/kernel/cpu/microcode/core.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
index dc54518299c4..3b74d2f315d3 100644
--- a/arch/x86/kernel/cpu/microcode/core.c
+++ b/arch/x86/kernel/cpu/microcode/core.c
@@ -69,6 +69,42 @@ struct cpu_info_ctx {
int err;
};
+/*
+ * Those patch levels cannot be updated to newer ones and thus should be final.
+ */
+static u32 final_levels[] = {
+ 0x01000098,
+ 0x0100009f,
+ 0x010000af,
+ 0, /* T-101 terminator */
+};
+
+/*
+ * Check the current patch level on this CPU.
+ *
+ * Returns:
+ * - true: if update should stop
+ * - false: otherwise
+ */
+static bool amd_check_current_patch_level(void)
+{
+ u32 lvl, dummy, i;
+ u32 *levels;
+
+ native_rdmsr(MSR_AMD64_PATCH_LEVEL, lvl, dummy);
+
+ if (IS_ENABLED(CONFIG_X86_32))
+ levels = (u32 *)__pa_nodebug(&final_levels);
+ else
+ levels = final_levels;
+
+ for (i = 0; levels[i]; i++) {
+ if (lvl == levels[i])
+ return true;
+ }
+ return false;
+}
+
static bool __init check_loader_disabled_bsp(void)
{
static const char *__dis_opt_str = "dis_ucode_ldr";
@@ -95,6 +131,11 @@ static bool __init check_loader_disabled_bsp(void)
if (native_cpuid_ecx(1) & BIT(31))
return *res;
+ if (x86_cpuid_vendor() == X86_VENDOR_AMD) {
+ if (amd_check_current_patch_level())
+ return *res;
+ }
+
if (cmdline_find_option_bool(cmdline, option) <= 0)
*res = false;