Blame linux-kernel-patches/01-3f1f576a195aa266813cbd4ca70291deb61e0129.patch

Packit Service c9fe53
From 3f1f576a195aa266813cbd4ca70291deb61e0129 Mon Sep 17 00:00:00 2001
Packit Service c9fe53
From: Borislav Petkov <bp@suse.de>
Packit Service c9fe53
Date: Fri, 16 Feb 2018 12:26:38 +0100
Packit Service c9fe53
Subject: x86/microcode: Propagate return value from updating functions
Packit Service c9fe53

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

Packit Service c9fe53
Tested-by: Ashok Raj <ashok.raj@intel.com>
Packit Service c9fe53
Signed-off-by: Borislav Petkov <bp@suse.de>
Packit Service c9fe53
Reviewed-by: Ashok Raj <ashok.raj@intel.com>
Packit Service c9fe53
Cc: Andy Lutomirski <luto@kernel.org>
Packit Service c9fe53
Cc: Arjan van de Ven <arjan@linux.intel.com>
Packit Service c9fe53
Cc: Borislav Petkov <bp@alien8.de>
Packit Service c9fe53
Cc: Dan Williams <dan.j.williams@intel.com>
Packit Service c9fe53
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Packit Service c9fe53
Cc: David Woodhouse <dwmw2@infradead.org>
Packit Service c9fe53
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Packit Service c9fe53
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Packit Service c9fe53
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Packit Service c9fe53
Cc: Peter Zijlstra <peterz@infradead.org>
Packit Service c9fe53
Cc: Thomas Gleixner <tglx@linutronix.de>
Packit Service c9fe53
Link: http://lkml.kernel.org/r/20180216112640.11554-2-bp@alien8.de
Packit Service c9fe53
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Packit Service c9fe53
---
Packit Service c9fe53
 arch/x86/include/asm/microcode.h      |  9 +++++++--
Packit Service c9fe53
 arch/x86/kernel/cpu/microcode/amd.c   | 10 +++++-----
Packit Service c9fe53
 arch/x86/kernel/cpu/microcode/core.c  | 33 +++++++++++++++++----------------
Packit Service c9fe53
 arch/x86/kernel/cpu/microcode/intel.c | 10 +++++-----
Packit Service c9fe53
 4 files changed, 34 insertions(+), 28 deletions(-)
Packit Service c9fe53

Packit Service c9fe53
diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h
Packit Service c9fe53
index 55520cec..7fb1047 100644
Packit Service c9fe53
--- a/arch/x86/include/asm/microcode.h
Packit Service c9fe53
+++ b/arch/x86/include/asm/microcode.h
Packit Service c9fe53
@@ -37,7 +37,12 @@ struct cpu_signature {
Packit Service c9fe53
 
Packit Service c9fe53
 struct device;
Packit Service c9fe53
 
Packit Service c9fe53
-enum ucode_state { UCODE_ERROR, UCODE_OK, UCODE_NFOUND };
Packit Service c9fe53
+enum ucode_state {
Packit Service c9fe53
+	UCODE_OK	= 0,
Packit Service c9fe53
+	UCODE_UPDATED,
Packit Service c9fe53
+	UCODE_NFOUND,
Packit Service c9fe53
+	UCODE_ERROR,
Packit Service c9fe53
+};
Packit Service c9fe53
 
Packit Service c9fe53
 struct microcode_ops {
Packit Service c9fe53
 	enum ucode_state (*request_microcode_user) (int cpu,
Packit Service c9fe53
@@ -54,7 +59,7 @@ struct microcode_ops {
Packit Service c9fe53
 	 * are being called.
Packit Service c9fe53
 	 * See also the "Synchronization" section in microcode_core.c.
Packit Service c9fe53
 	 */
Packit Service c9fe53
-	int (*apply_microcode) (int cpu);
Packit Service c9fe53
+	enum ucode_state (*apply_microcode) (int cpu);
Packit Service c9fe53
 	int (*collect_cpu_info) (int cpu, struct cpu_signature *csig);
Packit Service c9fe53
 };
Packit Service c9fe53
 
Packit Service c9fe53
diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c
Packit Service c9fe53
index 330b846..a998e1a 100644
Packit Service c9fe53
--- a/arch/x86/kernel/cpu/microcode/amd.c
Packit Service c9fe53
+++ b/arch/x86/kernel/cpu/microcode/amd.c
Packit Service c9fe53
@@ -498,7 +498,7 @@ static unsigned int verify_patch_size(u8 family, u32 patch_size,
Packit Service c9fe53
 	return patch_size;
Packit Service c9fe53
 }
Packit Service c9fe53
 
Packit Service c9fe53
-static int apply_microcode_amd(int cpu)
Packit Service c9fe53
+static enum ucode_state apply_microcode_amd(int cpu)
Packit Service c9fe53
 {
Packit Service c9fe53
 	struct cpuinfo_x86 *c = &cpu_data(cpu);
Packit Service c9fe53
 	struct microcode_amd *mc_amd;
Packit Service c9fe53
@@ -512,7 +512,7 @@ static int apply_microcode_amd(int cpu)
Packit Service c9fe53
 
Packit Service c9fe53
 	p = find_patch(cpu);
Packit Service c9fe53
 	if (!p)
Packit Service c9fe53
-		return 0;
Packit Service c9fe53
+		return UCODE_NFOUND;
Packit Service c9fe53
 
Packit Service c9fe53
 	mc_amd  = p->data;
Packit Service c9fe53
 	uci->mc = p->data;
Packit Service c9fe53
@@ -523,13 +523,13 @@ static int apply_microcode_amd(int cpu)
Packit Service c9fe53
 	if (rev >= mc_amd->hdr.patch_id) {
Packit Service c9fe53
 		c->microcode = rev;
Packit Service c9fe53
 		uci->cpu_sig.rev = rev;
Packit Service c9fe53
-		return 0;
Packit Service c9fe53
+		return UCODE_OK;
Packit Service c9fe53
 	}
Packit Service c9fe53
 
Packit Service c9fe53
 	if (__apply_microcode_amd(mc_amd)) {
Packit Service c9fe53
 		pr_err("CPU%d: update failed for patch_level=0x%08x\n",
Packit Service c9fe53
 			cpu, mc_amd->hdr.patch_id);
Packit Service c9fe53
-		return -1;
Packit Service c9fe53
+		return UCODE_ERROR;
Packit Service c9fe53
 	}
Packit Service c9fe53
 	pr_info("CPU%d: new patch_level=0x%08x\n", cpu,
Packit Service c9fe53
 		mc_amd->hdr.patch_id);
Packit Service c9fe53
@@ -537,7 +537,7 @@ static int apply_microcode_amd(int cpu)
Packit Service c9fe53
 	uci->cpu_sig.rev = mc_amd->hdr.patch_id;
Packit Service c9fe53
 	c->microcode = mc_amd->hdr.patch_id;
Packit Service c9fe53
 
Packit Service c9fe53
-	return 0;
Packit Service c9fe53
+	return UCODE_UPDATED;
Packit Service c9fe53
 }
Packit Service c9fe53
 
Packit Service c9fe53
 static int install_equiv_cpu_table(const u8 *buf)
Packit Service c9fe53
diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
Packit Service c9fe53
index 319dd65..6fdaf7c 100644
Packit Service c9fe53
--- a/arch/x86/kernel/cpu/microcode/core.c
Packit Service c9fe53
+++ b/arch/x86/kernel/cpu/microcode/core.c
Packit Service c9fe53
@@ -374,7 +374,7 @@ static int collect_cpu_info(int cpu)
Packit Service c9fe53
 }
Packit Service c9fe53
 
Packit Service c9fe53
 struct apply_microcode_ctx {
Packit Service c9fe53
-	int err;
Packit Service c9fe53
+	enum ucode_state err;
Packit Service c9fe53
 };
Packit Service c9fe53
 
Packit Service c9fe53
 static void apply_microcode_local(void *arg)
Packit Service c9fe53
@@ -489,31 +489,29 @@ static void __exit microcode_dev_exit(void)
Packit Service c9fe53
 /* fake device for request_firmware */
Packit Service c9fe53
 static struct platform_device	*microcode_pdev;
Packit Service c9fe53
 
Packit Service c9fe53
-static int reload_for_cpu(int cpu)
Packit Service c9fe53
+static enum ucode_state reload_for_cpu(int cpu)
Packit Service c9fe53
 {
Packit Service c9fe53
 	struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
Packit Service c9fe53
 	enum ucode_state ustate;
Packit Service c9fe53
-	int err = 0;
Packit Service c9fe53
 
Packit Service c9fe53
 	if (!uci->valid)
Packit Service c9fe53
-		return err;
Packit Service c9fe53
+		return UCODE_OK;
Packit Service c9fe53
 
Packit Service c9fe53
 	ustate = microcode_ops->request_microcode_fw(cpu, &microcode_pdev->dev, true);
Packit Service c9fe53
-	if (ustate == UCODE_OK)
Packit Service c9fe53
-		apply_microcode_on_target(cpu);
Packit Service c9fe53
-	else
Packit Service c9fe53
-		if (ustate == UCODE_ERROR)
Packit Service c9fe53
-			err = -EINVAL;
Packit Service c9fe53
-	return err;
Packit Service c9fe53
+	if (ustate != UCODE_OK)
Packit Service c9fe53
+		return ustate;
Packit Service c9fe53
+
Packit Service c9fe53
+	return apply_microcode_on_target(cpu);
Packit Service c9fe53
 }
Packit Service c9fe53
 
Packit Service c9fe53
 static ssize_t reload_store(struct device *dev,
Packit Service c9fe53
 			    struct device_attribute *attr,
Packit Service c9fe53
 			    const char *buf, size_t size)
Packit Service c9fe53
 {
Packit Service c9fe53
+	enum ucode_state tmp_ret = UCODE_OK;
Packit Service c9fe53
 	unsigned long val;
Packit Service c9fe53
+	ssize_t ret = 0;
Packit Service c9fe53
 	int cpu;
Packit Service c9fe53
-	ssize_t ret = 0, tmp_ret;
Packit Service c9fe53
 
Packit Service c9fe53
 	ret = kstrtoul(buf, 0, &val;;
Packit Service c9fe53
 	if (ret)
Packit Service c9fe53
@@ -526,15 +524,18 @@ static ssize_t reload_store(struct device *dev,
Packit Service c9fe53
 	mutex_lock(&microcode_mutex);
Packit Service c9fe53
 	for_each_online_cpu(cpu) {
Packit Service c9fe53
 		tmp_ret = reload_for_cpu(cpu);
Packit Service c9fe53
-		if (tmp_ret != 0)
Packit Service c9fe53
+		if (tmp_ret > UCODE_NFOUND) {
Packit Service c9fe53
 			pr_warn("Error reloading microcode on CPU %d\n", cpu);
Packit Service c9fe53
 
Packit Service c9fe53
-		/* save retval of the first encountered reload error */
Packit Service c9fe53
-		if (!ret)
Packit Service c9fe53
-			ret = tmp_ret;
Packit Service c9fe53
+			/* set retval for the first encountered reload error */
Packit Service c9fe53
+			if (!ret)
Packit Service c9fe53
+				ret = -EINVAL;
Packit Service c9fe53
+		}
Packit Service c9fe53
 	}
Packit Service c9fe53
-	if (!ret)
Packit Service c9fe53
+
Packit Service c9fe53
+	if (!ret && tmp_ret == UCODE_UPDATED)
Packit Service c9fe53
 		perf_check_microcode();
Packit Service c9fe53
+
Packit Service c9fe53
 	mutex_unlock(&microcode_mutex);
Packit Service c9fe53
 	put_online_cpus();
Packit Service c9fe53
 
Packit Service c9fe53
diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c
Packit Service c9fe53
index a15db2b..923054a 100644
Packit Service c9fe53
--- a/arch/x86/kernel/cpu/microcode/intel.c
Packit Service c9fe53
+++ b/arch/x86/kernel/cpu/microcode/intel.c
Packit Service c9fe53
@@ -772,7 +772,7 @@ static int collect_cpu_info(int cpu_num, struct cpu_signature *csig)
Packit Service c9fe53
 	return 0;
Packit Service c9fe53
 }
Packit Service c9fe53
 
Packit Service c9fe53
-static int apply_microcode_intel(int cpu)
Packit Service c9fe53
+static enum ucode_state apply_microcode_intel(int cpu)
Packit Service c9fe53
 {
Packit Service c9fe53
 	struct microcode_intel *mc;
Packit Service c9fe53
 	struct ucode_cpu_info *uci;
Packit Service c9fe53
@@ -782,7 +782,7 @@ static int apply_microcode_intel(int cpu)
Packit Service c9fe53
 
Packit Service c9fe53
 	/* We should bind the task to the CPU */
Packit Service c9fe53
 	if (WARN_ON(raw_smp_processor_id() != cpu))
Packit Service c9fe53
-		return -1;
Packit Service c9fe53
+		return UCODE_ERROR;
Packit Service c9fe53
 
Packit Service c9fe53
 	uci = ucode_cpu_info + cpu;
Packit Service c9fe53
 	mc = uci->mc;
Packit Service c9fe53
@@ -790,7 +790,7 @@ static int apply_microcode_intel(int cpu)
Packit Service c9fe53
 		/* Look for a newer patch in our cache: */
Packit Service c9fe53
 		mc = find_patch(uci);
Packit Service c9fe53
 		if (!mc)
Packit Service c9fe53
-			return 0;
Packit Service c9fe53
+			return UCODE_NFOUND;
Packit Service c9fe53
 	}
Packit Service c9fe53
 
Packit Service c9fe53
 	/* write microcode via MSR 0x79 */
Packit Service c9fe53
@@ -801,7 +801,7 @@ static int apply_microcode_intel(int cpu)
Packit Service c9fe53
 	if (rev != mc->hdr.rev) {
Packit Service c9fe53
 		pr_err("CPU%d update to revision 0x%x failed\n",
Packit Service c9fe53
 		       cpu, mc->hdr.rev);
Packit Service c9fe53
-		return -1;
Packit Service c9fe53
+		return UCODE_ERROR;
Packit Service c9fe53
 	}
Packit Service c9fe53
 
Packit Service c9fe53
 	if (rev != prev_rev) {
Packit Service c9fe53
@@ -818,7 +818,7 @@ static int apply_microcode_intel(int cpu)
Packit Service c9fe53
 	uci->cpu_sig.rev = rev;
Packit Service c9fe53
 	c->microcode = rev;
Packit Service c9fe53
 
Packit Service c9fe53
-	return 0;
Packit Service c9fe53
+	return UCODE_UPDATED;
Packit Service c9fe53
 }
Packit Service c9fe53
 
Packit Service c9fe53
 static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
Packit Service c9fe53
-- 
Packit Service c9fe53
cgit v1.1
Packit Service c9fe53