]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob
09625ee12ffc2354d2d8a3384719e6bcb7e1843d
[thirdparty/kernel/stable-queue.git] /
1 From foo@baz Fri Feb 23 17:12:49 CET 2018
2 From: Arnd Bergmann <arnd@arndb.de>
3 Date: Tue, 20 Feb 2018 12:55:05 +0100
4 Subject: x86/microcode/AMD: Change load_microcode_amd()'s param to bool to fix preemptibility bug
5 To: stable@vger.kernel.org
6 Cc: Greg KH <gregkh@linuxfoundation.org>, linux-kernel@vger.kernel.org, Borislav Petkov <bp@suse.de>, Linus Torvalds <torvalds@linux-foundation.org>, Peter Zijlstra <peterz@infradead.org>, Thomas Gleixner <tglx@linutronix.de>, Ingo Molnar <mingo@kernel.org>, Arnd Bergmann <arnd@arndb.de>, Ingo Molnar <mingo@redhat.com>, "H. Peter Anvin" <hpa@zytor.com>, x86@kernel.org, Borislav Petkov <bp@alien8.de>, Tom Lendacky <thomas.lendacky@amd.com>
7 Message-ID: <20180220115527.1806578-19-arnd@arndb.de>
8
9 From: Borislav Petkov <bp@suse.de>
10
11 commit dac6ca243c4c49a9ca7507d3d66140ebfac8b04b upstream.
12
13 With CONFIG_DEBUG_PREEMPT enabled, I get:
14
15 BUG: using smp_processor_id() in preemptible [00000000] code: swapper/0/1
16 caller is debug_smp_processor_id
17 CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.12.0-rc2+ #2
18 Call Trace:
19 dump_stack
20 check_preemption_disabled
21 debug_smp_processor_id
22 save_microcode_in_initrd_amd
23 ? microcode_init
24 save_microcode_in_initrd
25 ...
26
27 because, well, it says it above, we're using smp_processor_id() in
28 preemptible code.
29
30 But passing the CPU number is not really needed. It is only used to
31 determine whether we're on the BSP, and, if so, to save the microcode
32 patch for early loading.
33
34 [ We don't absolutely need to do it on the BSP but we do that
35 customarily there. ]
36
37 Instead, convert that function parameter to a boolean which denotes
38 whether the patch should be saved or not, thereby avoiding the use of
39 smp_processor_id() in preemptible code.
40
41 Signed-off-by: Borislav Petkov <bp@suse.de>
42 Cc: Linus Torvalds <torvalds@linux-foundation.org>
43 Cc: Peter Zijlstra <peterz@infradead.org>
44 Cc: Thomas Gleixner <tglx@linutronix.de>
45 Link: http://lkml.kernel.org/r/20170528200414.31305-1-bp@alien8.de
46 Signed-off-by: Ingo Molnar <mingo@kernel.org>
47 [arnd: rebased to 4.9, after running into warning:
48 arch/x86/kernel/cpu/microcode/amd.c:881:30: self-comparison always evaluates to true]
49 Signed-off-by: Arnd Bergmann <arnd@arndb.de>
50 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
51 ---
52 arch/x86/include/asm/microcode_amd.h | 1 -
53 arch/x86/kernel/cpu/microcode/amd.c | 17 +++++++++++------
54 2 files changed, 11 insertions(+), 7 deletions(-)
55
56 --- a/arch/x86/include/asm/microcode_amd.h
57 +++ b/arch/x86/include/asm/microcode_amd.h
58 @@ -59,7 +59,6 @@ static inline u16 find_equiv_id(struct e
59
60 extern int __apply_microcode_amd(struct microcode_amd *mc_amd);
61 extern int apply_microcode_amd(int cpu);
62 -extern enum ucode_state load_microcode_amd(int cpu, u8 family, const u8 *data, size_t size);
63
64 #define PATCH_MAX_SIZE PAGE_SIZE
65 extern u8 amd_ucode_patch[PATCH_MAX_SIZE];
66 --- a/arch/x86/kernel/cpu/microcode/amd.c
67 +++ b/arch/x86/kernel/cpu/microcode/amd.c
68 @@ -131,6 +131,9 @@ static size_t compute_container_size(u8
69 return size;
70 }
71
72 +static enum ucode_state
73 +load_microcode_amd(bool save, u8 family, const u8 *data, size_t size);
74 +
75 /*
76 * Early load occurs before we can vmalloc(). So we look for the microcode
77 * patch container file in initrd, traverse equivalent cpu table, look for a
78 @@ -438,7 +441,7 @@ int __init save_microcode_in_initrd_amd(
79 eax = cpuid_eax(0x00000001);
80 eax = ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff);
81
82 - ret = load_microcode_amd(smp_processor_id(), eax, container, container_size);
83 + ret = load_microcode_amd(true, eax, container, container_size);
84 if (ret != UCODE_OK)
85 retval = -EINVAL;
86
87 @@ -854,7 +857,8 @@ static enum ucode_state __load_microcode
88 return UCODE_OK;
89 }
90
91 -enum ucode_state load_microcode_amd(int cpu, u8 family, const u8 *data, size_t size)
92 +static enum ucode_state
93 +load_microcode_amd(bool save, u8 family, const u8 *data, size_t size)
94 {
95 enum ucode_state ret;
96
97 @@ -868,8 +872,8 @@ enum ucode_state load_microcode_amd(int
98
99 #ifdef CONFIG_X86_32
100 /* save BSP's matching patch for early load */
101 - if (cpu_data(cpu).cpu_index == boot_cpu_data.cpu_index) {
102 - struct ucode_patch *p = find_patch(cpu);
103 + if (save) {
104 + struct ucode_patch *p = find_patch(0);
105 if (p) {
106 memset(amd_ucode_patch, 0, PATCH_MAX_SIZE);
107 memcpy(amd_ucode_patch, p->data, min_t(u32, ksize(p->data),
108 @@ -901,11 +905,12 @@ static enum ucode_state request_microcod
109 {
110 char fw_name[36] = "amd-ucode/microcode_amd.bin";
111 struct cpuinfo_x86 *c = &cpu_data(cpu);
112 + bool bsp = c->cpu_index == boot_cpu_data.cpu_index;
113 enum ucode_state ret = UCODE_NFOUND;
114 const struct firmware *fw;
115
116 /* reload ucode container only on the boot cpu */
117 - if (!refresh_fw || c->cpu_index != boot_cpu_data.cpu_index)
118 + if (!refresh_fw || !bsp)
119 return UCODE_OK;
120
121 if (c->x86 >= 0x15)
122 @@ -922,7 +927,7 @@ static enum ucode_state request_microcod
123 goto fw_release;
124 }
125
126 - ret = load_microcode_amd(cpu, c->x86, fw->data, fw->size);
127 + ret = load_microcode_amd(bsp, c->x86, fw->data, fw->size);
128
129 fw_release:
130 release_firmware(fw);