aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.9.21/0011-x86-microcode-AMD-Change-load_microcode_amd-s-param-.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.9.21/0011-x86-microcode-AMD-Change-load_microcode_amd-s-param-.patch')
-rw-r--r--common/recipes-kernel/linux/linux-yocto-4.9.21/0011-x86-microcode-AMD-Change-load_microcode_amd-s-param-.patch133
1 files changed, 133 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.9.21/0011-x86-microcode-AMD-Change-load_microcode_amd-s-param-.patch b/common/recipes-kernel/linux/linux-yocto-4.9.21/0011-x86-microcode-AMD-Change-load_microcode_amd-s-param-.patch
new file mode 100644
index 00000000..00297c34
--- /dev/null
+++ b/common/recipes-kernel/linux/linux-yocto-4.9.21/0011-x86-microcode-AMD-Change-load_microcode_amd-s-param-.patch
@@ -0,0 +1,133 @@
+From df2f7e0d21ca37bdbdf3fc5b6fa42a9b0bc6fbd6 Mon Sep 17 00:00:00 2001
+From: Borislav Petkov <bp@suse.de>
+Date: Mon, 19 Feb 2018 11:13:28 +0100
+Subject: [PATCH 11/12] x86/microcode/AMD: Change load_microcode_amd()'s param
+ to bool to fix preemptibility bug
+
+commit dac6ca243c4c49a9ca7507d3d66140ebfac8b04b upstream.
+
+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>
+[arnd: rebased to 4.9, after running into warning:
+ arch/x86/kernel/cpu/microcode/amd.c:881:30: self-comparison always evaluates to true]
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/include/asm/microcode_amd.h | 1 -
+ arch/x86/kernel/cpu/microcode/amd.c | 17 +++++++++++------
+ 2 files changed, 11 insertions(+), 7 deletions(-)
+
+diff --git a/arch/x86/include/asm/microcode_amd.h b/arch/x86/include/asm/microcode_amd.h
+index 15eb754..98ccbd1 100644
+--- a/arch/x86/include/asm/microcode_amd.h
++++ b/arch/x86/include/asm/microcode_amd.h
+@@ -59,7 +59,6 @@ static inline u16 find_equiv_id(struct equiv_cpu_entry *equiv_cpu_table,
+
+ extern int __apply_microcode_amd(struct microcode_amd *mc_amd);
+ extern int apply_microcode_amd(int cpu);
+-extern enum ucode_state load_microcode_amd(int cpu, u8 family, const u8 *data, size_t size);
+
+ #define PATCH_MAX_SIZE PAGE_SIZE
+
+diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c
+index 017bda1..aaab28a 100644
+--- a/arch/x86/kernel/cpu/microcode/amd.c
++++ b/arch/x86/kernel/cpu/microcode/amd.c
+@@ -135,6 +135,9 @@ static size_t compute_container_size(u8 *data, u32 total_size)
+ return size;
+ }
+
++static enum ucode_state
++load_microcode_amd(bool save, u8 family, const u8 *data, size_t size);
++
+ /*
+ * Early load occurs before we can vmalloc(). So we look for the microcode
+ * patch container file in initrd, traverse equivalent cpu table, look for a
+@@ -451,7 +454,7 @@ int __init save_microcode_in_initrd_amd(void)
+ eax = cpuid_eax(0x00000001);
+ eax = ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff);
+
+- ret = load_microcode_amd(smp_processor_id(), eax, container, container_size);
++ ret = load_microcode_amd(true, eax, container, container_size);
+ if (ret != UCODE_OK)
+ retval = -EINVAL;
+
+@@ -860,7 +863,8 @@ static enum ucode_state __load_microcode_amd(u8 family, const u8 *data,
+ return UCODE_OK;
+ }
+
+-enum ucode_state load_microcode_amd(int cpu, u8 family, const u8 *data, size_t size)
++static enum ucode_state
++load_microcode_amd(bool save, u8 family, const u8 *data, size_t size)
+ {
+ enum ucode_state ret;
+
+@@ -874,8 +878,8 @@ enum ucode_state load_microcode_amd(int cpu, u8 family, const u8 *data, size_t s
+
+ #ifdef CONFIG_X86_32
+ /* save BSP's matching patch for early load */
+- if (cpu_data(cpu).cpu_index == boot_cpu_data.cpu_index) {
+- struct ucode_patch *p = find_patch(cpu);
++ if (save) {
++ struct ucode_patch *p = find_patch(0);
+ if (p) {
+ memset(amd_ucode_patch, 0, PATCH_MAX_SIZE);
+ memcpy(amd_ucode_patch, p->data, min_t(u32, ksize(p->data),
+@@ -907,11 +911,12 @@ static enum ucode_state request_microcode_amd(int cpu, struct device *device,
+ {
+ char fw_name[36] = "amd-ucode/microcode_amd.bin";
+ struct cpuinfo_x86 *c = &cpu_data(cpu);
++ bool bsp = c->cpu_index == boot_cpu_data.cpu_index;
+ enum ucode_state ret = UCODE_NFOUND;
+ const struct firmware *fw;
+
+ /* reload ucode container only on the boot cpu */
+- if (!refresh_fw || c->cpu_index != boot_cpu_data.cpu_index)
++ if (!refresh_fw || !bsp)
+ return UCODE_OK;
+
+ if (c->x86 >= 0x15)
+@@ -928,7 +933,7 @@ static enum ucode_state request_microcode_amd(int cpu, struct device *device,
+ goto fw_release;
+ }
+
+- ret = load_microcode_amd(cpu, c->x86, fw->data, fw->size);
++ ret = load_microcode_amd(bsp, c->x86, fw->data, fw->size);
+
+ fw_release:
+ release_firmware(fw);
+--
+2.7.4
+