x86, microcode, AMD: Fix ucode patch stashing on 32-bit
Save the patch while we're running on the BSP instead of later, before
the initrd has been jettisoned. More importantly, on 32-bit we need to
access the physical address instead of the virtual.
This way we actually do find it on the APs instead of having to go
through the initrd each time.
Tested-by: Richard Hendershot <rshendershot@mchsi.com>
Fixes: 5335ba5cf4
("x86, microcode, AMD: Fix early ucode loading")
Cc: <stable@vger.kernel.org> # v3.13+
Signed-off-by: Borislav Petkov <bp@suse.de>
This commit is contained in:
Родитель
85be07c324
Коммит
c0a717f23d
|
@ -108,12 +108,13 @@ static size_t compute_container_size(u8 *data, u32 total_size)
|
|||
* load_microcode_amd() to save equivalent cpu table and microcode patches in
|
||||
* kernel heap memory.
|
||||
*/
|
||||
static void apply_ucode_in_initrd(void *ucode, size_t size)
|
||||
static void apply_ucode_in_initrd(void *ucode, size_t size, bool save_patch)
|
||||
{
|
||||
struct equiv_cpu_entry *eq;
|
||||
size_t *cont_sz;
|
||||
u32 *header;
|
||||
u8 *data, **cont;
|
||||
u8 (*patch)[PATCH_MAX_SIZE];
|
||||
u16 eq_id = 0;
|
||||
int offset, left;
|
||||
u32 rev, eax, ebx, ecx, edx;
|
||||
|
@ -123,10 +124,12 @@ static void apply_ucode_in_initrd(void *ucode, size_t size)
|
|||
new_rev = (u32 *)__pa_nodebug(&ucode_new_rev);
|
||||
cont_sz = (size_t *)__pa_nodebug(&container_size);
|
||||
cont = (u8 **)__pa_nodebug(&container);
|
||||
patch = (u8 (*)[PATCH_MAX_SIZE])__pa_nodebug(&amd_ucode_patch);
|
||||
#else
|
||||
new_rev = &ucode_new_rev;
|
||||
cont_sz = &container_size;
|
||||
cont = &container;
|
||||
patch = &amd_ucode_patch;
|
||||
#endif
|
||||
|
||||
data = ucode;
|
||||
|
@ -213,9 +216,9 @@ static void apply_ucode_in_initrd(void *ucode, size_t size)
|
|||
rev = mc->hdr.patch_id;
|
||||
*new_rev = rev;
|
||||
|
||||
/* save ucode patch */
|
||||
memcpy(amd_ucode_patch, mc,
|
||||
min_t(u32, header[1], PATCH_MAX_SIZE));
|
||||
if (save_patch)
|
||||
memcpy(patch, mc,
|
||||
min_t(u32, header[1], PATCH_MAX_SIZE));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -246,7 +249,7 @@ void __init load_ucode_amd_bsp(void)
|
|||
*data = cp.data;
|
||||
*size = cp.size;
|
||||
|
||||
apply_ucode_in_initrd(cp.data, cp.size);
|
||||
apply_ucode_in_initrd(cp.data, cp.size, true);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
|
@ -263,7 +266,7 @@ void load_ucode_amd_ap(void)
|
|||
size_t *usize;
|
||||
void **ucode;
|
||||
|
||||
mc = (struct microcode_amd *)__pa(amd_ucode_patch);
|
||||
mc = (struct microcode_amd *)__pa_nodebug(amd_ucode_patch);
|
||||
if (mc->hdr.patch_id && mc->hdr.processor_rev_id) {
|
||||
__apply_microcode_amd(mc);
|
||||
return;
|
||||
|
@ -275,7 +278,7 @@ void load_ucode_amd_ap(void)
|
|||
if (!*ucode || !*usize)
|
||||
return;
|
||||
|
||||
apply_ucode_in_initrd(*ucode, *usize);
|
||||
apply_ucode_in_initrd(*ucode, *usize, false);
|
||||
}
|
||||
|
||||
static void __init collect_cpu_sig_on_bsp(void *arg)
|
||||
|
@ -339,7 +342,7 @@ void load_ucode_amd_ap(void)
|
|||
* AP has a different equivalence ID than BSP, looks like
|
||||
* mixed-steppings silicon so go through the ucode blob anew.
|
||||
*/
|
||||
apply_ucode_in_initrd(ucode_cpio.data, ucode_cpio.size);
|
||||
apply_ucode_in_initrd(ucode_cpio.data, ucode_cpio.size, false);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -347,6 +350,7 @@ void load_ucode_amd_ap(void)
|
|||
int __init save_microcode_in_initrd_amd(void)
|
||||
{
|
||||
unsigned long cont;
|
||||
int retval = 0;
|
||||
enum ucode_state ret;
|
||||
u8 *cont_va;
|
||||
u32 eax;
|
||||
|
@ -387,7 +391,7 @@ int __init save_microcode_in_initrd_amd(void)
|
|||
|
||||
ret = load_microcode_amd(eax, container, container_size);
|
||||
if (ret != UCODE_OK)
|
||||
return -EINVAL;
|
||||
retval = -EINVAL;
|
||||
|
||||
/*
|
||||
* This will be freed any msec now, stash patches for the current
|
||||
|
@ -396,5 +400,5 @@ int __init save_microcode_in_initrd_amd(void)
|
|||
container = NULL;
|
||||
container_size = 0;
|
||||
|
||||
return 0;
|
||||
return retval;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче