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@xxxxxxx> > 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@xxxxxxx> > Cc: Borislav Petkov <bp@xxxxxxxxx> > Cc: H. Peter Anvin <hpa@xxxxxxxxx> > Cc: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx> > Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx> > Cc: Takashi Iwai <tiwai@xxxxxxxx>: > Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx> > Cc: Tony Luck <tony.luck@xxxxxxxxx> > Link: http://lkml.kernel.org/r/1444641762-9437-6-git-send-email-bp@xxxxxxxxx > Signed-off-by: Ingo Molnar <mingo@xxxxxxxxxx> > --- > 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@xxxxxxx> > 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@xxxxxxxxxxx> > Signed-off-by: Borislav Petkov <bp@xxxxxxx> > Cc: Borislav Petkov <bp@xxxxxxxxx> > Cc: H. Peter Anvin <hpa@xxxxxxxxx> > Cc: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx> > Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx> > Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx> > Cc: Tony Luck <tony.luck@xxxxxxxxx> > Link: http://lkml.kernel.org/r/1444641762-9437-7-git-send-email-bp@xxxxxxxxx > Signed-off-by: Ingo Molnar <mingo@xxxxxxxxxx> > --- > 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:
signature.asc
Description: This is a digitally signed message part