From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Ashok Raj Date: Sat, 20 Jul 2019 14:14:47 +0000 Subject: [PATCH] x86/microcode: Force update a uCode even if the rev is the same Signed-off-by: Ashok Raj --- arch/x86/kernel/cpu/microcode/core.c | 1 + arch/x86/kernel/cpu/microcode/intel.c | 57 +++++++++++++++++++++++++-- 2 files changed, 55 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c index cb0fdcaf1415..d44fe3e5c028 100644 --- a/arch/x86/kernel/cpu/microcode/core.c +++ b/arch/x86/kernel/cpu/microcode/core.c @@ -601,6 +601,7 @@ static int microcode_reload_late(void) atomic_set(&late_cpus_in, 0); atomic_set(&late_cpus_out, 0); + printk ("Going to do stop_machine\n"); ret = stop_machine_cpuslocked(__reload_late, NULL, cpu_online_mask); if (ret > 0) microcode_check(); diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c index ce799cfe9434..9e85d785b226 100644 --- a/arch/x86/kernel/cpu/microcode/intel.c +++ b/arch/x86/kernel/cpu/microcode/intel.c @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -38,6 +39,7 @@ #include static const char ucode_path[] = "kernel/x86/microcode/GenuineIntel.bin"; +static bool force_ucode_load = false; /* Current microcode patch used in early patching on the APs. */ static struct microcode_intel *intel_ucode_patch; @@ -94,8 +96,18 @@ static int has_newer_microcode(void *mc, unsigned int csig, int cpf, int new_rev { struct microcode_header_intel *mc_hdr = mc; - if (mc_hdr->rev <= new_rev) + //if (mc_hdr->rev <= new_rev) + if (mc_hdr->rev < new_rev) { + printk ("Returning NO_NEW old = 0x%x new = 0x%x\n", + mc_hdr->rev, new_rev); return 0; + } + if ((mc_hdr->rev == new_rev) && !force_ucode_load) { + printk ("SAME REV: no_force Returning NO_NEW old = 0x%x new = 0x%x\n", + mc_hdr->rev, new_rev); + return 0; + } + printk ("ucode: force loading same rev\n"); return find_matching_signature(mc, csig, cpf); } @@ -593,11 +605,20 @@ static int apply_microcode_early(struct ucode_cpu_info *uci, bool early) * already. */ rev = intel_get_microcode_revision(); - if (rev >= mc->hdr.rev) { + if (rev > mc->hdr.rev) { uci->cpu_sig.rev = rev; return UCODE_OK; } + if (rev == mc->hdr.rev) { + if (!force_ucode_load) { + printk ("Matching ucode rev, no update\n"); + return UCODE_OK; + } else { + printk ("Matching ucode rev.. force updating\n"); + } + } + /* * Writeback and invalidate caches before updating microcode to avoid * internal issues depending on what the microcode is updating. @@ -649,6 +670,29 @@ int __init save_microcode_in_initrd_intel(void) return 0; } +static bool check_force_ucode_bsp(void) +{ + static const char *__force_ucode_str = "force_ucode_load"; + +#ifdef CONFIG_X86_32 + const char *cmdline = (const char *)__pa_nodebug(boot_command_line); + const char *option = (const char *)__pa_nodebug(__force_ucode_str); + bool *res = (bool *)__pa_nodebug(&force_ucode_load); + +#else /* CONFIG_X86_64 */ + const char *cmdline = boot_command_line; + const char *option = __force_ucode_str; + bool *res = &force_ucode_load; +#endif + + if (cmdline_find_option_bool(cmdline, option)) { + printk("cmdline forcing ucode update for same rev\n"); + *res = true; + } + + return *res; +} + /* * @res_patch, output: a pointer to the patch we found. */ @@ -682,6 +726,9 @@ void __init load_ucode_intel_bsp(void) { struct microcode_intel *patch; struct ucode_cpu_info uci; + bool force_bsp; + + force_bsp = check_force_ucode_bsp(); patch = __load_ucode_intel(&uci); if (!patch) @@ -730,8 +777,12 @@ static struct microcode_intel *find_patch(struct ucode_cpu_info *uci) phdr = (struct microcode_header_intel *)iter->data; - if (phdr->rev <= uci->cpu_sig.rev) + if (phdr->rev < uci->cpu_sig.rev) continue; + if (phdr->rev == uci->cpu_sig.rev && !force_ucode_load) + continue; + else + printk ("same rev forcing ucode\n"); if (!find_matching_signature(phdr, uci->cpu_sig.sig, -- https://clearlinux.org