]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 6 Jan 2015 23:26:08 +0000 (15:26 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 6 Jan 2015 23:26:08 +0000 (15:26 -0800)
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

queue-3.18/isofs-fix-unchecked-printing-of-er-records.patch [new file with mode: 0644]
queue-3.18/series
queue-3.18/x86-microcode-amd-do-not-use-smp_processor_id-in-preemtible-context.patch [new file with mode: 0644]
queue-3.18/x86-microcode-don-t-initialize-microcode-code-on-paravirt.patch [new file with mode: 0644]
queue-3.18/x86-microcode-intel-drop-unused-parameter.patch [new file with mode: 0644]
queue-3.18/x86-microcode-intel-fish-out-the-stashed-microcode-for-the-bsp.patch [new file with mode: 0644]
queue-3.18/x86-microcode-reload-microcode-on-resume.patch [new file with mode: 0644]

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 (file)
index 0000000..f57a366
--- /dev/null
@@ -0,0 +1,33 @@
+From 4e2024624e678f0ebb916e6192bd23c1f9fdf696 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Thu, 18 Dec 2014 17:26:10 +0100
+Subject: isofs: Fix unchecked printing of ER records
+
+From: Jan Kara <jack@suse.cz>
+
+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 <chlunde@ping.uio.no>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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: ");
+                       {
index 393e35eba1e2450d38625379ce957f2653691faa..76dde37674192277dabcffd7c343efe148051626 100644 (file)
@@ -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 (file)
index 0000000..53e43f3
--- /dev/null
@@ -0,0 +1,82 @@
+From 2ef84b3bb97f03332f0c1edb4466b1750dcf97b5 Mon Sep 17 00:00:00 2001
+From: Borislav Petkov <bp@suse.de>
+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 <bp@suse.de>
+
+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 <bp@suse.de>
+Link: http://lkml.kernel.org/r/1417428741-4501-1-git-send-email-bp@alien8.de
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..037db03
--- /dev/null
@@ -0,0 +1,39 @@
+From a18a0f6850d4b286a5ebf02cd5b22fe496b86349 Mon Sep 17 00:00:00 2001
+From: Boris Ostrovsky <boris.ostrovsky@oracle.com>
+Date: Mon, 1 Dec 2014 16:27:44 -0500
+Subject: x86, microcode: Don't initialize microcode code on paravirt
+
+From: Boris Ostrovsky <boris.ostrovsky@oracle.com>
+
+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 <boris.ostrovsky@oracle.com>
+Link: http://lkml.kernel.org/r/1417469264-31470-1-git-send-email-boris.ostrovsky@oracle.com
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..5a82e16
--- /dev/null
@@ -0,0 +1,46 @@
+From 47768626c6db42cd06ff077ba12dd2cb10ab818b Mon Sep 17 00:00:00 2001
+From: Borislav Petkov <bp@suse.de>
+Date: Mon, 1 Dec 2014 17:50:16 +0100
+Subject: x86, microcode, intel: Drop unused parameter
+
+From: Borislav Petkov <bp@suse.de>
+
+commit 47768626c6db42cd06ff077ba12dd2cb10ab818b upstream.
+
+apply_microcode_early() doesn't use mc_saved_data, kill it.
+
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..7f26366
--- /dev/null
@@ -0,0 +1,115 @@
+From 25cdb9c86826f8d035d8aaa07fc36832e76bd8a0 Mon Sep 17 00:00:00 2001
+From: Borislav Petkov <bp@suse.de>
+Date: Mon, 8 Dec 2014 12:08:20 +0100
+Subject: x86/microcode/intel: Fish out the stashed microcode for the BSP
+
+From: Borislav Petkov <bp@suse.de>
+
+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 <bp@suse.de>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Link: http://lkml.kernel.org/r/20141208110820.GB20057@pd.tnic
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..990fdf4
--- /dev/null
@@ -0,0 +1,260 @@
+From fbae4ba8c4a387e306adc9c710e5c225cece7678 Mon Sep 17 00:00:00 2001
+From: Borislav Petkov <bp@suse.de>
+Date: Wed, 3 Dec 2014 17:21:41 +0100
+Subject: x86, microcode: Reload microcode on resume
+
+From: Borislav Petkov <bp@suse.de>
+
+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 <bp@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);
+ }