diff options
Diffstat (limited to 'linux-kernel-patches/01-3f1f576a195aa266813cbd4ca70291deb61e0129.patch')
-rw-r--r-- | linux-kernel-patches/01-3f1f576a195aa266813cbd4ca70291deb61e0129.patch | 234 |
1 files changed, 234 insertions, 0 deletions
diff --git a/linux-kernel-patches/01-3f1f576a195aa266813cbd4ca70291deb61e0129.patch b/linux-kernel-patches/01-3f1f576a195aa266813cbd4ca70291deb61e0129.patch new file mode 100644 index 0000000..fb895a4 --- /dev/null +++ b/linux-kernel-patches/01-3f1f576a195aa266813cbd4ca70291deb61e0129.patch @@ -0,0 +1,234 @@ +From 3f1f576a195aa266813cbd4ca70291deb61e0129 Mon Sep 17 00:00:00 2001
+From: Borislav Petkov <bp@suse.de>
+Date: Fri, 16 Feb 2018 12:26:38 +0100
+Subject: x86/microcode: Propagate return value from updating functions
+
+... 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>
+---
+ 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(-)
+
+diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h
+index 55520cec..7fb1047 100644
+--- 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);
+ };
+
+diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c
+index 330b846..a998e1a 100644
+--- 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 family, u32 patch_size,
+ 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)
+diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
+index 319dd65..6fdaf7c 100644
+--- 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(void)
+ /* 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, µcode_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 device *dev,
+ mutex_lock(µcode_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(µcode_mutex);
+ put_online_cpus();
+
+diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c
+index a15db2b..923054a 100644
+--- 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, struct cpu_signature *csig)
+ 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,
+--
+cgit v1.1
+
|