Skip to content

Commit

Permalink
x86, microcode, AMD: Fix ucode patch stashing on 32-bit
Browse files Browse the repository at this point in the history
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: 5335ba5 ("x86, microcode, AMD: Fix early ucode loading")
Cc: <stable@vger.kernel.org> # v3.13+
Signed-off-by: Borislav Petkov <bp@suse.de>
  • Loading branch information
Borislav Petkov committed Nov 10, 2014
1 parent 85be07c commit c0a717f
Showing 1 changed file with 14 additions and 10 deletions.
24 changes: 14 additions & 10 deletions arch/x86/kernel/cpu/microcode/amd_early.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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));
}
}

Expand Down Expand Up @@ -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
Expand All @@ -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;
Expand All @@ -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)
Expand Down Expand Up @@ -339,14 +342,15 @@ 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

int __init save_microcode_in_initrd_amd(void)
{
unsigned long cont;
int retval = 0;
enum ucode_state ret;
u8 *cont_va;
u32 eax;
Expand Down Expand Up @@ -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
Expand All @@ -396,5 +400,5 @@ int __init save_microcode_in_initrd_amd(void)
container = NULL;
container_size = 0;

return 0;
return retval;
}

0 comments on commit c0a717f

Please sign in to comment.