All of lore.kernel.org
 help / color / mirror / Atom feed
From: tip-bot for Borislav Petkov <tipbot@zytor.com>
To: linux-tip-commits@vger.kernel.org
Cc: tglx@linutronix.de, bp@suse.de, mingo@kernel.org,
	torvalds@linux-foundation.org, pkirchgessner@t-online.de,
	hpa@zytor.com, bp@alien8.de, tony.luck@intel.com,
	linux-kernel@vger.kernel.org, peterz@infradead.org
Subject: [tip:ras/core] x86/microcode/amd: Do not overwrite final patch levels
Date: Mon, 12 Oct 2015 07:32:23 -0700	[thread overview]
Message-ID: <tip-0399f73299f1b7e04de329050f7111b362b7eeb5@git.kernel.org> (raw)
In-Reply-To: <1444641762-9437-7-git-send-email-bp@alien8.de>

Commit-ID:  0399f73299f1b7e04de329050f7111b362b7eeb5
Gitweb:     http://git.kernel.org/tip/0399f73299f1b7e04de329050f7111b362b7eeb5
Author:     Borislav Petkov <bp@suse.de>
AuthorDate: Mon, 12 Oct 2015 11:22:42 +0200
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Mon, 12 Oct 2015 16:15:48 +0200

x86/microcode/amd: Do not overwrite final patch levels

A certain number of patch levels of applied microcode should not
be overwritten by the microcode loader, otherwise bad things
will happen.

Check those and abort update if the current core has one of
those final patch levels applied by the BIOS. 32-bit needs
special handling, of course.

See https://bugzilla.suse.com/show_bug.cgi?id=913996 for more
info.

Tested-by: Peter Kirchgeßner <pkirchgessner@t-online.de>
Signed-off-by: Borislav Petkov <bp@suse.de>
Cc: Borislav Petkov <bp@alien8.de>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Tony Luck <tony.luck@intel.com>
Link: http://lkml.kernel.org/r/1444641762-9437-7-git-send-email-bp@alien8.de
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/include/asm/microcode_amd.h      |  2 +-
 arch/x86/kernel/cpu/microcode/amd.c       | 38 +++++++++++++++++++++++++++----
 arch/x86/kernel/cpu/microcode/amd_early.c | 13 ++++++++---
 3 files changed, 44 insertions(+), 9 deletions(-)

diff --git a/arch/x86/include/asm/microcode_amd.h b/arch/x86/include/asm/microcode_amd.h
index 9b214e1..d3e86cf 100644
--- a/arch/x86/include/asm/microcode_amd.h
+++ b/arch/x86/include/asm/microcode_amd.h
@@ -76,5 +76,5 @@ static inline int __init save_microcode_in_initrd_amd(void) { return -EINVAL; }
 void reload_ucode_amd(void) {}
 #endif
 
-extern bool check_current_patch_level(u32 *rev);
+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 2d63013..da922d1 100644
--- a/arch/x86/kernel/cpu/microcode/amd.c
+++ b/arch/x86/kernel/cpu/microcode/amd.c
@@ -178,6 +178,16 @@ static unsigned int verify_patch_size(u8 family, u32 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
@@ -187,13 +197,31 @@ static unsigned int verify_patch_size(u8 family, u32 patch_size,
  *  - true: if update should stop
  *  - false: otherwise
  */
-bool check_current_patch_level(u32 *rev)
+bool check_current_patch_level(u32 *rev, bool early)
 {
-	u32 dummy;
+	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;
+		}
+	}
 
-	native_rdmsr(MSR_AMD64_PATCH_LEVEL, *rev, dummy);
+	if (rev)
+		*rev = lvl;
 
-	return false;
+	return ret;
 }
 
 int __apply_microcode_amd(struct microcode_amd *mc_amd)
@@ -229,7 +257,7 @@ int apply_microcode_amd(int cpu)
 	mc_amd  = p->data;
 	uci->mc = p->data;
 
-	if (check_current_patch_level(&rev))
+	if (check_current_patch_level(&rev, false))
 		return -1;
 
 	/* need to apply patch? */
diff --git a/arch/x86/kernel/cpu/microcode/amd_early.c b/arch/x86/kernel/cpu/microcode/amd_early.c
index abb9009..a54a47b 100644
--- a/arch/x86/kernel/cpu/microcode/amd_early.c
+++ b/arch/x86/kernel/cpu/microcode/amd_early.c
@@ -196,7 +196,7 @@ static void apply_ucode_in_initrd(void *ucode, size_t size, bool save_patch)
 		return;
 	}
 
-	if (check_current_patch_level(&rev))
+	if (check_current_patch_level(&rev, true))
 		return;
 
 	while (left > 0) {
@@ -330,7 +330,10 @@ void load_ucode_amd_ap(void)
 	if (!container)
 		return;
 
-	if (check_current_patch_level(&rev))
+	/*
+	 * 64-bit runs with paging enabled, thus early==false.
+	 */
+	if (check_current_patch_level(&rev, false))
 		return;
 
 	eax = cpuid_eax(0x00000001);
@@ -422,7 +425,11 @@ void reload_ucode_amd(void)
 	struct microcode_amd *mc;
 	u32 rev;
 
-	if (check_current_patch_level(&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;
 
 	mc = (struct microcode_amd *)amd_ucode_patch;

  reply	other threads:[~2015-10-12 14:33 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-10-12  9:22 [PATCH 0/6] tip-queue 2015-10-12 Borislav Petkov
2015-10-12  9:22 ` [PATCH 1/6] x86/mce: Don't clear shared banks on Intel when offlining CPUs Borislav Petkov
2015-10-12  9:22 ` [PATCH 2/6] x86/ras/mce_amd_inj: Return early on invalid input Borislav Petkov
2015-10-12 14:31   ` [tip:ras/core] " tip-bot for Aravind Gopalakrishnan
2015-10-12  9:22 ` [PATCH 3/6] x86/ras/mce_amd_inj: Trigger deferred and thresholding errors interrupts Borislav Petkov
2015-10-12 14:31   ` [tip:ras/core] " tip-bot for Aravind Gopalakrishnan
2015-10-12  9:22 ` [PATCH 4/6] x86/ras/mce_amd_inj: Inject bank 4 errors on the NBC Borislav Petkov
2015-10-12 14:31   ` [tip:ras/core] " tip-bot for Aravind Gopalakrishnan
2015-10-12  9:22 ` [PATCH 5/6] x86/microcode/amd: Extract current patch level read to a function Borislav Petkov
2015-10-12 14:32   ` [tip:ras/core] " tip-bot for Borislav Petkov
2015-10-12  9:22 ` [PATCH 6/6] x86/microcode/amd: Do not overwrite final patch levels Borislav Petkov
2015-10-12 14:32   ` tip-bot for Borislav Petkov [this message]
  -- strict thread matches above, loose matches on Subject: below --
2015-09-25 14:20 [PATCH V2 0/3] Updates to mce_amd_inj module Aravind Gopalakrishnan
2015-09-25 14:20 ` [PATCH V2 1/3] RAS, mce_amd_inj: Return early on invalid input Aravind Gopalakrishnan
2015-09-25 14:20 ` [PATCH V2 2/3] RAS, mce_amd_inj: Add capability to trigger apic interrupts Aravind Gopalakrishnan
2015-09-25 14:20 ` [PATCH V2 3/3] RAS, mce_amd_inj: Inject errors on NBC for bank 4 errors Aravind Gopalakrishnan
2015-09-28  9:06 ` [PATCH V2 0/3] Updates to mce_amd_inj module 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=tip-0399f73299f1b7e04de329050f7111b362b7eeb5@git.kernel.org \
    --to=tipbot@zytor.com \
    --cc=bp@alien8.de \
    --cc=bp@suse.de \
    --cc=hpa@zytor.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-tip-commits@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=peterz@infradead.org \
    --cc=pkirchgessner@t-online.de \
    --cc=tglx@linutronix.de \
    --cc=tony.luck@intel.com \
    --cc=torvalds@linux-foundation.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.