* 2 microcode loader patches for 3.2-stable
@ 2016-05-06 13:28 Borislav Petkov
2016-05-15 16:50 ` Ben Hutchings
0 siblings, 1 reply; 2+ messages in thread
From: Borislav Petkov @ 2016-05-06 13:28 UTC (permalink / raw)
To: Ben Hutchings; +Cc: Henrique de Moraes Holschuh, stable
Hi Ben,
please queue those two for 3.2-stable, otherwise some AMD laptops freeze
during microcode updating.
Thanks.
---
>From 2eff73c0a11f19ff082a566e3429fbaaca7b8e7b Mon Sep 17 00:00:00 2001
From: Borislav Petkov <bp@suse.de>
Date: Mon, 12 Oct 2015 11:22:41 +0200
Subject: [PATCH] x86/microcode/amd: Extract current patch level read to a
function
Commit 2eff73c0a11f19ff082a566e3429fbaaca7b8e7b upstream.
Pave the way for checking the current patch level of the
microcode in a core. We want to be able to do stuff depending on
the patch level - in this case decide whether to update or not.
But that will be added in a later patch.
Drop unused local var uci assignment, while at it.
Integrate a fix for 32-bit and CONFIG_PARAVIRT from Takashi Iwai:
Use native_rdmsr() in check_current_patch_level() because with
CONFIG_PARAVIRT enabled and on 32-bit, where we run before
paging has been enabled, we cannot deref pv_info yet. Or we
could, but we'd need to access its physical address. This way of
fixing it is simpler. See:
https://bugzilla.suse.com/show_bug.cgi?id=943179 for the background.
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: Takashi Iwai <tiwai@suse.com>:
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Tony Luck <tony.luck@intel.com>
Link: http://lkml.kernel.org/r/1444641762-9437-6-git-send-email-bp@alien8.de
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
arch/x86/include/asm/microcode.h | 1 +
arch/x86/kernel/microcode_amd.c | 24 ++++++++++++++++++++++--
3 files changed, 30 insertions(+), 12 deletions(-)
Index: linux/arch/x86/include/asm/microcode.h
===================================================================
--- linux.orig/arch/x86/include/asm/microcode.h 2016-05-02 12:20:08.364728800 +0200
+++ linux/arch/x86/include/asm/microcode.h 2016-05-02 12:20:31.944728581 +0200
@@ -61,4 +61,5 @@ static inline struct microcode_ops * __i
}
#endif
+extern bool check_current_patch_level(u32 *rev);
#endif /* _ASM_X86_MICROCODE_H */
Index: linux/arch/x86/kernel/microcode_amd.c
===================================================================
--- linux.orig/arch/x86/kernel/microcode_amd.c 2016-05-02 12:20:08.364728800 +0200
+++ linux/arch/x86/kernel/microcode_amd.c 2016-05-02 12:24:35.768726320 +0200
@@ -123,13 +123,32 @@ static int get_matching_microcode(int cp
return 1;
}
+/*
+ * 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)
+{
+ u32 dummy;
+
+ rdmsr(MSR_AMD64_PATCH_LEVEL, *rev, dummy);
+
+ return false;
+}
+
static int apply_microcode_amd(int cpu)
{
- u32 rev, dummy;
int cpu_num = raw_smp_processor_id();
struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;
struct microcode_amd *mc_amd = uci->mc;
struct cpuinfo_x86 *c = &cpu_data(cpu);
+ u32 dummy, rev;
/* We should bind the task to the CPU */
BUG_ON(cpu_num != cpu);
@@ -137,6 +156,9 @@ static int apply_microcode_amd(int cpu)
if (mc_amd == NULL)
return 0;
+ if (check_current_patch_level(&rev))
+ return -1;
+
wrmsrl(MSR_AMD64_PATCH_LOADER, (u64)(long)&mc_amd->hdr.data_code);
/* get patch id after patching */
rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
---
>From 0399f73299f1b7e04de329050f7111b362b7eeb5 Mon Sep 17 00:00:00 2001
From: Borislav Petkov <bp@suse.de>
Date: Mon, 12 Oct 2015 11:22:42 +0200
Subject: [PATCH] x86/microcode/amd: Do not overwrite final patch levels
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Commit 0399f73299f1b7e04de329050f7111b362b7eeb5 upstream.
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.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(-)
Index: linux/arch/x86/include/asm/microcode.h
===================================================================
--- linux.orig/arch/x86/include/asm/microcode.h 2016-05-02 13:40:48.980683909 +0200
+++ linux/arch/x86/include/asm/microcode.h 2016-05-02 13:40:48.976683909 +0200
@@ -61,5 +61,5 @@ static inline struct microcode_ops * __i
}
#endif
-extern bool check_current_patch_level(u32 *rev);
+extern bool check_current_patch_level(u32 *rev, bool early);
#endif /* _ASM_X86_MICROCODE_H */
Index: linux/arch/x86/kernel/microcode_amd.c
===================================================================
--- linux.orig/arch/x86/kernel/microcode_amd.c 2016-05-02 13:40:48.980683909 +0200
+++ linux/arch/x86/kernel/microcode_amd.c 2016-05-02 13:56:56.688674935 +0200
@@ -124,6 +124,16 @@ static int get_matching_microcode(int cp
}
/*
+ * 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
@@ -133,13 +143,33 @@ static int get_matching_microcode(int cp
* - 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;
+
+ rdmsr(MSR_AMD64_PATCH_LEVEL, lvl, dummy);
+
+#ifdef CONFIG_X86_32
+ if (early)
+ levels = (u32 *)__pa_nodebug(&final_levels);
+ else
+#endif
+ levels = final_levels;
+
+ for (i = 0; levels[i]; i++) {
+ if (lvl == levels[i]) {
+ lvl = 0;
+ ret = true;
+ break;
+ }
+ }
- rdmsr(MSR_AMD64_PATCH_LEVEL, *rev, dummy);
+ if (rev)
+ *rev = lvl;
- return false;
+ return ret;
}
static int apply_microcode_amd(int cpu)
@@ -156,7 +186,7 @@ static int apply_microcode_amd(int cpu)
if (mc_amd == NULL)
return 0;
- if (check_current_patch_level(&rev))
+ if (check_current_patch_level(&rev, false))
return -1;
wrmsrl(MSR_AMD64_PATCH_LOADER, (u64)(long)&mc_amd->hdr.data_code);
--
Regards/Gruss,
Boris.
ECO tip #101: Trim your mails when you reply.
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: 2 microcode loader patches for 3.2-stable
2016-05-06 13:28 2 microcode loader patches for 3.2-stable Borislav Petkov
@ 2016-05-15 16:50 ` Ben Hutchings
0 siblings, 0 replies; 2+ messages in thread
From: Ben Hutchings @ 2016-05-15 16:50 UTC (permalink / raw)
To: Borislav Petkov; +Cc: Henrique de Moraes Holschuh, stable
[-- Attachment #1: Type: text/plain, Size: 8059 bytes --]
On Fri, 2016-05-06 at 15:28 +0200, Borislav Petkov wrote:
> Hi Ben,
>
> please queue those two for 3.2-stable, otherwise some AMD laptops freeze
> during microcode updating.
I've queued these up, thanks.
Ben.
> Thanks.
>
> ---
> From 2eff73c0a11f19ff082a566e3429fbaaca7b8e7b Mon Sep 17 00:00:00 2001
> From: Borislav Petkov <bp@suse.de>
> Date: Mon, 12 Oct 2015 11:22:41 +0200
> Subject: [PATCH] x86/microcode/amd: Extract current patch level read to a
> function
>
> Commit 2eff73c0a11f19ff082a566e3429fbaaca7b8e7b upstream.
>
> Pave the way for checking the current patch level of the
> microcode in a core. We want to be able to do stuff depending on
> the patch level - in this case decide whether to update or not.
> But that will be added in a later patch.
>
> Drop unused local var uci assignment, while at it.
>
> Integrate a fix for 32-bit and CONFIG_PARAVIRT from Takashi Iwai:
>
> Use native_rdmsr() in check_current_patch_level() because with
> CONFIG_PARAVIRT enabled and on 32-bit, where we run before
> paging has been enabled, we cannot deref pv_info yet. Or we
> could, but we'd need to access its physical address. This way of
> fixing it is simpler. See:
>
> https://bugzilla.suse.com/show_bug.cgi?id=943179 for the background.
>
> 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: Takashi Iwai <tiwai@suse.com>:
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Tony Luck <tony.luck@intel.com>
> Link: http://lkml.kernel.org/r/1444641762-9437-6-git-send-email-bp@alien8.de
> Signed-off-by: Ingo Molnar <mingo@kernel.org>
> ---
> arch/x86/include/asm/microcode.h | 1 +
> arch/x86/kernel/microcode_amd.c | 24 ++++++++++++++++++++++--
> 3 files changed, 30 insertions(+), 12 deletions(-)
>
> Index: linux/arch/x86/include/asm/microcode.h
> ===================================================================
> --- linux.orig/arch/x86/include/asm/microcode.h 2016-05-02 12:20:08.364728800 +0200
> +++ linux/arch/x86/include/asm/microcode.h 2016-05-02 12:20:31.944728581 +0200
> @@ -61,4 +61,5 @@ static inline struct microcode_ops * __i
> }
> #endif
>
> +extern bool check_current_patch_level(u32 *rev);
> #endif /* _ASM_X86_MICROCODE_H */
> Index: linux/arch/x86/kernel/microcode_amd.c
> ===================================================================
> --- linux.orig/arch/x86/kernel/microcode_amd.c 2016-05-02 12:20:08.364728800 +0200
> +++ linux/arch/x86/kernel/microcode_amd.c 2016-05-02 12:24:35.768726320 +0200
> @@ -123,13 +123,32 @@ static int get_matching_microcode(int cp
> return 1;
> }
>
> +/*
> + * 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)
> +{
> + u32 dummy;
> +
> + rdmsr(MSR_AMD64_PATCH_LEVEL, *rev, dummy);
> +
> + return false;
> +}
> +
> static int apply_microcode_amd(int cpu)
> {
> - u32 rev, dummy;
> int cpu_num = raw_smp_processor_id();
> struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;
> struct microcode_amd *mc_amd = uci->mc;
> struct cpuinfo_x86 *c = &cpu_data(cpu);
> + u32 dummy, rev;
>
> /* We should bind the task to the CPU */
> BUG_ON(cpu_num != cpu);
> @@ -137,6 +156,9 @@ static int apply_microcode_amd(int cpu)
> if (mc_amd == NULL)
> return 0;
>
> + if (check_current_patch_level(&rev))
> + return -1;
> +
> wrmsrl(MSR_AMD64_PATCH_LOADER, (u64)(long)&mc_amd->hdr.data_code);
> /* get patch id after patching */
> rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
>
>
> ---
> From 0399f73299f1b7e04de329050f7111b362b7eeb5 Mon Sep 17 00:00:00 2001
> From: Borislav Petkov <bp@suse.de>
> Date: Mon, 12 Oct 2015 11:22:42 +0200
> Subject: [PATCH] x86/microcode/amd: Do not overwrite final patch levels
> MIME-Version: 1.0
> Content-Type: text/plain; charset=UTF-8
> Content-Transfer-Encoding: 8bit
>
> Commit 0399f73299f1b7e04de329050f7111b362b7eeb5 upstream.
>
> 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.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(-)
>
> Index: linux/arch/x86/include/asm/microcode.h
> ===================================================================
> --- linux.orig/arch/x86/include/asm/microcode.h 2016-05-02 13:40:48.980683909 +0200
> +++ linux/arch/x86/include/asm/microcode.h 2016-05-02 13:40:48.976683909 +0200
> @@ -61,5 +61,5 @@ static inline struct microcode_ops * __i
> }
> #endif
>
> -extern bool check_current_patch_level(u32 *rev);
> +extern bool check_current_patch_level(u32 *rev, bool early);
> #endif /* _ASM_X86_MICROCODE_H */
> Index: linux/arch/x86/kernel/microcode_amd.c
> ===================================================================
> --- linux.orig/arch/x86/kernel/microcode_amd.c 2016-05-02 13:40:48.980683909 +0200
> +++ linux/arch/x86/kernel/microcode_amd.c 2016-05-02 13:56:56.688674935 +0200
> @@ -124,6 +124,16 @@ static int get_matching_microcode(int cp
> }
>
> /*
> + * 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
> @@ -133,13 +143,33 @@ static int get_matching_microcode(int cp
> * - 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;
> +
> + rdmsr(MSR_AMD64_PATCH_LEVEL, lvl, dummy);
> +
> +#ifdef CONFIG_X86_32
> + if (early)
> + levels = (u32 *)__pa_nodebug(&final_levels);
> + else
> +#endif
> + levels = final_levels;
> +
> + for (i = 0; levels[i]; i++) {
> + if (lvl == levels[i]) {
> + lvl = 0;
> + ret = true;
> + break;
> + }
> + }
>
> - rdmsr(MSR_AMD64_PATCH_LEVEL, *rev, dummy);
> + if (rev)
> + *rev = lvl;
>
> - return false;
> + return ret;
> }
>
> static int apply_microcode_amd(int cpu)
> @@ -156,7 +186,7 @@ static int apply_microcode_amd(int cpu)
> if (mc_amd == NULL)
> return 0;
>
> - if (check_current_patch_level(&rev))
> + if (check_current_patch_level(&rev, false))
> return -1;
>
> wrmsrl(MSR_AMD64_PATCH_LOADER, (u64)(long)&mc_amd->hdr.data_code);
>
--
Ben Hutchings
For every action, there is an equal and opposite criticism. - Harrison
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2016-05-15 20:11 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-05-06 13:28 2 microcode loader patches for 3.2-stable Borislav Petkov
2016-05-15 16:50 ` Ben Hutchings
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox