aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/cpu/microcode/amd_early.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/cpu/microcode/amd_early.c')
-rw-r--r--arch/x86/kernel/cpu/microcode/amd_early.c33
1 files changed, 21 insertions, 12 deletions
diff --git a/arch/x86/kernel/cpu/microcode/amd_early.c b/arch/x86/kernel/cpu/microcode/amd_early.c
index 7aa1acc79789..06674473b0e6 100644
--- a/arch/x86/kernel/cpu/microcode/amd_early.c
+++ b/arch/x86/kernel/cpu/microcode/amd_early.c
@@ -108,12 +108,13 @@ static size_t compute_container_size(u8 *data, u32 total_size)
108 * load_microcode_amd() to save equivalent cpu table and microcode patches in 108 * load_microcode_amd() to save equivalent cpu table and microcode patches in
109 * kernel heap memory. 109 * kernel heap memory.
110 */ 110 */
111static void apply_ucode_in_initrd(void *ucode, size_t size) 111static void apply_ucode_in_initrd(void *ucode, size_t size, bool save_patch)
112{ 112{
113 struct equiv_cpu_entry *eq; 113 struct equiv_cpu_entry *eq;
114 size_t *cont_sz; 114 size_t *cont_sz;
115 u32 *header; 115 u32 *header;
116 u8 *data, **cont; 116 u8 *data, **cont;
117 u8 (*patch)[PATCH_MAX_SIZE];
117 u16 eq_id = 0; 118 u16 eq_id = 0;
118 int offset, left; 119 int offset, left;
119 u32 rev, eax, ebx, ecx, edx; 120 u32 rev, eax, ebx, ecx, edx;
@@ -123,10 +124,12 @@ static void apply_ucode_in_initrd(void *ucode, size_t size)
123 new_rev = (u32 *)__pa_nodebug(&ucode_new_rev); 124 new_rev = (u32 *)__pa_nodebug(&ucode_new_rev);
124 cont_sz = (size_t *)__pa_nodebug(&container_size); 125 cont_sz = (size_t *)__pa_nodebug(&container_size);
125 cont = (u8 **)__pa_nodebug(&container); 126 cont = (u8 **)__pa_nodebug(&container);
127 patch = (u8 (*)[PATCH_MAX_SIZE])__pa_nodebug(&amd_ucode_patch);
126#else 128#else
127 new_rev = &ucode_new_rev; 129 new_rev = &ucode_new_rev;
128 cont_sz = &container_size; 130 cont_sz = &container_size;
129 cont = &container; 131 cont = &container;
132 patch = &amd_ucode_patch;
130#endif 133#endif
131 134
132 data = ucode; 135 data = ucode;
@@ -213,9 +216,9 @@ static void apply_ucode_in_initrd(void *ucode, size_t size)
213 rev = mc->hdr.patch_id; 216 rev = mc->hdr.patch_id;
214 *new_rev = rev; 217 *new_rev = rev;
215 218
216 /* save ucode patch */ 219 if (save_patch)
217 memcpy(amd_ucode_patch, mc, 220 memcpy(patch, mc,
218 min_t(u32, header[1], PATCH_MAX_SIZE)); 221 min_t(u32, header[1], PATCH_MAX_SIZE));
219 } 222 }
220 } 223 }
221 224
@@ -246,7 +249,7 @@ void __init load_ucode_amd_bsp(void)
246 *data = cp.data; 249 *data = cp.data;
247 *size = cp.size; 250 *size = cp.size;
248 251
249 apply_ucode_in_initrd(cp.data, cp.size); 252 apply_ucode_in_initrd(cp.data, cp.size, true);
250} 253}
251 254
252#ifdef CONFIG_X86_32 255#ifdef CONFIG_X86_32
@@ -263,7 +266,7 @@ void load_ucode_amd_ap(void)
263 size_t *usize; 266 size_t *usize;
264 void **ucode; 267 void **ucode;
265 268
266 mc = (struct microcode_amd *)__pa(amd_ucode_patch); 269 mc = (struct microcode_amd *)__pa_nodebug(amd_ucode_patch);
267 if (mc->hdr.patch_id && mc->hdr.processor_rev_id) { 270 if (mc->hdr.patch_id && mc->hdr.processor_rev_id) {
268 __apply_microcode_amd(mc); 271 __apply_microcode_amd(mc);
269 return; 272 return;
@@ -275,7 +278,7 @@ void load_ucode_amd_ap(void)
275 if (!*ucode || !*usize) 278 if (!*ucode || !*usize)
276 return; 279 return;
277 280
278 apply_ucode_in_initrd(*ucode, *usize); 281 apply_ucode_in_initrd(*ucode, *usize, false);
279} 282}
280 283
281static void __init collect_cpu_sig_on_bsp(void *arg) 284static void __init collect_cpu_sig_on_bsp(void *arg)
@@ -339,7 +342,7 @@ void load_ucode_amd_ap(void)
339 * AP has a different equivalence ID than BSP, looks like 342 * AP has a different equivalence ID than BSP, looks like
340 * mixed-steppings silicon so go through the ucode blob anew. 343 * mixed-steppings silicon so go through the ucode blob anew.
341 */ 344 */
342 apply_ucode_in_initrd(ucode_cpio.data, ucode_cpio.size); 345 apply_ucode_in_initrd(ucode_cpio.data, ucode_cpio.size, false);
343 } 346 }
344} 347}
345#endif 348#endif
@@ -347,7 +350,9 @@ void load_ucode_amd_ap(void)
347int __init save_microcode_in_initrd_amd(void) 350int __init save_microcode_in_initrd_amd(void)
348{ 351{
349 unsigned long cont; 352 unsigned long cont;
353 int retval = 0;
350 enum ucode_state ret; 354 enum ucode_state ret;
355 u8 *cont_va;
351 u32 eax; 356 u32 eax;
352 357
353 if (!container) 358 if (!container)
@@ -355,13 +360,15 @@ int __init save_microcode_in_initrd_amd(void)
355 360
356#ifdef CONFIG_X86_32 361#ifdef CONFIG_X86_32
357 get_bsp_sig(); 362 get_bsp_sig();
358 cont = (unsigned long)container; 363 cont = (unsigned long)container;
364 cont_va = __va(container);
359#else 365#else
360 /* 366 /*
361 * We need the physical address of the container for both bitness since 367 * We need the physical address of the container for both bitness since
362 * boot_params.hdr.ramdisk_image is a physical address. 368 * boot_params.hdr.ramdisk_image is a physical address.
363 */ 369 */
364 cont = __pa(container); 370 cont = __pa(container);
371 cont_va = container;
365#endif 372#endif
366 373
367 /* 374 /*
@@ -372,6 +379,8 @@ int __init save_microcode_in_initrd_amd(void)
372 if (relocated_ramdisk) 379 if (relocated_ramdisk)
373 container = (u8 *)(__va(relocated_ramdisk) + 380 container = (u8 *)(__va(relocated_ramdisk) +
374 (cont - boot_params.hdr.ramdisk_image)); 381 (cont - boot_params.hdr.ramdisk_image));
382 else
383 container = cont_va;
375 384
376 if (ucode_new_rev) 385 if (ucode_new_rev)
377 pr_info("microcode: updated early to new patch_level=0x%08x\n", 386 pr_info("microcode: updated early to new patch_level=0x%08x\n",
@@ -382,7 +391,7 @@ int __init save_microcode_in_initrd_amd(void)
382 391
383 ret = load_microcode_amd(eax, container, container_size); 392 ret = load_microcode_amd(eax, container, container_size);
384 if (ret != UCODE_OK) 393 if (ret != UCODE_OK)
385 return -EINVAL; 394 retval = -EINVAL;
386 395
387 /* 396 /*
388 * This will be freed any msec now, stash patches for the current 397 * This will be freed any msec now, stash patches for the current
@@ -391,5 +400,5 @@ int __init save_microcode_in_initrd_amd(void)
391 container = NULL; 400 container = NULL;
392 container_size = 0; 401 container_size = 0;
393 402
394 return 0; 403 return retval;
395} 404}