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>
This commit is contained in:
Родитель
6583327c4d
Коммит
75a1ba5b2c
|
@ -285,6 +285,15 @@ static void __init collect_cpu_sig_on_bsp(void *arg)
|
||||||
|
|
||||||
uci->cpu_sig.sig = cpuid_eax(0x00000001);
|
uci->cpu_sig.sig = cpuid_eax(0x00000001);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void __init get_bsp_sig(void)
|
||||||
|
{
|
||||||
|
unsigned int bsp = boot_cpu_data.cpu_index;
|
||||||
|
struct ucode_cpu_info *uci = ucode_cpu_info + bsp;
|
||||||
|
|
||||||
|
if (!uci->cpu_sig.sig)
|
||||||
|
smp_call_function_single(bsp, collect_cpu_sig_on_bsp, NULL, 1);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
void load_ucode_amd_ap(void)
|
void load_ucode_amd_ap(void)
|
||||||
{
|
{
|
||||||
|
@ -337,31 +346,37 @@ void load_ucode_amd_ap(void)
|
||||||
|
|
||||||
int __init save_microcode_in_initrd_amd(void)
|
int __init save_microcode_in_initrd_amd(void)
|
||||||
{
|
{
|
||||||
|
unsigned long cont;
|
||||||
enum ucode_state ret;
|
enum ucode_state ret;
|
||||||
u32 eax;
|
u32 eax;
|
||||||
|
|
||||||
#ifdef CONFIG_X86_32
|
if (!container)
|
||||||
unsigned int bsp = boot_cpu_data.cpu_index;
|
return -EINVAL;
|
||||||
struct ucode_cpu_info *uci = ucode_cpu_info + bsp;
|
|
||||||
|
|
||||||
if (!uci->cpu_sig.sig)
|
#ifdef CONFIG_X86_32
|
||||||
smp_call_function_single(bsp, collect_cpu_sig_on_bsp, NULL, 1);
|
get_bsp_sig();
|
||||||
|
cont = (unsigned long)container;
|
||||||
|
#else
|
||||||
|
/*
|
||||||
|
* We need the physical address of the container for both bitness since
|
||||||
|
* boot_params.hdr.ramdisk_image is a physical address.
|
||||||
|
*/
|
||||||
|
cont = __pa(container);
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Take into account the fact that the ramdisk might get relocated
|
* Take into account the fact that the ramdisk might get relocated and
|
||||||
* and therefore we need to recompute the container's position in
|
* therefore we need to recompute the container's position in virtual
|
||||||
* virtual memory space.
|
* memory space.
|
||||||
*/
|
*/
|
||||||
container = (u8 *)(__va((u32)relocated_ramdisk) +
|
if (relocated_ramdisk)
|
||||||
((u32)container - boot_params.hdr.ramdisk_image));
|
container = (u8 *)(__va(relocated_ramdisk) +
|
||||||
#endif
|
(cont - boot_params.hdr.ramdisk_image));
|
||||||
|
|
||||||
if (ucode_new_rev)
|
if (ucode_new_rev)
|
||||||
pr_info("microcode: updated early to new patch_level=0x%08x\n",
|
pr_info("microcode: updated early to new patch_level=0x%08x\n",
|
||||||
ucode_new_rev);
|
ucode_new_rev);
|
||||||
|
|
||||||
if (!container)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
eax = cpuid_eax(0x00000001);
|
eax = cpuid_eax(0x00000001);
|
||||||
eax = ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff);
|
eax = ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff);
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче