linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Borislav Petkov <bp@alien8.de>
To: X86 ML <x86@kernel.org>
Cc: LKML <linux-kernel@vger.kernel.org>
Subject: [PATCH 12/16] x86/microcode/AMD: Check patch level only on the BSP
Date: Fri, 20 Jan 2017 21:29:51 +0100	[thread overview]
Message-ID: <20170120202955.4091-13-bp@alien8.de> (raw)
In-Reply-To: <20170120202955.4091-1-bp@alien8.de>

From: Borislav Petkov <bp@suse.de>

Check final patch levels for AMD only on the BSP. This way, we decide
early and only once whether to continue loading or to leave the loader
disabled on such systems.

Simplify a lot.

Signed-off-by: Borislav Petkov <bp@suse.de>
---
 arch/x86/include/asm/microcode_amd.h |  2 -
 arch/x86/kernel/cpu/microcode/amd.c  | 78 +++++-------------------------------
 arch/x86/kernel/cpu/microcode/core.c | 41 +++++++++++++++++++
 3 files changed, 52 insertions(+), 69 deletions(-)

diff --git a/arch/x86/include/asm/microcode_amd.h b/arch/x86/include/asm/microcode_amd.h
index 3e3e20be829a..3d57009e168b 100644
--- a/arch/x86/include/asm/microcode_amd.h
+++ b/arch/x86/include/asm/microcode_amd.h
@@ -54,6 +54,4 @@ static inline int __init
 save_microcode_in_initrd_amd(unsigned int family) { return -EINVAL; }
 void reload_ucode_amd(void) {}
 #endif
-
-extern bool check_current_patch_level(u32 *rev, bool early);
 #endif /* _ASM_X86_MICROCODE_AMD_H */
diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c
index 7727f278de58..61743476c25b 100644
--- a/arch/x86/kernel/cpu/microcode/amd.c
+++ b/arch/x86/kernel/cpu/microcode/amd.c
@@ -207,7 +207,7 @@ apply_microcode_early_amd(u32 cpuid_1_eax, void *ucode, size_t size,
 	struct cont_desc desc = { 0 };
 	u8 (*patch)[PATCH_MAX_SIZE];
 	struct microcode_amd *mc;
-	u32 rev, *new_rev;
+	u32 rev, dummy, *new_rev;
 	bool ret = false;
 
 #ifdef CONFIG_X86_32
@@ -218,9 +218,6 @@ apply_microcode_early_amd(u32 cpuid_1_eax, void *ucode, size_t size,
 	patch	= &amd_ucode_patch;
 #endif
 
-	if (check_current_patch_level(&rev, true))
-		return false;
-
 	desc.cpuid_1_eax = cpuid_1_eax;
 
 	scan_containers(ucode, size, &desc);
@@ -231,6 +228,7 @@ apply_microcode_early_amd(u32 cpuid_1_eax, void *ucode, size_t size,
 	if (!mc)
 		return ret;
 
+	native_rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
 	if (rev >= mc->hdr.patch_id)
 		return ret;
 
@@ -328,13 +326,8 @@ void load_ucode_amd_ap(unsigned int cpuid_1_eax)
 {
 	struct equiv_cpu_entry *eq;
 	struct microcode_amd *mc;
-	u32 rev;
 	u16 eq_id;
 
-	/* 64-bit runs with paging enabled, thus early==false. */
-	if (check_current_patch_level(&rev, false))
-		return;
-
 	/* First AP hasn't cached it yet, go through the blob. */
 	if (!cont.data) {
 		struct cpio_data cp;
@@ -371,6 +364,10 @@ void load_ucode_amd_ap(unsigned int cpuid_1_eax)
 		return;
 
 	if (eq_id == cont.eq_id) {
+		u32 rev, dummy;
+
+		native_rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
+
 		mc = (struct microcode_amd *)amd_ucode_patch;
 
 		if (mc && rev < mc->hdr.patch_id) {
@@ -436,19 +433,14 @@ int __init save_microcode_in_initrd_amd(unsigned int cpuid_1_eax)
 void reload_ucode_amd(void)
 {
 	struct microcode_amd *mc;
-	u32 rev;
-
-	/*
-	 * early==false because this is a syscore ->resume path and by
-	 * that time paging is long enabled.
-	 */
-	if (check_current_patch_level(&rev, false))
-		return;
+	u32 rev, dummy;
 
 	mc = (struct microcode_amd *)amd_ucode_patch;
 	if (!mc)
 		return;
 
+	rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
+
 	if (rev < mc->hdr.patch_id) {
 		if (!__apply_microcode_amd(mc)) {
 			ucode_new_rev = mc->hdr.patch_id;
@@ -586,60 +578,13 @@ static unsigned int verify_patch_size(u8 family, u32 patch_size,
 	return patch_size;
 }
 
-/*
- * Those patch levels cannot be updated to newer ones and thus should be final.
- */
-static u32 final_levels[] = {
-	0x01000098,
-	0x0100009f,
-	0x010000af,
-	0, /* T-101 terminator */
-};
-
-/*
- * Check the current patch level on this CPU.
- *
- * @rev: Use it to return the patch level. It is set to 0 in the case of
- * error.
- *
- * Returns:
- *  - true: if update should stop
- *  - false: otherwise
- */
-bool check_current_patch_level(u32 *rev, bool early)
-{
-	u32 lvl, dummy, i;
-	bool ret = false;
-	u32 *levels;
-
-	native_rdmsr(MSR_AMD64_PATCH_LEVEL, lvl, dummy);
-
-	if (IS_ENABLED(CONFIG_X86_32) && early)
-		levels = (u32 *)__pa_nodebug(&final_levels);
-	else
-		levels = final_levels;
-
-	for (i = 0; levels[i]; i++) {
-		if (lvl == levels[i]) {
-			lvl = 0;
-			ret = true;
-			break;
-		}
-	}
-
-	if (rev)
-		*rev = lvl;
-
-	return ret;
-}
-
 static int apply_microcode_amd(int cpu)
 {
 	struct cpuinfo_x86 *c = &cpu_data(cpu);
 	struct microcode_amd *mc_amd;
 	struct ucode_cpu_info *uci;
 	struct ucode_patch *p;
-	u32 rev;
+	u32 rev, dummy;
 
 	BUG_ON(raw_smp_processor_id() != cpu);
 
@@ -652,8 +597,7 @@ static int apply_microcode_amd(int cpu)
 	mc_amd  = p->data;
 	uci->mc = p->data;
 
-	if (check_current_patch_level(&rev, false))
-		return -1;
+	rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
 
 	/* need to apply patch? */
 	if (rev >= mc_amd->hdr.patch_id) {
diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
index dc54518299c4..3b74d2f315d3 100644
--- a/arch/x86/kernel/cpu/microcode/core.c
+++ b/arch/x86/kernel/cpu/microcode/core.c
@@ -69,6 +69,42 @@ struct cpu_info_ctx {
 	int			err;
 };
 
+/*
+ * Those patch levels cannot be updated to newer ones and thus should be final.
+ */
+static u32 final_levels[] = {
+	0x01000098,
+	0x0100009f,
+	0x010000af,
+	0, /* T-101 terminator */
+};
+
+/*
+ * Check the current patch level on this CPU.
+ *
+ * Returns:
+ *  - true: if update should stop
+ *  - false: otherwise
+ */
+static bool amd_check_current_patch_level(void)
+{
+	u32 lvl, dummy, i;
+	u32 *levels;
+
+	native_rdmsr(MSR_AMD64_PATCH_LEVEL, lvl, dummy);
+
+	if (IS_ENABLED(CONFIG_X86_32))
+		levels = (u32 *)__pa_nodebug(&final_levels);
+	else
+		levels = final_levels;
+
+	for (i = 0; levels[i]; i++) {
+		if (lvl == levels[i])
+			return true;
+	}
+	return false;
+}
+
 static bool __init check_loader_disabled_bsp(void)
 {
 	static const char *__dis_opt_str = "dis_ucode_ldr";
@@ -95,6 +131,11 @@ static bool __init check_loader_disabled_bsp(void)
 	if (native_cpuid_ecx(1) & BIT(31))
 		return *res;
 
+	if (x86_cpuid_vendor() == X86_VENDOR_AMD) {
+		if (amd_check_current_patch_level())
+			return *res;
+	}
+
 	if (cmdline_find_option_bool(cmdline, option) <= 0)
 		*res = false;
 
-- 
2.11.0

  parent reply	other threads:[~2017-01-20 20:31 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-01-20 20:29 [PATCH 00/16 v2] x86/microcode: 4.11 queue Borislav Petkov
2017-01-20 20:29 ` [PATCH 01/16] x86/microcode/intel: Drop stashed AP patch pointer optimization Borislav Petkov
2017-01-23  9:07   ` [tip:x86/mce] " tip-bot for Borislav Petkov
2017-01-20 20:29 ` [PATCH 02/16] x86/MSR: Carve out bare minimum accessors Borislav Petkov
2017-01-23  9:07   ` [tip:x86/mce] " tip-bot for Borislav Petkov
2017-01-20 20:29 ` [PATCH 03/16] x86/microcode: Convert to bare minimum MSR accessors Borislav Petkov
2017-01-23  9:08   ` [tip:x86/mce] " tip-bot for Borislav Petkov
2017-01-20 20:29 ` [PATCH 04/16] x86/microcode/AMD: Clean up find_equiv_id() Borislav Petkov
2017-01-23  9:08   ` [tip:x86/mce] " tip-bot for Borislav Petkov
2017-01-20 20:29 ` [PATCH 05/16] x86/microcode/AMD: Shorten function parameter's name Borislav Petkov
2017-01-23  9:09   ` [tip:x86/mce] " tip-bot for Borislav Petkov
2017-01-20 20:29 ` [PATCH 06/16] x86/microcode/AMD: Extend the container struct Borislav Petkov
2017-01-23  9:09   ` [tip:x86/mce] " tip-bot for Borislav Petkov
2017-01-20 20:29 ` [PATCH 07/16] x86/microcode/AMD: Rework container parsing Borislav Petkov
2017-01-23  9:10   ` [tip:x86/mce] " tip-bot for Borislav Petkov
2017-01-20 20:29 ` [PATCH 08/16] x86/microcode: Decrease CPUID use Borislav Petkov
2017-01-23  9:10   ` [tip:x86/mce] " tip-bot for Borislav Petkov
2017-01-20 20:29 ` [PATCH 09/16] x86/microcode/AMD: Get rid of global this_equiv_id Borislav Petkov
2017-01-23  9:11   ` [tip:x86/mce] " tip-bot for Borislav Petkov
2017-01-20 20:29 ` [PATCH 10/16] x86/microcode/AMD: Use find_microcode_in_initrd() Borislav Petkov
2017-01-23  9:11   ` [tip:x86/mce] " tip-bot for Borislav Petkov
2017-01-20 20:29 ` [PATCH 11/16] x86/microcode: Remove local vendor variable Borislav Petkov
2017-01-23  9:12   ` [tip:x86/mce] " tip-bot for Borislav Petkov
2017-01-20 20:29 ` Borislav Petkov [this message]
2017-01-23  9:12   ` [tip:x86/mce] x86/microcode/AMD: Check patch level only on the BSP tip-bot for Borislav Petkov
2017-01-20 20:29 ` [PATCH 13/16] x86/microcode/AMD: Unify load_ucode_amd_ap() Borislav Petkov
2017-01-23  9:13   ` [tip:x86/mce] " tip-bot for Borislav Petkov
2017-01-20 20:29 ` [PATCH 14/16] x86/microcode/AMD: Simplify saving from initrd Borislav Petkov
2017-01-23  9:13   ` [tip:x86/mce] " tip-bot for Borislav Petkov
2017-01-20 20:29 ` [PATCH 15/16] x86/microcode/AMD: Remove AP scanning optimization Borislav Petkov
2017-01-23  9:14   ` [tip:x86/mce] " tip-bot for Borislav Petkov
2017-01-20 20:29 ` [PATCH 16/16] x86/microcode/AMD: Remove struct cont_desc.eq_id Borislav Petkov
2017-01-23  9:14   ` [tip:x86/mce] " tip-bot for Borislav Petkov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170120202955.4091-13-bp@alien8.de \
    --to=bp@alien8.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).