Skip to content

Commit 75a1ba5

Browse files
suryasaimadhuH. Peter Anvin
authored andcommitted
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 <[email protected]> Signed-off-by: Borislav Petkov <[email protected]> Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: H. Peter Anvin <[email protected]>
1 parent 6583327 commit 75a1ba5

File tree

1 file changed

+29
-14
lines changed

1 file changed

+29
-14
lines changed

arch/x86/kernel/cpu/microcode/amd_early.c

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,15 @@ static void __init collect_cpu_sig_on_bsp(void *arg)
285285

286286
uci->cpu_sig.sig = cpuid_eax(0x00000001);
287287
}
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+
}
288297
#else
289298
void load_ucode_amd_ap(void)
290299
{
@@ -337,31 +346,37 @@ void load_ucode_amd_ap(void)
337346

338347
int __init save_microcode_in_initrd_amd(void)
339348
{
349+
unsigned long cont;
340350
enum ucode_state ret;
341351
u32 eax;
342352

343-
#ifdef CONFIG_X86_32
344-
unsigned int bsp = boot_cpu_data.cpu_index;
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);
353+
if (!container)
354+
return -EINVAL;
349355

356+
#ifdef CONFIG_X86_32
357+
get_bsp_sig();
358+
cont = (unsigned long)container;
359+
#else
350360
/*
351-
* Take into account the fact that the ramdisk might get relocated
352-
* and therefore we need to recompute the container's position in
353-
* virtual memory space.
361+
* We need the physical address of the container for both bitness since
362+
* boot_params.hdr.ramdisk_image is a physical address.
354363
*/
355-
container = (u8 *)(__va((u32)relocated_ramdisk) +
356-
((u32)container - boot_params.hdr.ramdisk_image));
364+
cont = __pa(container);
357365
#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+
358376
if (ucode_new_rev)
359377
pr_info("microcode: updated early to new patch_level=0x%08x\n",
360378
ucode_new_rev);
361379

362-
if (!container)
363-
return -EINVAL;
364-
365380
eax = cpuid_eax(0x00000001);
366381
eax = ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff);
367382

0 commit comments

Comments
 (0)