Commit 0cafa3e7 authored by Ingo Molnar's avatar Ingo Molnar

Merge tag 'microcode_fixes_for_3.18' of...

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: default avatarIngo Molnar <mingo@kernel.org>
parents 54279552 c0a717f2
...@@ -108,12 +108,13 @@ static size_t compute_container_size(u8 *data, u32 total_size) ...@@ -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 * load_microcode_amd() to save equivalent cpu table and microcode patches in
* kernel heap memory. * 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; struct equiv_cpu_entry *eq;
size_t *cont_sz; size_t *cont_sz;
u32 *header; u32 *header;
u8 *data, **cont; u8 *data, **cont;
u8 (*patch)[PATCH_MAX_SIZE];
u16 eq_id = 0; u16 eq_id = 0;
int offset, left; int offset, left;
u32 rev, eax, ebx, ecx, edx; u32 rev, eax, ebx, ecx, edx;
...@@ -123,10 +124,12 @@ static void apply_ucode_in_initrd(void *ucode, size_t size) ...@@ -123,10 +124,12 @@ static void apply_ucode_in_initrd(void *ucode, size_t size)
new_rev = (u32 *)__pa_nodebug(&ucode_new_rev); new_rev = (u32 *)__pa_nodebug(&ucode_new_rev);
cont_sz = (size_t *)__pa_nodebug(&container_size); cont_sz = (size_t *)__pa_nodebug(&container_size);
cont = (u8 **)__pa_nodebug(&container); cont = (u8 **)__pa_nodebug(&container);
patch = (u8 (*)[PATCH_MAX_SIZE])__pa_nodebug(&amd_ucode_patch);
#else #else
new_rev = &ucode_new_rev; new_rev = &ucode_new_rev;
cont_sz = &container_size; cont_sz = &container_size;
cont = &container; cont = &container;
patch = &amd_ucode_patch;
#endif #endif
data = ucode; data = ucode;
...@@ -213,9 +216,9 @@ static void apply_ucode_in_initrd(void *ucode, size_t size) ...@@ -213,9 +216,9 @@ static void apply_ucode_in_initrd(void *ucode, size_t size)
rev = mc->hdr.patch_id; rev = mc->hdr.patch_id;
*new_rev = rev; *new_rev = rev;
/* save ucode patch */ if (save_patch)
memcpy(amd_ucode_patch, mc, memcpy(patch, mc,
min_t(u32, header[1], PATCH_MAX_SIZE)); min_t(u32, header[1], PATCH_MAX_SIZE));
} }
} }
...@@ -246,7 +249,7 @@ void __init load_ucode_amd_bsp(void) ...@@ -246,7 +249,7 @@ void __init load_ucode_amd_bsp(void)
*data = cp.data; *data = cp.data;
*size = cp.size; *size = cp.size;
apply_ucode_in_initrd(cp.data, cp.size); apply_ucode_in_initrd(cp.data, cp.size, true);
} }
#ifdef CONFIG_X86_32 #ifdef CONFIG_X86_32
...@@ -263,7 +266,7 @@ void load_ucode_amd_ap(void) ...@@ -263,7 +266,7 @@ void load_ucode_amd_ap(void)
size_t *usize; size_t *usize;
void **ucode; 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) { if (mc->hdr.patch_id && mc->hdr.processor_rev_id) {
__apply_microcode_amd(mc); __apply_microcode_amd(mc);
return; return;
...@@ -275,7 +278,7 @@ void load_ucode_amd_ap(void) ...@@ -275,7 +278,7 @@ void load_ucode_amd_ap(void)
if (!*ucode || !*usize) if (!*ucode || !*usize)
return; return;
apply_ucode_in_initrd(*ucode, *usize); apply_ucode_in_initrd(*ucode, *usize, false);
} }
static void __init collect_cpu_sig_on_bsp(void *arg) static void __init collect_cpu_sig_on_bsp(void *arg)
...@@ -339,7 +342,7 @@ void load_ucode_amd_ap(void) ...@@ -339,7 +342,7 @@ void load_ucode_amd_ap(void)
* AP has a different equivalence ID than BSP, looks like * AP has a different equivalence ID than BSP, looks like
* mixed-steppings silicon so go through the ucode blob anew. * 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 #endif
...@@ -347,6 +350,7 @@ void load_ucode_amd_ap(void) ...@@ -347,6 +350,7 @@ 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; unsigned long cont;
int retval = 0;
enum ucode_state ret; enum ucode_state ret;
u8 *cont_va; u8 *cont_va;
u32 eax; u32 eax;
...@@ -387,7 +391,7 @@ int __init save_microcode_in_initrd_amd(void) ...@@ -387,7 +391,7 @@ int __init save_microcode_in_initrd_amd(void)
ret = load_microcode_amd(eax, container, container_size); ret = load_microcode_amd(eax, container, container_size);
if (ret != UCODE_OK) if (ret != UCODE_OK)
return -EINVAL; retval = -EINVAL;
/* /*
* This will be freed any msec now, stash patches for the current * This will be freed any msec now, stash patches for the current
...@@ -396,5 +400,5 @@ int __init save_microcode_in_initrd_amd(void) ...@@ -396,5 +400,5 @@ int __init save_microcode_in_initrd_amd(void)
container = NULL; container = NULL;
container_size = 0; container_size = 0;
return 0; return retval;
} }
...@@ -124,7 +124,7 @@ void __init load_ucode_bsp(void) ...@@ -124,7 +124,7 @@ void __init load_ucode_bsp(void)
static bool check_loader_disabled_ap(void) static bool check_loader_disabled_ap(void)
{ {
#ifdef CONFIG_X86_32 #ifdef CONFIG_X86_32
return __pa_nodebug(dis_ucode_ldr); return *((bool *)__pa_nodebug(&dis_ucode_ldr));
#else #else
return dis_ucode_ldr; return dis_ucode_ldr;
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment