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.15 109/168] x86/microcode: Propagate return value from updating functions
    Date
    4.15-stable review patch.  If anyone has any objections, please let me know.

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

    From: Borislav Petkov <bp@suse.de>

    commit 3f1f576a195aa266813cbd4ca70291deb61e0129 upstream.

    ... so that callers can know when microcode was updated and act
    accordingly.

    Tested-by: Ashok Raj <ashok.raj@intel.com>
    Signed-off-by: Borislav Petkov <bp@suse.de>
    Reviewed-by: Ashok Raj <ashok.raj@intel.com>
    Cc: Andy Lutomirski <luto@kernel.org>
    Cc: Arjan van de Ven <arjan@linux.intel.com>
    Cc: Borislav Petkov <bp@alien8.de>
    Cc: Dan Williams <dan.j.williams@intel.com>
    Cc: Dave Hansen <dave.hansen@linux.intel.com>
    Cc: David Woodhouse <dwmw2@infradead.org>
    Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    Cc: Josh Poimboeuf <jpoimboe@redhat.com>
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Link: http://lkml.kernel.org/r/20180216112640.11554-2-bp@alien8.de
    Signed-off-by: Ingo Molnar <mingo@kernel.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

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

    --- a/arch/x86/include/asm/microcode.h
    +++ b/arch/x86/include/asm/microcode.h
    @@ -37,7 +37,12 @@ struct cpu_signature {

    struct device;

    -enum ucode_state { UCODE_ERROR, UCODE_OK, UCODE_NFOUND };
    +enum ucode_state {
    + UCODE_OK = 0,
    + UCODE_UPDATED,
    + UCODE_NFOUND,
    + UCODE_ERROR,
    +};

    struct microcode_ops {
    enum ucode_state (*request_microcode_user) (int cpu,
    @@ -54,7 +59,7 @@ struct microcode_ops {
    * are being called.
    * See also the "Synchronization" section in microcode_core.c.
    */
    - int (*apply_microcode) (int cpu);
    + enum ucode_state (*apply_microcode) (int cpu);
    int (*collect_cpu_info) (int cpu, struct cpu_signature *csig);
    };

    --- a/arch/x86/kernel/cpu/microcode/amd.c
    +++ b/arch/x86/kernel/cpu/microcode/amd.c
    @@ -498,7 +498,7 @@ static unsigned int verify_patch_size(u8
    return patch_size;
    }

    -static int apply_microcode_amd(int cpu)
    +static enum ucode_state apply_microcode_amd(int cpu)
    {
    struct cpuinfo_x86 *c = &cpu_data(cpu);
    struct microcode_amd *mc_amd;
    @@ -512,7 +512,7 @@ static int apply_microcode_amd(int cpu)

    p = find_patch(cpu);
    if (!p)
    - return 0;
    + return UCODE_NFOUND;

    mc_amd = p->data;
    uci->mc = p->data;
    @@ -523,13 +523,13 @@ static int apply_microcode_amd(int cpu)
    if (rev >= mc_amd->hdr.patch_id) {
    c->microcode = rev;
    uci->cpu_sig.rev = rev;
    - return 0;
    + return UCODE_OK;
    }

    if (__apply_microcode_amd(mc_amd)) {
    pr_err("CPU%d: update failed for patch_level=0x%08x\n",
    cpu, mc_amd->hdr.patch_id);
    - return -1;
    + return UCODE_ERROR;
    }
    pr_info("CPU%d: new patch_level=0x%08x\n", cpu,
    mc_amd->hdr.patch_id);
    @@ -537,7 +537,7 @@ static int apply_microcode_amd(int cpu)
    uci->cpu_sig.rev = mc_amd->hdr.patch_id;
    c->microcode = mc_amd->hdr.patch_id;

    - return 0;
    + return UCODE_UPDATED;
    }

    static int install_equiv_cpu_table(const u8 *buf)
    --- a/arch/x86/kernel/cpu/microcode/core.c
    +++ b/arch/x86/kernel/cpu/microcode/core.c
    @@ -374,7 +374,7 @@ static int collect_cpu_info(int cpu)
    }

    struct apply_microcode_ctx {
    - int err;
    + enum ucode_state err;
    };

    static void apply_microcode_local(void *arg)
    @@ -489,31 +489,29 @@ static void __exit microcode_dev_exit(vo
    /* fake device for request_firmware */
    static struct platform_device *microcode_pdev;

    -static int reload_for_cpu(int cpu)
    +static enum ucode_state reload_for_cpu(int cpu)
    {
    struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
    enum ucode_state ustate;
    - int err = 0;

    if (!uci->valid)
    - return err;
    + return UCODE_OK;

    ustate = microcode_ops->request_microcode_fw(cpu, &microcode_pdev->dev, true);
    - if (ustate == UCODE_OK)
    - apply_microcode_on_target(cpu);
    - else
    - if (ustate == UCODE_ERROR)
    - err = -EINVAL;
    - return err;
    + if (ustate != UCODE_OK)
    + return ustate;
    +
    + return apply_microcode_on_target(cpu);
    }

    static ssize_t reload_store(struct device *dev,
    struct device_attribute *attr,
    const char *buf, size_t size)
    {
    + enum ucode_state tmp_ret = UCODE_OK;
    unsigned long val;
    + ssize_t ret = 0;
    int cpu;
    - ssize_t ret = 0, tmp_ret;

    ret = kstrtoul(buf, 0, &val);
    if (ret)
    @@ -526,15 +524,18 @@ static ssize_t reload_store(struct devic
    mutex_lock(&microcode_mutex);
    for_each_online_cpu(cpu) {
    tmp_ret = reload_for_cpu(cpu);
    - if (tmp_ret != 0)
    + if (tmp_ret > UCODE_NFOUND) {
    pr_warn("Error reloading microcode on CPU %d\n", cpu);

    - /* save retval of the first encountered reload error */
    - if (!ret)
    - ret = tmp_ret;
    + /* set retval for the first encountered reload error */
    + if (!ret)
    + ret = -EINVAL;
    + }
    }
    - if (!ret)
    +
    + if (!ret && tmp_ret == UCODE_UPDATED)
    perf_check_microcode();
    +
    mutex_unlock(&microcode_mutex);
    put_online_cpus();

    --- a/arch/x86/kernel/cpu/microcode/intel.c
    +++ b/arch/x86/kernel/cpu/microcode/intel.c
    @@ -772,7 +772,7 @@ static int collect_cpu_info(int cpu_num,
    return 0;
    }

    -static int apply_microcode_intel(int cpu)
    +static enum ucode_state apply_microcode_intel(int cpu)
    {
    struct microcode_intel *mc;
    struct ucode_cpu_info *uci;
    @@ -782,7 +782,7 @@ static int apply_microcode_intel(int cpu

    /* We should bind the task to the CPU */
    if (WARN_ON(raw_smp_processor_id() != cpu))
    - return -1;
    + return UCODE_ERROR;

    uci = ucode_cpu_info + cpu;
    mc = uci->mc;
    @@ -790,7 +790,7 @@ static int apply_microcode_intel(int cpu
    /* Look for a newer patch in our cache: */
    mc = find_patch(uci);
    if (!mc)
    - return 0;
    + return UCODE_NFOUND;
    }

    /* write microcode via MSR 0x79 */
    @@ -801,7 +801,7 @@ static int apply_microcode_intel(int cpu
    if (rev != mc->hdr.rev) {
    pr_err("CPU%d update to revision 0x%x failed\n",
    cpu, mc->hdr.rev);
    - return -1;
    + return UCODE_ERROR;
    }

    if (rev != prev_rev) {
    @@ -818,7 +818,7 @@ static int apply_microcode_intel(int cpu
    uci->cpu_sig.rev = rev;
    c->microcode = rev;

    - return 0;
    + return UCODE_UPDATED;
    }

    static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,

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