From: Greg Kroah-Hartman Date: Tue, 6 Jan 2015 23:26:08 +0000 (-0800) Subject: 3.18-stable patches X-Git-Tag: v3.10.64~15 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=dfb5608b37da2c629e66ff3c15933822ec600eac;p=thirdparty%2Fkernel%2Fstable-queue.git 3.18-stable patches added patches: isofs-fix-unchecked-printing-of-er-records.patch x86-microcode-amd-do-not-use-smp_processor_id-in-preemtible-context.patch x86-microcode-don-t-initialize-microcode-code-on-paravirt.patch x86-microcode-intel-drop-unused-parameter.patch x86-microcode-intel-fish-out-the-stashed-microcode-for-the-bsp.patch x86-microcode-reload-microcode-on-resume.patch --- diff --git a/queue-3.18/isofs-fix-unchecked-printing-of-er-records.patch b/queue-3.18/isofs-fix-unchecked-printing-of-er-records.patch new file mode 100644 index 00000000000..f57a3660f3a --- /dev/null +++ b/queue-3.18/isofs-fix-unchecked-printing-of-er-records.patch @@ -0,0 +1,33 @@ +From 4e2024624e678f0ebb916e6192bd23c1f9fdf696 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Thu, 18 Dec 2014 17:26:10 +0100 +Subject: isofs: Fix unchecked printing of ER records + +From: Jan Kara + +commit 4e2024624e678f0ebb916e6192bd23c1f9fdf696 upstream. + +We didn't check length of rock ridge ER records before printing them. +Thus corrupted isofs image can cause us to access and print some memory +behind the buffer with obvious consequences. + +Reported-and-tested-by: Carl Henrik Lunde +Signed-off-by: Jan Kara +Signed-off-by: Greg Kroah-Hartman + +--- + fs/isofs/rock.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/fs/isofs/rock.c ++++ b/fs/isofs/rock.c +@@ -362,6 +362,9 @@ repeat: + rs.cont_size = isonum_733(rr->u.CE.size); + break; + case SIG('E', 'R'): ++ /* Invalid length of ER tag id? */ ++ if (rr->u.ER.len_id + offsetof(struct rock_ridge, u.ER.data) > rr->len) ++ goto out; + ISOFS_SB(inode->i_sb)->s_rock = 1; + printk(KERN_DEBUG "ISO 9660 Extensions: "); + { diff --git a/queue-3.18/series b/queue-3.18/series index 393e35eba1e..76dde376741 100644 --- a/queue-3.18/series +++ b/queue-3.18/series @@ -38,3 +38,9 @@ arm-mvebu-remove-conflicting-muxing-on-armada-370-db.patch arm-mvebu-fix-ordering-in-armada-370-.dtsi.patch x86-asm-traps-disable-tracing-and-kprobes-in-fixup_bad_iret-and-sync_regs.patch x86-tls-don-t-validate-lm-in-set_thread_area-after-all.patch +isofs-fix-unchecked-printing-of-er-records.patch +x86-microcode-amd-do-not-use-smp_processor_id-in-preemtible-context.patch +x86-microcode-intel-drop-unused-parameter.patch +x86-microcode-don-t-initialize-microcode-code-on-paravirt.patch +x86-microcode-reload-microcode-on-resume.patch +x86-microcode-intel-fish-out-the-stashed-microcode-for-the-bsp.patch diff --git a/queue-3.18/x86-microcode-amd-do-not-use-smp_processor_id-in-preemtible-context.patch b/queue-3.18/x86-microcode-amd-do-not-use-smp_processor_id-in-preemtible-context.patch new file mode 100644 index 00000000000..53e43f3fc76 --- /dev/null +++ b/queue-3.18/x86-microcode-amd-do-not-use-smp_processor_id-in-preemtible-context.patch @@ -0,0 +1,82 @@ +From 2ef84b3bb97f03332f0c1edb4466b1750dcf97b5 Mon Sep 17 00:00:00 2001 +From: Borislav Petkov +Date: Mon, 1 Dec 2014 11:12:21 +0100 +Subject: x86, microcode, AMD: Do not use smp_processor_id() in preemtible context + +From: Borislav Petkov + +commit 2ef84b3bb97f03332f0c1edb4466b1750dcf97b5 upstream. + +Hand down the cpu number instead, otherwise lockdep screams when doing + +echo 1 > /sys/devices/system/cpu/microcode/reload. + +BUG: using smp_processor_id() in preemptible [00000000] code: amd64-microcode/2470 +caller is debug_smp_processor_id+0x12/0x20 +CPU: 1 PID: 2470 Comm: amd64-microcode Not tainted 3.18.0-rc6+ #26 +... + +Signed-off-by: Borislav Petkov +Link: http://lkml.kernel.org/r/1417428741-4501-1-git-send-email-bp@alien8.de +Signed-off-by: Thomas Gleixner +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/include/asm/microcode_amd.h | 2 +- + arch/x86/kernel/cpu/microcode/amd.c | 8 ++++---- + arch/x86/kernel/cpu/microcode/amd_early.c | 2 +- + 3 files changed, 6 insertions(+), 6 deletions(-) + +--- a/arch/x86/include/asm/microcode_amd.h ++++ b/arch/x86/include/asm/microcode_amd.h +@@ -59,7 +59,7 @@ static inline u16 find_equiv_id(struct e + + extern int __apply_microcode_amd(struct microcode_amd *mc_amd); + extern int apply_microcode_amd(int cpu); +-extern enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t size); ++extern enum ucode_state load_microcode_amd(int cpu, u8 family, const u8 *data, size_t size); + + #define PATCH_MAX_SIZE PAGE_SIZE + extern u8 amd_ucode_patch[PATCH_MAX_SIZE]; +--- a/arch/x86/kernel/cpu/microcode/amd.c ++++ b/arch/x86/kernel/cpu/microcode/amd.c +@@ -376,7 +376,7 @@ static enum ucode_state __load_microcode + return UCODE_OK; + } + +-enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t size) ++enum ucode_state load_microcode_amd(int cpu, u8 family, const u8 *data, size_t size) + { + enum ucode_state ret; + +@@ -390,8 +390,8 @@ enum ucode_state load_microcode_amd(u8 f + + #if defined(CONFIG_MICROCODE_AMD_EARLY) && defined(CONFIG_X86_32) + /* save BSP's matching patch for early load */ +- if (cpu_data(smp_processor_id()).cpu_index == boot_cpu_data.cpu_index) { +- struct ucode_patch *p = find_patch(smp_processor_id()); ++ if (cpu_data(cpu).cpu_index == boot_cpu_data.cpu_index) { ++ struct ucode_patch *p = find_patch(cpu); + if (p) { + memset(amd_ucode_patch, 0, PATCH_MAX_SIZE); + memcpy(amd_ucode_patch, p->data, min_t(u32, ksize(p->data), +@@ -444,7 +444,7 @@ static enum ucode_state request_microcod + goto fw_release; + } + +- ret = load_microcode_amd(c->x86, fw->data, fw->size); ++ ret = load_microcode_amd(cpu, c->x86, fw->data, fw->size); + + fw_release: + release_firmware(fw); +--- a/arch/x86/kernel/cpu/microcode/amd_early.c ++++ b/arch/x86/kernel/cpu/microcode/amd_early.c +@@ -389,7 +389,7 @@ int __init save_microcode_in_initrd_amd( + eax = cpuid_eax(0x00000001); + eax = ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff); + +- ret = load_microcode_amd(eax, container, container_size); ++ ret = load_microcode_amd(smp_processor_id(), eax, container, container_size); + if (ret != UCODE_OK) + retval = -EINVAL; + diff --git a/queue-3.18/x86-microcode-don-t-initialize-microcode-code-on-paravirt.patch b/queue-3.18/x86-microcode-don-t-initialize-microcode-code-on-paravirt.patch new file mode 100644 index 00000000000..037db030a91 --- /dev/null +++ b/queue-3.18/x86-microcode-don-t-initialize-microcode-code-on-paravirt.patch @@ -0,0 +1,39 @@ +From a18a0f6850d4b286a5ebf02cd5b22fe496b86349 Mon Sep 17 00:00:00 2001 +From: Boris Ostrovsky +Date: Mon, 1 Dec 2014 16:27:44 -0500 +Subject: x86, microcode: Don't initialize microcode code on paravirt + +From: Boris Ostrovsky + +commit a18a0f6850d4b286a5ebf02cd5b22fe496b86349 upstream. + +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()) + +Signed-off-by: Boris Ostrovsky +Link: http://lkml.kernel.org/r/1417469264-31470-1-git-send-email-boris.ostrovsky@oracle.com +Signed-off-by: Borislav Petkov +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/cpu/microcode/core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/x86/kernel/cpu/microcode/core.c ++++ b/arch/x86/kernel/cpu/microcode/core.c +@@ -559,7 +559,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) diff --git a/queue-3.18/x86-microcode-intel-drop-unused-parameter.patch b/queue-3.18/x86-microcode-intel-drop-unused-parameter.patch new file mode 100644 index 00000000000..5a82e168759 --- /dev/null +++ b/queue-3.18/x86-microcode-intel-drop-unused-parameter.patch @@ -0,0 +1,46 @@ +From 47768626c6db42cd06ff077ba12dd2cb10ab818b Mon Sep 17 00:00:00 2001 +From: Borislav Petkov +Date: Mon, 1 Dec 2014 17:50:16 +0100 +Subject: x86, microcode, intel: Drop unused parameter + +From: Borislav Petkov + +commit 47768626c6db42cd06ff077ba12dd2cb10ab818b upstream. + +apply_microcode_early() doesn't use mc_saved_data, kill it. + +Signed-off-by: Borislav Petkov +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/cpu/microcode/intel_early.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +--- a/arch/x86/kernel/cpu/microcode/intel_early.c ++++ b/arch/x86/kernel/cpu/microcode/intel_early.c +@@ -650,8 +650,7 @@ static inline void print_ucode(struct uc + } + #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_da + 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); + } diff --git a/queue-3.18/x86-microcode-intel-fish-out-the-stashed-microcode-for-the-bsp.patch b/queue-3.18/x86-microcode-intel-fish-out-the-stashed-microcode-for-the-bsp.patch new file mode 100644 index 00000000000..7f26366beb6 --- /dev/null +++ b/queue-3.18/x86-microcode-intel-fish-out-the-stashed-microcode-for-the-bsp.patch @@ -0,0 +1,115 @@ +From 25cdb9c86826f8d035d8aaa07fc36832e76bd8a0 Mon Sep 17 00:00:00 2001 +From: Borislav Petkov +Date: Mon, 8 Dec 2014 12:08:20 +0100 +Subject: x86/microcode/intel: Fish out the stashed microcode for the BSP + +From: Borislav Petkov + +commit 25cdb9c86826f8d035d8aaa07fc36832e76bd8a0 upstream. + +I'm such a moron! The simple solution of saving the BSP patch +for use on resume was too simple (and wrong!), hint: +sizeof(struct microcode_intel). + +What needs to be done instead is to fish out the microcode patch +we have stashed previously and apply that on the BSP in case the +late loader hasn't been utilized. + +So do that instead. + +Signed-off-by: Borislav Petkov +Cc: Linus Torvalds +Link: http://lkml.kernel.org/r/20141208110820.GB20057@pd.tnic +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/cpu/microcode/intel_early.c | 26 ++++++++++++-------------- + 1 file changed, 12 insertions(+), 14 deletions(-) + +--- a/arch/x86/kernel/cpu/microcode/intel_early.c ++++ b/arch/x86/kernel/cpu/microcode/intel_early.c +@@ -34,8 +34,6 @@ static struct mc_saved_data { + struct microcode_intel **mc_saved; + } mc_saved_data; + +-static struct microcode_intel bsp_patch; +- + static enum ucode_state + generic_load_microcode_early(struct microcode_intel **mc_saved_p, + unsigned int mc_saved_count, +@@ -717,8 +715,7 @@ _load_ucode_intel_bsp(struct mc_saved_da + unsigned long *mc_saved_in_initrd, + unsigned long initrd_start_early, + unsigned long initrd_end_early, +- struct ucode_cpu_info *uci, +- struct microcode_intel *bsp) ++ struct ucode_cpu_info *uci) + { + enum ucode_state ret; + +@@ -729,10 +726,8 @@ _load_ucode_intel_bsp(struct mc_saved_da + ret = load_microcode(mc_saved_data, mc_saved_in_initrd, + initrd_start_early, uci); + +- if (ret == UCODE_OK) { ++ if (ret == UCODE_OK) + apply_microcode_early(uci, true); +- memcpy(bsp, uci->mc, sizeof(*bsp)); +- } + } + + void __init +@@ -741,12 +736,10 @@ load_ucode_intel_bsp(void) + u64 ramdisk_image, ramdisk_size; + unsigned long initrd_start_early, initrd_end_early; + struct ucode_cpu_info uci; +- struct microcode_intel *bsp_p; + #ifdef CONFIG_X86_32 + struct boot_params *boot_params_p; + + boot_params_p = (struct boot_params *)__pa_nodebug(&boot_params); +- bsp_p = (struct microcode_intel *)__pa_nodebug(&bsp_patch); + ramdisk_image = boot_params_p->hdr.ramdisk_image; + ramdisk_size = boot_params_p->hdr.ramdisk_size; + initrd_start_early = ramdisk_image; +@@ -755,9 +748,8 @@ load_ucode_intel_bsp(void) + _load_ucode_intel_bsp( + (struct mc_saved_data *)__pa_nodebug(&mc_saved_data), + (unsigned long *)__pa_nodebug(&mc_saved_in_initrd), +- initrd_start_early, initrd_end_early, &uci, bsp_p); ++ initrd_start_early, initrd_end_early, &uci); + #else +- bsp_p = &bsp_patch; + ramdisk_image = boot_params.hdr.ramdisk_image; + ramdisk_size = boot_params.hdr.ramdisk_size; + initrd_start_early = ramdisk_image + PAGE_OFFSET; +@@ -765,7 +757,7 @@ load_ucode_intel_bsp(void) + + _load_ucode_intel_bsp(&mc_saved_data, mc_saved_in_initrd, + initrd_start_early, initrd_end_early, +- &uci, bsp_p); ++ &uci); + #endif + } + +@@ -805,11 +797,17 @@ void load_ucode_intel_ap(void) + void reload_ucode_intel(void) + { + struct ucode_cpu_info uci; ++ enum ucode_state ret; + +- if (!bsp_patch.hdr.rev) ++ if (!mc_saved_data.mc_saved_count) + return; + +- uci.mc = &bsp_patch; ++ collect_cpu_info_early(&uci); ++ ++ ret = generic_load_microcode_early(mc_saved_data.mc_saved, ++ mc_saved_data.mc_saved_count, &uci); ++ if (ret != UCODE_OK) ++ return; + + apply_microcode_early(&uci, false); + } diff --git a/queue-3.18/x86-microcode-reload-microcode-on-resume.patch b/queue-3.18/x86-microcode-reload-microcode-on-resume.patch new file mode 100644 index 00000000000..990fdf48d95 --- /dev/null +++ b/queue-3.18/x86-microcode-reload-microcode-on-resume.patch @@ -0,0 +1,260 @@ +From fbae4ba8c4a387e306adc9c710e5c225cece7678 Mon Sep 17 00:00:00 2001 +From: Borislav Petkov +Date: Wed, 3 Dec 2014 17:21:41 +0100 +Subject: x86, microcode: Reload microcode on resume + +From: Borislav Petkov + +commit fbae4ba8c4a387e306adc9c710e5c225cece7678 upstream. + +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. + +Signed-off-by: Borislav Petkov +Signed-off-by: Greg Kroah-Hartman + +--- + 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 | 47 ++++++++++++++++++++++------ + 7 files changed, 84 insertions(+), 18 deletions(-) + +--- a/arch/x86/include/asm/microcode.h ++++ b/arch/x86/include/asm/microcode.h +@@ -78,6 +78,7 @@ static inline void __exit exit_amd_micro + 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_ + { + return 0; + } ++static inline void reload_early_microcode(void) {} + #endif + + #endif /* _ASM_X86_MICROCODE_H */ +--- a/arch/x86/include/asm/microcode_amd.h ++++ b/arch/x86/include/asm/microcode_amd.h +@@ -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 */ +--- a/arch/x86/include/asm/microcode_intel.h ++++ b/arch/x86/include/asm/microcode_intel.h +@@ -68,11 +68,13 @@ extern void __init load_ucode_intel_bsp( + 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) +--- a/arch/x86/kernel/cpu/microcode/amd_early.c ++++ b/arch/x86/kernel/cpu/microcode/amd_early.c +@@ -402,3 +402,21 @@ int __init save_microcode_in_initrd_amd( + + 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); ++ } ++ } ++} +--- a/arch/x86/kernel/cpu/microcode/core.c ++++ b/arch/x86/kernel/cpu/microcode/core.c +@@ -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(); + } + + static struct syscore_ops mc_syscore_ops = { +--- a/arch/x86/kernel/cpu/microcode/core_early.c ++++ b/arch/x86/kernel/cpu/microcode/core_early.c +@@ -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; ++ } ++} +--- a/arch/x86/kernel/cpu/microcode/intel_early.c ++++ b/arch/x86/kernel/cpu/microcode/intel_early.c +@@ -34,6 +34,8 @@ static struct mc_saved_data { + struct microcode_intel **mc_saved; + } mc_saved_data; + ++static struct microcode_intel bsp_patch; ++ + static enum ucode_state + generic_load_microcode_early(struct microcode_intel **mc_saved_p, + unsigned int mc_saved_count, +@@ -650,7 +652,7 @@ static inline void print_ucode(struct uc + } + #endif + +-static int apply_microcode_early(struct ucode_cpu_info *uci) ++static int apply_microcode_early(struct ucode_cpu_info *uci, bool early) + { + struct microcode_intel *mc_intel; + unsigned int val[2]; +@@ -679,7 +681,10 @@ static int apply_microcode_early(struct + #endif + uci->cpu_sig.rev = val[1]; + +- print_ucode(uci); ++ if (early) ++ print_ucode(uci); ++ else ++ print_ucode_info(uci, mc_intel->hdr.date); + + return 0; + } +@@ -712,14 +717,22 @@ _load_ucode_intel_bsp(struct mc_saved_da + unsigned long *mc_saved_in_initrd, + unsigned long initrd_start_early, + unsigned long initrd_end_early, +- struct ucode_cpu_info *uci) ++ struct ucode_cpu_info *uci, ++ struct microcode_intel *bsp) + { ++ enum ucode_state ret; ++ + collect_cpu_info_early(uci); + scan_microcode(initrd_start_early, initrd_end_early, mc_saved_data, + mc_saved_in_initrd, uci); +- load_microcode(mc_saved_data, mc_saved_in_initrd, +- initrd_start_early, uci); +- apply_microcode_early(uci); ++ ++ ret = load_microcode(mc_saved_data, mc_saved_in_initrd, ++ initrd_start_early, uci); ++ ++ if (ret == UCODE_OK) { ++ apply_microcode_early(uci, true); ++ memcpy(bsp, uci->mc, sizeof(*bsp)); ++ } + } + + void __init +@@ -728,10 +741,12 @@ load_ucode_intel_bsp(void) + u64 ramdisk_image, ramdisk_size; + unsigned long initrd_start_early, initrd_end_early; + struct ucode_cpu_info uci; ++ struct microcode_intel *bsp_p; + #ifdef CONFIG_X86_32 + struct boot_params *boot_params_p; + + boot_params_p = (struct boot_params *)__pa_nodebug(&boot_params); ++ bsp_p = (struct microcode_intel *)__pa_nodebug(&bsp_patch); + ramdisk_image = boot_params_p->hdr.ramdisk_image; + ramdisk_size = boot_params_p->hdr.ramdisk_size; + initrd_start_early = ramdisk_image; +@@ -740,15 +755,17 @@ load_ucode_intel_bsp(void) + _load_ucode_intel_bsp( + (struct mc_saved_data *)__pa_nodebug(&mc_saved_data), + (unsigned long *)__pa_nodebug(&mc_saved_in_initrd), +- initrd_start_early, initrd_end_early, &uci); ++ initrd_start_early, initrd_end_early, &uci, bsp_p); + #else ++ bsp_p = &bsp_patch; + ramdisk_image = boot_params.hdr.ramdisk_image; + ramdisk_size = boot_params.hdr.ramdisk_size; + initrd_start_early = ramdisk_image + PAGE_OFFSET; + initrd_end_early = initrd_start_early + ramdisk_size; + + _load_ucode_intel_bsp(&mc_saved_data, mc_saved_in_initrd, +- initrd_start_early, initrd_end_early, &uci); ++ initrd_start_early, initrd_end_early, ++ &uci, bsp_p); + #endif + } + +@@ -782,5 +799,17 @@ 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(&uci); ++ apply_microcode_early(&uci, true); ++} ++ ++void reload_ucode_intel(void) ++{ ++ struct ucode_cpu_info uci; ++ ++ if (!bsp_patch.hdr.rev) ++ return; ++ ++ uci.mc = &bsp_patch; ++ ++ apply_microcode_early(&uci, false); + }