lkml.org 
[lkml]   [2018]   [Apr]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.14 095/138] x86/microcode: Attempt late loading only when new microcode is present
    Date
    4.14-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Borislav Petkov <bp@suse.de>

    commit 2613f36ed965d0e5a595a1d931fd3b480e82d6fd upstream.

    Return UCODE_NEW from the scanning functions to denote that new microcode
    was found and only then attempt the expensive synchronization dance.

    Reported-by: Emanuel Czirai <xftroxgpx@protonmail.com>
    Signed-off-by: Borislav Petkov <bp@suse.de>
    Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
    Tested-by: Emanuel Czirai <xftroxgpx@protonmail.com>
    Tested-by: Ashok Raj <ashok.raj@intel.com>
    Tested-by: Tom Lendacky <thomas.lendacky@amd.com>
    Link: https://lkml.kernel.org/r/20180314183615.17629-1-bp@alien8.de
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    arch/x86/include/asm/microcode.h | 1 +
    arch/x86/kernel/cpu/microcode/amd.c | 34 +++++++++++++++++++++-------------
    arch/x86/kernel/cpu/microcode/core.c | 8 +++-----
    arch/x86/kernel/cpu/microcode/intel.c | 4 +++-
    4 files changed, 28 insertions(+), 19 deletions(-)

    --- a/arch/x86/include/asm/microcode.h
    +++ b/arch/x86/include/asm/microcode.h
    @@ -39,6 +39,7 @@ struct device;

    enum ucode_state {
    UCODE_OK = 0,
    + UCODE_NEW,
    UCODE_UPDATED,
    UCODE_NFOUND,
    UCODE_ERROR,
    --- a/arch/x86/kernel/cpu/microcode/amd.c
    +++ b/arch/x86/kernel/cpu/microcode/amd.c
    @@ -339,7 +339,7 @@ int __init save_microcode_in_initrd_amd(
    return -EINVAL;

    ret = load_microcode_amd(true, x86_family(cpuid_1_eax), desc.data, desc.size);
    - if (ret != UCODE_OK)
    + if (ret > UCODE_UPDATED)
    return -EINVAL;

    return 0;
    @@ -683,27 +683,35 @@ static enum ucode_state __load_microcode
    static enum ucode_state
    load_microcode_amd(bool save, u8 family, const u8 *data, size_t size)
    {
    + struct ucode_patch *p;
    enum ucode_state ret;

    /* free old equiv table */
    free_equiv_cpu_table();

    ret = __load_microcode_amd(family, data, size);
    -
    - if (ret != UCODE_OK)
    + if (ret != UCODE_OK) {
    cleanup();
    + return ret;
    + }

    -#ifdef CONFIG_X86_32
    - /* save BSP's matching patch for early load */
    - if (save) {
    - struct ucode_patch *p = find_patch(0);
    - if (p) {
    - memset(amd_ucode_patch, 0, PATCH_MAX_SIZE);
    - memcpy(amd_ucode_patch, p->data, min_t(u32, ksize(p->data),
    - PATCH_MAX_SIZE));
    - }
    + p = find_patch(0);
    + if (!p) {
    + return ret;
    + } else {
    + if (boot_cpu_data.microcode == p->patch_id)
    + return ret;
    +
    + ret = UCODE_NEW;
    }
    -#endif
    +
    + /* save BSP's matching patch for early load */
    + if (!save)
    + return ret;
    +
    + memset(amd_ucode_patch, 0, PATCH_MAX_SIZE);
    + memcpy(amd_ucode_patch, p->data, min_t(u32, ksize(p->data), PATCH_MAX_SIZE));
    +
    return ret;
    }

    --- a/arch/x86/kernel/cpu/microcode/core.c
    +++ b/arch/x86/kernel/cpu/microcode/core.c
    @@ -607,7 +607,7 @@ static ssize_t reload_store(struct devic
    return size;

    tmp_ret = microcode_ops->request_microcode_fw(bsp, &microcode_pdev->dev, true);
    - if (tmp_ret != UCODE_OK)
    + if (tmp_ret != UCODE_NEW)
    return size;

    get_online_cpus();
    @@ -691,10 +691,8 @@ static enum ucode_state microcode_init_c
    if (system_state != SYSTEM_RUNNING)
    return UCODE_NFOUND;

    - ustate = microcode_ops->request_microcode_fw(cpu, &microcode_pdev->dev,
    - refresh_fw);
    -
    - if (ustate == UCODE_OK) {
    + ustate = microcode_ops->request_microcode_fw(cpu, &microcode_pdev->dev, refresh_fw);
    + if (ustate == UCODE_NEW) {
    pr_debug("CPU%d updated upon init\n", cpu);
    apply_microcode_on_target(cpu);
    }
    --- a/arch/x86/kernel/cpu/microcode/intel.c
    +++ b/arch/x86/kernel/cpu/microcode/intel.c
    @@ -862,6 +862,7 @@ static enum ucode_state generic_load_mic
    unsigned int leftover = size;
    unsigned int curr_mc_size = 0, new_mc_size = 0;
    unsigned int csig, cpf;
    + enum ucode_state ret = UCODE_OK;

    while (leftover) {
    struct microcode_header_intel mc_header;
    @@ -903,6 +904,7 @@ static enum ucode_state generic_load_mic
    new_mc = mc;
    new_mc_size = mc_size;
    mc = NULL; /* trigger new vmalloc */
    + ret = UCODE_NEW;
    }

    ucode_ptr += mc_size;
    @@ -932,7 +934,7 @@ static enum ucode_state generic_load_mic
    pr_debug("CPU%d found a matching microcode update with version 0x%x (current=0x%x)\n",
    cpu, new_rev, uci->cpu_sig.rev);

    - return UCODE_OK;
    + return ret;
    }

    static int get_ucode_fw(void *to, const void *from, size_t n)

    \
     
     \ /
      Last update: 2018-04-11 00:47    [W:4.473 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site