aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBorislav Petkov <bp@suse.de>2017-05-28 16:04:14 -0400
committerIngo Molnar <mingo@kernel.org>2017-05-29 02:22:48 -0400
commitdac6ca243c4c49a9ca7507d3d66140ebfac8b04b (patch)
tree5dc4ba53f80a4be6a5c66291de2b81b418911e09
parent5ed02dbb497422bf225783f46e6eadd237d23d6b (diff)
x86/microcode/AMD: Change load_microcode_amd()'s param to bool to fix preemptibility bug
With CONFIG_DEBUG_PREEMPT enabled, I get: BUG: using smp_processor_id() in preemptible [00000000] code: swapper/0/1 caller is debug_smp_processor_id CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.12.0-rc2+ #2 Call Trace: dump_stack check_preemption_disabled debug_smp_processor_id save_microcode_in_initrd_amd ? microcode_init save_microcode_in_initrd ... because, well, it says it above, we're using smp_processor_id() in preemptible code. But passing the CPU number is not really needed. It is only used to determine whether we're on the BSP, and, if so, to save the microcode patch for early loading. [ We don't absolutely need to do it on the BSP but we do that customarily there. ] Instead, convert that function parameter to a boolean which denotes whether the patch should be saved or not, thereby avoiding the use of smp_processor_id() in preemptible code. Signed-off-by: Borislav Petkov <bp@suse.de> 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/20170528200414.31305-1-bp@alien8.de Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--arch/x86/kernel/cpu/microcode/amd.c16
1 files changed, 8 insertions, 8 deletions
diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c
index 45db4d2ebd01..e9f4d762aa5b 100644
--- a/arch/x86/kernel/cpu/microcode/amd.c
+++ b/arch/x86/kernel/cpu/microcode/amd.c
@@ -320,7 +320,7 @@ void load_ucode_amd_ap(unsigned int cpuid_1_eax)
320} 320}
321 321
322static enum ucode_state 322static enum ucode_state
323load_microcode_amd(int cpu, u8 family, const u8 *data, size_t size); 323load_microcode_amd(bool save, u8 family, const u8 *data, size_t size);
324 324
325int __init save_microcode_in_initrd_amd(unsigned int cpuid_1_eax) 325int __init save_microcode_in_initrd_amd(unsigned int cpuid_1_eax)
326{ 326{
@@ -338,8 +338,7 @@ int __init save_microcode_in_initrd_amd(unsigned int cpuid_1_eax)
338 if (!desc.mc) 338 if (!desc.mc)
339 return -EINVAL; 339 return -EINVAL;
340 340
341 ret = load_microcode_amd(smp_processor_id(), x86_family(cpuid_1_eax), 341 ret = load_microcode_amd(true, x86_family(cpuid_1_eax), desc.data, desc.size);
342 desc.data, desc.size);
343 if (ret != UCODE_OK) 342 if (ret != UCODE_OK)
344 return -EINVAL; 343 return -EINVAL;
345 344
@@ -675,7 +674,7 @@ static enum ucode_state __load_microcode_amd(u8 family, const u8 *data,
675} 674}
676 675
677static enum ucode_state 676static enum ucode_state
678load_microcode_amd(int cpu, u8 family, const u8 *data, size_t size) 677load_microcode_amd(bool save, u8 family, const u8 *data, size_t size)
679{ 678{
680 enum ucode_state ret; 679 enum ucode_state ret;
681 680
@@ -689,8 +688,8 @@ load_microcode_amd(int cpu, u8 family, const u8 *data, size_t size)
689 688
690#ifdef CONFIG_X86_32 689#ifdef CONFIG_X86_32
691 /* save BSP's matching patch for early load */ 690 /* save BSP's matching patch for early load */
692 if (cpu_data(cpu).cpu_index == boot_cpu_data.cpu_index) { 691 if (save) {
693 struct ucode_patch *p = find_patch(cpu); 692 struct ucode_patch *p = find_patch(0);
694 if (p) { 693 if (p) {
695 memset(amd_ucode_patch, 0, PATCH_MAX_SIZE); 694 memset(amd_ucode_patch, 0, PATCH_MAX_SIZE);
696 memcpy(amd_ucode_patch, p->data, min_t(u32, ksize(p->data), 695 memcpy(amd_ucode_patch, p->data, min_t(u32, ksize(p->data),
@@ -722,11 +721,12 @@ static enum ucode_state request_microcode_amd(int cpu, struct device *device,
722{ 721{
723 char fw_name[36] = "amd-ucode/microcode_amd.bin"; 722 char fw_name[36] = "amd-ucode/microcode_amd.bin";
724 struct cpuinfo_x86 *c = &cpu_data(cpu); 723 struct cpuinfo_x86 *c = &cpu_data(cpu);
724 bool bsp = c->cpu_index == boot_cpu_data.cpu_index;
725 enum ucode_state ret = UCODE_NFOUND; 725 enum ucode_state ret = UCODE_NFOUND;
726 const struct firmware *fw; 726 const struct firmware *fw;
727 727
728 /* reload ucode container only on the boot cpu */ 728 /* reload ucode container only on the boot cpu */
729 if (!refresh_fw || c->cpu_index != boot_cpu_data.cpu_index) 729 if (!refresh_fw || !bsp)
730 return UCODE_OK; 730 return UCODE_OK;
731 731
732 if (c->x86 >= 0x15) 732 if (c->x86 >= 0x15)
@@ -743,7 +743,7 @@ static enum ucode_state request_microcode_amd(int cpu, struct device *device,
743 goto fw_release; 743 goto fw_release;
744 } 744 }
745 745
746 ret = load_microcode_amd(cpu, c->x86, fw->data, fw->size); 746 ret = load_microcode_amd(bsp, c->x86, fw->data, fw->size);
747 747
748 fw_release: 748 fw_release:
749 release_firmware(fw); 749 release_firmware(fw);