aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBorislav Petkov <bp@suse.de>2018-02-16 06:26:39 -0500
committerIngo Molnar <mingo@kernel.org>2018-02-17 02:43:55 -0500
commit1008c52c09dcb23d93f8e0ea83a6246265d2cce0 (patch)
tree3228127163bbf4befdba6f95ef612e4d6b710dc8
parent3f1f576a195aa266813cbd4ca70291deb61e0129 (diff)
x86/CPU: Add a microcode loader callback
Add a callback function which the microcode loader calls when microcode has been updated to a newer revision. Do the callback only when no error was encountered during loading. Tested-by: Ashok Raj <ashok.raj@intel.com> Signed-off-by: Borislav Petkov <bp@suse.de> Reviewed-by: Ashok Raj <ashok.raj@intel.com> Cc: Andy Lutomirski <luto@kernel.org> Cc: Arjan van de Ven <arjan@linux.intel.com> Cc: Borislav Petkov <bp@alien8.de> Cc: Dan Williams <dan.j.williams@intel.com> Cc: Dave Hansen <dave.hansen@linux.intel.com> Cc: David Woodhouse <dwmw2@infradead.org> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: Josh Poimboeuf <jpoimboe@redhat.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Link: http://lkml.kernel.org/r/20180216112640.11554-3-bp@alien8.de Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--arch/x86/include/asm/processor.h1
-rw-r--r--arch/x86/kernel/cpu/common.c10
-rw-r--r--arch/x86/kernel/cpu/microcode/core.c8
3 files changed, 17 insertions, 2 deletions
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 1bd9ed87606f..b0ccd4847a58 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -977,4 +977,5 @@ bool xen_set_default_idle(void);
977 977
978void stop_this_cpu(void *dummy); 978void stop_this_cpu(void *dummy);
979void df_debug(struct pt_regs *regs, long error_code); 979void df_debug(struct pt_regs *regs, long error_code);
980void microcode_check(void);
980#endif /* _ASM_X86_PROCESSOR_H */ 981#endif /* _ASM_X86_PROCESSOR_H */
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 824aee0117bb..84f1cd88608b 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -1749,3 +1749,13 @@ static int __init init_cpu_syscore(void)
1749 return 0; 1749 return 0;
1750} 1750}
1751core_initcall(init_cpu_syscore); 1751core_initcall(init_cpu_syscore);
1752
1753/*
1754 * The microcode loader calls this upon late microcode load to recheck features,
1755 * only when microcode has been updated. Caller holds microcode_mutex and CPU
1756 * hotplug lock.
1757 */
1758void microcode_check(void)
1759{
1760 perf_check_microcode();
1761}
diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
index 6fdaf7cf3182..aa1b9a422f2b 100644
--- a/arch/x86/kernel/cpu/microcode/core.c
+++ b/arch/x86/kernel/cpu/microcode/core.c
@@ -509,6 +509,7 @@ static ssize_t reload_store(struct device *dev,
509 const char *buf, size_t size) 509 const char *buf, size_t size)
510{ 510{
511 enum ucode_state tmp_ret = UCODE_OK; 511 enum ucode_state tmp_ret = UCODE_OK;
512 bool do_callback = false;
512 unsigned long val; 513 unsigned long val;
513 ssize_t ret = 0; 514 ssize_t ret = 0;
514 int cpu; 515 int cpu;
@@ -531,10 +532,13 @@ static ssize_t reload_store(struct device *dev,
531 if (!ret) 532 if (!ret)
532 ret = -EINVAL; 533 ret = -EINVAL;
533 } 534 }
535
536 if (tmp_ret == UCODE_UPDATED)
537 do_callback = true;
534 } 538 }
535 539
536 if (!ret && tmp_ret == UCODE_UPDATED) 540 if (!ret && do_callback)
537 perf_check_microcode(); 541 microcode_check();
538 542
539 mutex_unlock(&microcode_mutex); 543 mutex_unlock(&microcode_mutex);
540 put_online_cpus(); 544 put_online_cpus();