[tip:x86/mce] x86/microcode/AMD: Check patch level only on the BSP

2017-01-23 Thread tip-bot for Borislav Petkov
Commit-ID:  f3ad136d6ef966c8ba9090770c2bfe7e85f18471
Gitweb: http://git.kernel.org/tip/f3ad136d6ef966c8ba9090770c2bfe7e85f18471
Author: Borislav Petkov 
AuthorDate: Fri, 20 Jan 2017 21:29:51 +0100
Committer:  Thomas Gleixner 
CommitDate: Mon, 23 Jan 2017 10:02:50 +0100

x86/microcode/AMD: Check patch level only on the BSP

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 
Link: http://lkml.kernel.org/r/20170120202955.4091-13...@alien8.de
Signed-off-by: Thomas Gleixner 

---
 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 3e3e20b..3d57009 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 7727f27..6174347 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   = _ucode_patch;
 #endif
 
-   if (check_current_patch_level(, true))
-   return false;
-
desc.cpuid_1_eax = cpuid_1_eax;
 
scan_containers(ucode, size, );
@@ -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(, false))
-   return;
-
/* First AP hasn't cached it yet, go through the blob. */
if (!cont.data) {
struct cpio_data cp;
@@ -371,6 +364,10 @@ reget:
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(, 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[] = {
-   0x0198,
-   0x019f,
-   0x01af,
-   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(_levels);
-   else
-   levels = final_levels;
-
-   for (i = 0; levels[i]; i++) {
-   if (lvl == levels[i]) {
-   lvl = 0;
- 

[tip:x86/mce] x86/microcode/AMD: Check patch level only on the BSP

2017-01-23 Thread tip-bot for Borislav Petkov
Commit-ID:  f3ad136d6ef966c8ba9090770c2bfe7e85f18471
Gitweb: http://git.kernel.org/tip/f3ad136d6ef966c8ba9090770c2bfe7e85f18471
Author: Borislav Petkov 
AuthorDate: Fri, 20 Jan 2017 21:29:51 +0100
Committer:  Thomas Gleixner 
CommitDate: Mon, 23 Jan 2017 10:02:50 +0100

x86/microcode/AMD: Check patch level only on the BSP

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 
Link: http://lkml.kernel.org/r/20170120202955.4091-13...@alien8.de
Signed-off-by: Thomas Gleixner 

---
 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 3e3e20b..3d57009 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 7727f27..6174347 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   = _ucode_patch;
 #endif
 
-   if (check_current_patch_level(, true))
-   return false;
-
desc.cpuid_1_eax = cpuid_1_eax;
 
scan_containers(ucode, size, );
@@ -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(, false))
-   return;
-
/* First AP hasn't cached it yet, go through the blob. */
if (!cont.data) {
struct cpio_data cp;
@@ -371,6 +364,10 @@ reget:
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(, 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[] = {
-   0x0198,
-   0x019f,
-   0x01af,
-   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(_levels);
-   else
-   levels = final_levels;
-
-   for (i = 0; levels[i]; i++) {
-   if (lvl == levels[i]) {
-   lvl = 0;
-   ret = true;
-   break;
-   }
-