x86, microcode: Reloading fixes
Subsystems (2)
Borislav Petkov
maintainercover x86, microcode: Reloading fixes
From: Borislav Petkov <[email protected]>
Hi guys,
please pull three fixes for the microcode loader. More specifically, microcode reloading for 3.19. Patches are against tip/x86/microcode.
I have this also as a tag if you'd prefer to pull:
git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp.git tags/microcode_fixes_for_3.19
This will have a conflict when merging into Linus' tree after tip/x86/urgent has went in for 3.18 but resolving it should be easy. The final result should be this with the ifdef dropped:
---
arch/x86/kernel/cpu/microcode/core.c +1 -10
@@ -465,16 +465,8 @@ static void mc_bp_resume(void)if (uci->valid && uci->mc) microcode_ops->apply_microcode (cpu); -#ifdef CONFIG_X86_64 else if (!uci->mc) -/* -* We might resume and not have applied late microcode but still -* have a newer patch stashed from the early loader. We don't -* have it in uci->mc so we have to load it the same way we're -* applying patches early on the APs. -*/ -load_ucode_ap (); -#endif +reload_early_microcode (); } --
Thanks.
Boris Ostrovsky (1):
x86, microcode: Don't initialize microcode code on paravirt
Borislav Petkov (2):
x86, microcode, intel: Drop unused parameter
x86, microcode: Reload microcode on resume
arch/x86/include/asm/microcode.h | 2 ++ arch/x86/include/asm/microcode_amd.h | 2 ++ arch/x86/include/asm/microcode_intel.h | 2 ++ arch/x86/kernel/cpu/microcode/amd_early.c | 18 +++++++++++ arch/x86/kernel/cpu/microcode/core.c | 10 ++---- arch/x86/kernel/cpu/microcode/core_early.c | 21 +++++++++++++ arch/x86/kernel/cpu/microcode/intel_early.c | 48 +++++++++++++++++++++++------ 7 files changed, 85 insertions(+), 18 deletions(-)
Signature · 1 line
2.0.0
Borislav Petkov
maintainerPATCH 1/3 x86, microcode, intel: Drop unused parameter
From: Borislav Petkov <[email protected]>
apply_microcode_early() doesn't use mc_saved_data, kill it.
--- arch/x86/kernel/cpu/microcode/intel_early.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
arch/x86/kernel/cpu/microcode/intel_early.c +3 -4
@@ -650,8 +650,7 @@ static inline void print_ucode(struct ucode_cpu_info *uci) }#endif -static int apply_microcode_early (struct mc_saved_data *mc_saved_data, -struct ucode_cpu_info *uci) +static int apply_microcode_early (struct ucode_cpu_info *uci) {struct microcode_intel *mc_intel;unsigned int val[2 ];
@@ -720,7 +719,7 @@ _load_ucode_intel_bsp(struct mc_saved_data *mc_saved_data, mc_saved_in_initrd, uci);load_microcode (mc_saved_data, mc_saved_in_initrd, initrd_start_early, uci); -apply_microcode_early (mc_saved_data, uci); +apply_microcode_early (uci); }void __init
@@ -783,5 +782,5 @@ void load_ucode_intel_ap(void)collect_cpu_info_early (&uci);load_microcode (mc_saved_data_p, mc_saved_in_initrd_p, initrd_start_addr, &uci); -apply_microcode_early (mc_saved_data_p, &uci); +apply_microcode_early (&uci); }
Signature · 1 line
2.0.0
Borislav Petkov
maintainerPATCH 2/3 x86, microcode: Don't initialize microcode code on paravirt
In reply to Borislav PetkovFrom: Boris Ostrovsky <[email protected]>
Paravirtual guests are not expected to load microcode into processors and therefore it is not necessary to initialize microcode loading logic.
In fact, under certain circumstances initializing this logic may cause the guest to crash. Specifically, 32-bit kernels use __pa_nodebug() macro which does not work in Xen (the code path that leads to this macro happens during resume when we call mc_bp_resume()->load_ucode_ap() ->check_loader_disabled_ap())
--- arch/x86/kernel/cpu/microcode/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kernel/cpu/microcode/core.c +1 -1
@@ -557,7 +557,7 @@ static int __init microcode_init(void)struct cpuinfo_x86 *c = &cpu_data (0 );int error; -if (dis_ucode_ldr) +if (paravirt_enabled () || dis_ucode_ldr)return 0 ;if (c->x86_vendor ==X86_VENDOR_INTEL )
Signature · 1 line
2.0.0
Borislav Petkov
maintainerPATCH 3/3 x86, microcode: Reload microcode on resume
In reply to Borislav PetkovFrom: Borislav Petkov <[email protected]>
Normally, we do reapply microcode on resume. However, in the cases where that microcode comes from the early loader and the late loader hasn't been utilized yet, there's no easy way for us to go and apply the patch applied during boot by the early loader.
Thus, reuse the patch stashed by the early loader for the BSP.
--- arch/x86/include/asm/microcode.h | 2 ++ arch/x86/include/asm/microcode_amd.h | 2 ++ arch/x86/include/asm/microcode_intel.h | 2 ++ arch/x86/kernel/cpu/microcode/amd_early.c | 18 +++++++++++ arch/x86/kernel/cpu/microcode/core.c | 8 +---- arch/x86/kernel/cpu/microcode/core_early.c | 21 +++++++++++++ arch/x86/kernel/cpu/microcode/intel_early.c | 47 +++++++++++++++++++++++------ 7 files changed, 84 insertions(+), 16 deletions(-)
arch/x86/include/asm/microcode.h +2 -0
@@ -78,6 +78,7 @@ static inline void __exit exit_amd_microcode(void) {}extern void __init load_ucode_bsp (void );extern void load_ucode_ap (void );extern int __init save_microcode_in_initrd (void ); +void reload_early_microcode (void );#else static inline void __init load_ucode_bsp (void ) {}static inline void load_ucode_ap (void ) {}
@@ -85,6 +86,7 @@ static inline int __init save_microcode_in_initrd(void) {return 0 ; } +static inline void reload_early_microcode (void ) {}#endif #endif /* _ASM_X86_MICROCODE_H */
arch/x86/include/asm/microcode_amd.h +2 -0
@@ -68,10 +68,12 @@ extern u8 amd_ucode_patch[PATCH_MAX_SIZE];extern void __init load_ucode_amd_bsp (void );extern void load_ucode_amd_ap (void );extern int __init save_microcode_in_initrd_amd (void ); +void reload_ucode_amd (void );#else static inline void __init load_ucode_amd_bsp (void ) {}static inline void load_ucode_amd_ap (void ) {}static inline int __init save_microcode_in_initrd_amd (void ) {return -EINVAL ; } +void reload_ucode_amd (void ) {}#endif #endif /* _ASM_X86_MICROCODE_AMD_H */
arch/x86/include/asm/microcode_intel.h +2 -0
@@ -68,11 +68,13 @@ extern void __init load_ucode_intel_bsp(void);extern void load_ucode_intel_ap (void );extern void show_ucode_info_early (void );extern int __init save_microcode_in_initrd_intel (void ); +void reload_ucode_intel (void );#else static inline __init void load_ucode_intel_bsp (void ) {}static inline void load_ucode_intel_ap (void ) {}static inline void show_ucode_info_early (void ) {}static inline int __init save_microcode_in_initrd_intel (void ) {return -EINVAL ; } +static inline void reload_ucode_intel (void ) {}#endif #if defined(CONFIG_MICROCODE_INTEL_EARLY ) && defined(CONFIG_HOTPLUG_CPU )
arch/x86/kernel/cpu/microcode/amd_early.c +18 -0
@@ -402,3 +402,21 @@ int __init save_microcode_in_initrd_amd(void)return retval; } + +void reload_ucode_amd (void ) +{ +struct microcode_amd *mc; +u32 rev, eax; + +rdmsr (MSR_AMD64_PATCH_LEVEL , rev, eax); + + mc = (struct microcode_amd *)amd_ucode_patch; + +if (mc && rev < mc->hdr.patch_id) { +if (!__apply_microcode_amd (mc)) { + ucode_new_rev = mc->hdr.patch_id; +pr_info ("microcode: reload patch_level=0x%08x\n" , + ucode_new_rev); + } + } +}
arch/x86/kernel/cpu/microcode/core.c +1 -7
@@ -466,13 +466,7 @@ static void mc_bp_resume(void)if (uci->valid && uci->mc) microcode_ops->apply_microcode (cpu);else if (!uci->mc) -/* -* We might resume and not have applied late microcode but still -* have a newer patch stashed from the early loader. We don't -* have it in uci->mc so we have to load it the same way we're -* applying patches early on the APs. -*/ -load_ucode_ap (); +reload_early_microcode (); }static struct syscore_ops mc_syscore_ops = {
arch/x86/kernel/cpu/microcode/core_early.c +21 -0
@@ -176,3 +176,24 @@ int __init save_microcode_in_initrd(void)return 0 ; } + +void reload_early_microcode (void ) +{ +int vendor, x86; + + vendor =x86_vendor (); + x86 =x86_family (); + +switch (vendor) { +case X86_VENDOR_INTEL : +if (x86 >=6 ) +reload_ucode_intel (); +break ; +case X86_VENDOR_AMD : +if (x86 >=0x10 ) +reload_ucode_amd (); +break ; +default : +break ; + } +}
arch/x86/kernel/cpu/microcode/intel_early.c +38 -9
102 lines not on this page · raw message
Signature · 1 line
2.0.0
Quoted 47 lines · Borislav Petkov
From: Borislav Petkov <[email protected]>
Hi guys,
please pull three fixes for the microcode loader. More specifically, microcode reloading for 3.19. Patches are against tip/x86/microcode.
I have this also as a tag if you'd prefer to pull:
git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp.gittags/microcode_fixes_for_3.19This will have a conflict when merging into Linus' tree after tip/x86/urgent has went in for 3.18 but resolving it should be easy. The final result should be this with the ifdef dropped:
---
arch/x86/kernel/cpu/microcode/core.c +1
-10@@ -465,16 +465,8 @@ static void mc_bp_resume(void)if (uci->valid && uci->mc) microcode_ops->apply_microcode (cpu); -#ifdef CONFIG_X86_64 else if (!uci->mc) -/* -* We might resume and not have applied late microcode but still -* have a newer patch stashed from the early loader. We don't -* have it in uci->mc so we have to load it the same way we're -* applying patches early on the APs. -*/ -load_ucode_ap (); -#endif +reload_early_microcode (); } --Thanks.
Boris Ostrovsky (1):
x86, microcode: Don't initialize microcode code on paravirtBorislav Petkov (2):
x86, microcode, intel: Drop unused parameter
x86, microcode: Reload microcode on resume
Quoted 8 lines
arch/x86/include/asm/microcode.h | 2 ++ arch/x86/include/asm/microcode_amd.h | 2 ++ arch/x86/include/asm/microcode_intel.h | 2 ++ arch/x86/kernel/cpu/microcode/amd_early.c | 18 +++++++++++ arch/x86/kernel/cpu/microcode/core.c | 10 ++---- arch/x86/kernel/cpu/microcode/core_early.c | 21 +++++++++++++ arch/x86/kernel/cpu/microcode/intel_early.c | 48 +++++++++++++++++++++++------ 7 files changed, 85 insertions(+), 18 deletions(-)
Pulled into tip:x86/microcode, thanks a lot Boris!
Ingo