diff options
author | Jacob Shin <jacob.shin@amd.com> | 2013-06-20 10:52:50 -0400 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2013-06-26 17:55:37 -0400 |
commit | 9608d33b8210c993af4430d661a6474946480c9b (patch) | |
tree | da966e44d9cc8a01e552cb26a9e964d4ca7fa769 | |
parent | cd1c32ca969ebfd65e61312c988223bb14f09c2e (diff) |
x86, microcode, amd: Another early loading fixup
commit cd1c32ca969ebfd65e61312c988223bb14f09c2e is an early premature
rendition of the patch. Augment it with this delta patch to:
* correctly mark offset and size of the matching bin file
* use __pa instead of __pa_nodebug during AP load
* check for !initrd_start before using it
Signed-off-by: Jacob Shin <jacob.shin@amd.com>
Link: http://lkml.kernel.org/r/20130620152414.GA6676@jshin-Toonie
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
-rw-r--r-- | arch/x86/kernel/microcode_amd_early.c | 40 |
1 files changed, 24 insertions, 16 deletions
diff --git a/arch/x86/kernel/microcode_amd_early.c b/arch/x86/kernel/microcode_amd_early.c index 4c593c276114..1ac6e9aee766 100644 --- a/arch/x86/kernel/microcode_amd_early.c +++ b/arch/x86/kernel/microcode_amd_early.c | |||
@@ -143,13 +143,17 @@ static void __cpuinit apply_ucode_in_initrd(void *ucode, size_t size) | |||
143 | left -= offset; | 143 | left -= offset; |
144 | } | 144 | } |
145 | 145 | ||
146 | offset = data - (u8 *)ucode; | 146 | /* mark where the next microcode container file starts */ |
147 | offset = data - (u8 *)ucode; | ||
147 | *uoffset += offset; | 148 | *uoffset += offset; |
148 | *usize -= offset; | 149 | *usize -= offset; |
150 | ucode = data; | ||
149 | } | 151 | } |
150 | 152 | ||
151 | if (!eq_id) | 153 | if (!eq_id) { |
154 | *usize = 0; | ||
152 | return; | 155 | return; |
156 | } | ||
153 | 157 | ||
154 | /* find ucode and update if needed */ | 158 | /* find ucode and update if needed */ |
155 | 159 | ||
@@ -166,15 +170,21 @@ static void __cpuinit apply_ucode_in_initrd(void *ucode, size_t size) | |||
166 | mc = (struct microcode_amd *)(data + SECTION_HDR_SIZE); | 170 | mc = (struct microcode_amd *)(data + SECTION_HDR_SIZE); |
167 | if (eq_id == mc->hdr.processor_rev_id && rev < mc->hdr.patch_id) | 171 | if (eq_id == mc->hdr.processor_rev_id && rev < mc->hdr.patch_id) |
168 | if (__apply_microcode_amd(mc) == 0) { | 172 | if (__apply_microcode_amd(mc) == 0) { |
169 | if (!(*new_rev)) | 173 | rev = mc->hdr.patch_id; |
170 | *new_rev = mc->hdr.patch_id; | 174 | *new_rev = rev; |
171 | break; | ||
172 | } | 175 | } |
173 | 176 | ||
174 | offset = header[1] + SECTION_HDR_SIZE; | 177 | offset = header[1] + SECTION_HDR_SIZE; |
175 | data += offset; | 178 | data += offset; |
176 | left -= offset; | 179 | left -= offset; |
177 | } | 180 | } |
181 | |||
182 | /* mark where this microcode container file ends */ | ||
183 | offset = *usize - (data - (u8 *)ucode); | ||
184 | *usize -= offset; | ||
185 | |||
186 | if (!(*new_rev)) | ||
187 | *usize = 0; | ||
178 | } | 188 | } |
179 | 189 | ||
180 | void __init load_ucode_amd_bsp(void) | 190 | void __init load_ucode_amd_bsp(void) |
@@ -204,19 +214,20 @@ void __cpuinit load_ucode_amd_ap(void) | |||
204 | size_t *usize; | 214 | size_t *usize; |
205 | void *ucode; | 215 | void *ucode; |
206 | 216 | ||
207 | mc = (struct microcode_amd *)__pa_nodebug(amd_bsp_mpb); | 217 | mc = (struct microcode_amd *)__pa(amd_bsp_mpb); |
208 | if (mc->hdr.patch_id && mc->hdr.processor_rev_id) { | 218 | if (mc->hdr.patch_id && mc->hdr.processor_rev_id) { |
209 | __apply_microcode_amd(mc); | 219 | __apply_microcode_amd(mc); |
210 | return; | 220 | return; |
211 | } | 221 | } |
212 | 222 | ||
213 | initrd = (unsigned long *)__pa_nodebug(&initrd_start); | 223 | initrd = (unsigned long *)__pa(&initrd_start); |
214 | uoffset = (unsigned long *)__pa_nodebug(&ucode_offset); | 224 | uoffset = (unsigned long *)__pa(&ucode_offset); |
215 | usize = (size_t *)__pa_nodebug(&ucode_size); | 225 | usize = (size_t *)__pa(&ucode_size); |
216 | if (!*usize) | 226 | |
227 | if (!*usize || !*initrd) | ||
217 | return; | 228 | return; |
218 | 229 | ||
219 | ucode = (void *)((unsigned long)__pa_nodebug(*initrd) + *uoffset); | 230 | ucode = (void *)((unsigned long)__pa(*initrd) + *uoffset); |
220 | apply_ucode_in_initrd(ucode, *usize); | 231 | apply_ucode_in_initrd(ucode, *usize); |
221 | } | 232 | } |
222 | 233 | ||
@@ -250,7 +261,7 @@ void __cpuinit load_ucode_amd_ap(void) | |||
250 | if (cpu && !ucode_loaded) { | 261 | if (cpu && !ucode_loaded) { |
251 | void *ucode; | 262 | void *ucode; |
252 | 263 | ||
253 | if (!ucode_size) | 264 | if (!ucode_size || !initrd_start) |
254 | return; | 265 | return; |
255 | 266 | ||
256 | ucode = (void *)(initrd_start + ucode_offset); | 267 | ucode = (void *)(initrd_start + ucode_offset); |
@@ -278,10 +289,7 @@ int __init save_microcode_in_initrd_amd(void) | |||
278 | pr_info("microcode: updated early to new patch_level=0x%08x\n", | 289 | pr_info("microcode: updated early to new patch_level=0x%08x\n", |
279 | ucode_new_rev); | 290 | ucode_new_rev); |
280 | 291 | ||
281 | if (ucode_loaded) | 292 | if (ucode_loaded || !ucode_size || !initrd_start) |
282 | return 0; | ||
283 | |||
284 | if (!ucode_size) | ||
285 | return 0; | 293 | return 0; |
286 | 294 | ||
287 | ucode = (void *)(initrd_start + ucode_offset); | 295 | ucode = (void *)(initrd_start + ucode_offset); |