Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'microcode_fixes_for_3.18' of git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp into x86/urgent

Pull two fixes for early microcode loader on 32-bit from Borislav Petkov:

- access the dis_ucode_ldr chicken bit properly
- fix patch stashing on AMD on 32-bit

Signed-off-by: Ingo Molnar <mingo@kernel.org>

+15 -11
+14 -10
arch/x86/kernel/cpu/microcode/amd_early.c
··· 108 108 * load_microcode_amd() to save equivalent cpu table and microcode patches in 109 109 * kernel heap memory. 110 110 */ 111 - static void apply_ucode_in_initrd(void *ucode, size_t size) 111 + static void apply_ucode_in_initrd(void *ucode, size_t size, bool save_patch) 112 112 { 113 113 struct equiv_cpu_entry *eq; 114 114 size_t *cont_sz; 115 115 u32 *header; 116 116 u8 *data, **cont; 117 + u8 (*patch)[PATCH_MAX_SIZE]; 117 118 u16 eq_id = 0; 118 119 int offset, left; 119 120 u32 rev, eax, ebx, ecx, edx; ··· 124 123 new_rev = (u32 *)__pa_nodebug(&ucode_new_rev); 125 124 cont_sz = (size_t *)__pa_nodebug(&container_size); 126 125 cont = (u8 **)__pa_nodebug(&container); 126 + patch = (u8 (*)[PATCH_MAX_SIZE])__pa_nodebug(&amd_ucode_patch); 127 127 #else 128 128 new_rev = &ucode_new_rev; 129 129 cont_sz = &container_size; 130 130 cont = &container; 131 + patch = &amd_ucode_patch; 131 132 #endif 132 133 133 134 data = ucode; ··· 216 213 rev = mc->hdr.patch_id; 217 214 *new_rev = rev; 218 215 219 - /* save ucode patch */ 220 - memcpy(amd_ucode_patch, mc, 221 - min_t(u32, header[1], PATCH_MAX_SIZE)); 216 + if (save_patch) 217 + memcpy(patch, mc, 218 + min_t(u32, header[1], PATCH_MAX_SIZE)); 222 219 } 223 220 } 224 221 ··· 249 246 *data = cp.data; 250 247 *size = cp.size; 251 248 252 - apply_ucode_in_initrd(cp.data, cp.size); 249 + apply_ucode_in_initrd(cp.data, cp.size, true); 253 250 } 254 251 255 252 #ifdef CONFIG_X86_32 ··· 266 263 size_t *usize; 267 264 void **ucode; 268 265 269 - mc = (struct microcode_amd *)__pa(amd_ucode_patch); 266 + mc = (struct microcode_amd *)__pa_nodebug(amd_ucode_patch); 270 267 if (mc->hdr.patch_id && mc->hdr.processor_rev_id) { 271 268 __apply_microcode_amd(mc); 272 269 return; ··· 278 275 if (!*ucode || !*usize) 279 276 return; 280 277 281 - apply_ucode_in_initrd(*ucode, *usize); 278 + apply_ucode_in_initrd(*ucode, *usize, false); 282 279 } 283 280 284 281 static void __init collect_cpu_sig_on_bsp(void *arg) ··· 342 339 * AP has a different equivalence ID than BSP, looks like 343 340 * mixed-steppings silicon so go through the ucode blob anew. 344 341 */ 345 - apply_ucode_in_initrd(ucode_cpio.data, ucode_cpio.size); 342 + apply_ucode_in_initrd(ucode_cpio.data, ucode_cpio.size, false); 346 343 } 347 344 } 348 345 #endif ··· 350 347 int __init save_microcode_in_initrd_amd(void) 351 348 { 352 349 unsigned long cont; 350 + int retval = 0; 353 351 enum ucode_state ret; 354 352 u8 *cont_va; 355 353 u32 eax; ··· 391 387 392 388 ret = load_microcode_amd(eax, container, container_size); 393 389 if (ret != UCODE_OK) 394 - return -EINVAL; 390 + retval = -EINVAL; 395 391 396 392 /* 397 393 * This will be freed any msec now, stash patches for the current ··· 400 396 container = NULL; 401 397 container_size = 0; 402 398 403 - return 0; 399 + return retval; 404 400 }
+1 -1
arch/x86/kernel/cpu/microcode/core_early.c
··· 124 124 static bool check_loader_disabled_ap(void) 125 125 { 126 126 #ifdef CONFIG_X86_32 127 - return __pa_nodebug(dis_ucode_ldr); 127 + return *((bool *)__pa_nodebug(&dis_ucode_ldr)); 128 128 #else 129 129 return dis_ucode_ldr; 130 130 #endif