diff options
| author | Borislav Petkov <bp@suse.de> | 2014-02-03 15:41:44 -0500 |
|---|---|---|
| committer | H. Peter Anvin <hpa@zytor.com> | 2014-02-06 14:11:19 -0500 |
| commit | 75a1ba5b2c529db60ca49626bcaf0bddf4548438 (patch) | |
| tree | 3b29eb108807f6e86d67d80f37052c4e7cd1a056 /arch/x86/kernel/cpu/microcode | |
| parent | 6583327c4dd55acbbf2a6f25e775b28b3abf9a42 (diff) | |
x86, microcode, AMD: Unify valid container checks
For additional coverage, BorisO and friends unknowlingly did swap AMD
microcode with Intel microcode blobs in order to see what happens. What
did happen on 32-bit was
[ 5.722656] BUG: unable to handle kernel paging request at be3a6008
[ 5.722693] IP: [<c106d6b4>] load_microcode_amd+0x24/0x3f0
[ 5.722716] *pdpt = 0000000000000000 *pde = 0000000000000000
because there was a valid initrd there but without valid microcode in it
and the container check happened *after* the relocated ramdisk handling
on 32-bit, which was clearly wrong.
While at it, take care of the ramdisk relocation on both 32- and 64-bit
as it is done on both. Also, comment what we're doing because this code
is a bit tricky.
Reported-and-tested-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Link: http://lkml.kernel.org/r/1391460104-7261-1-git-send-email-bp@alien8.de
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'arch/x86/kernel/cpu/microcode')
| -rw-r--r-- | arch/x86/kernel/cpu/microcode/amd_early.c | 43 |
1 files changed, 29 insertions, 14 deletions
diff --git a/arch/x86/kernel/cpu/microcode/amd_early.c b/arch/x86/kernel/cpu/microcode/amd_early.c index 8384c0fa206f..617a9e284245 100644 --- a/arch/x86/kernel/cpu/microcode/amd_early.c +++ b/arch/x86/kernel/cpu/microcode/amd_early.c | |||
| @@ -285,6 +285,15 @@ static void __init collect_cpu_sig_on_bsp(void *arg) | |||
| 285 | 285 | ||
| 286 | uci->cpu_sig.sig = cpuid_eax(0x00000001); | 286 | uci->cpu_sig.sig = cpuid_eax(0x00000001); |
| 287 | } | 287 | } |
| 288 | |||
| 289 | static void __init get_bsp_sig(void) | ||
| 290 | { | ||
| 291 | unsigned int bsp = boot_cpu_data.cpu_index; | ||
| 292 | struct ucode_cpu_info *uci = ucode_cpu_info + bsp; | ||
| 293 | |||
| 294 | if (!uci->cpu_sig.sig) | ||
| 295 | smp_call_function_single(bsp, collect_cpu_sig_on_bsp, NULL, 1); | ||
| 296 | } | ||
| 288 | #else | 297 | #else |
| 289 | void load_ucode_amd_ap(void) | 298 | void load_ucode_amd_ap(void) |
| 290 | { | 299 | { |
| @@ -337,31 +346,37 @@ void load_ucode_amd_ap(void) | |||
| 337 | 346 | ||
| 338 | int __init save_microcode_in_initrd_amd(void) | 347 | int __init save_microcode_in_initrd_amd(void) |
| 339 | { | 348 | { |
| 349 | unsigned long cont; | ||
| 340 | enum ucode_state ret; | 350 | enum ucode_state ret; |
| 341 | u32 eax; | 351 | u32 eax; |
| 342 | 352 | ||
| 343 | #ifdef CONFIG_X86_32 | 353 | if (!container) |
| 344 | unsigned int bsp = boot_cpu_data.cpu_index; | 354 | return -EINVAL; |
| 345 | struct ucode_cpu_info *uci = ucode_cpu_info + bsp; | ||
| 346 | |||
| 347 | if (!uci->cpu_sig.sig) | ||
| 348 | smp_call_function_single(bsp, collect_cpu_sig_on_bsp, NULL, 1); | ||
| 349 | 355 | ||
| 356 | #ifdef CONFIG_X86_32 | ||
| 357 | get_bsp_sig(); | ||
| 358 | cont = (unsigned long)container; | ||
| 359 | #else | ||
| 350 | /* | 360 | /* |
| 351 | * Take into account the fact that the ramdisk might get relocated | 361 | * We need the physical address of the container for both bitness since |
| 352 | * and therefore we need to recompute the container's position in | 362 | * boot_params.hdr.ramdisk_image is a physical address. |
| 353 | * virtual memory space. | ||
| 354 | */ | 363 | */ |
| 355 | container = (u8 *)(__va((u32)relocated_ramdisk) + | 364 | cont = __pa(container); |
| 356 | ((u32)container - boot_params.hdr.ramdisk_image)); | ||
| 357 | #endif | 365 | #endif |
| 366 | |||
| 367 | /* | ||
| 368 | * Take into account the fact that the ramdisk might get relocated and | ||
| 369 | * therefore we need to recompute the container's position in virtual | ||
| 370 | * memory space. | ||
| 371 | */ | ||
| 372 | if (relocated_ramdisk) | ||
| 373 | container = (u8 *)(__va(relocated_ramdisk) + | ||
| 374 | (cont - boot_params.hdr.ramdisk_image)); | ||
| 375 | |||
| 358 | if (ucode_new_rev) | 376 | if (ucode_new_rev) |
| 359 | pr_info("microcode: updated early to new patch_level=0x%08x\n", | 377 | pr_info("microcode: updated early to new patch_level=0x%08x\n", |
| 360 | ucode_new_rev); | 378 | ucode_new_rev); |
| 361 | 379 | ||
| 362 | if (!container) | ||
| 363 | return -EINVAL; | ||
| 364 | |||
| 365 | eax = cpuid_eax(0x00000001); | 380 | eax = cpuid_eax(0x00000001); |
| 366 | eax = ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff); | 381 | eax = ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff); |
| 367 | 382 | ||
