aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/microcode_amd.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/microcode_amd.c')
-rw-r--r--arch/x86/kernel/microcode_amd.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/arch/x86/kernel/microcode_amd.c b/arch/x86/kernel/microcode_amd.c
index 8f11f8f90e98..47ebb1dbfbcb 100644
--- a/arch/x86/kernel/microcode_amd.c
+++ b/arch/x86/kernel/microcode_amd.c
@@ -126,9 +126,20 @@ static struct ucode_patch *find_patch(unsigned int cpu)
126static int collect_cpu_info_amd(int cpu, struct cpu_signature *csig) 126static int collect_cpu_info_amd(int cpu, struct cpu_signature *csig)
127{ 127{
128 struct cpuinfo_x86 *c = &cpu_data(cpu); 128 struct cpuinfo_x86 *c = &cpu_data(cpu);
129 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
130 struct ucode_patch *p;
129 131
130 csig->sig = cpuid_eax(0x00000001); 132 csig->sig = cpuid_eax(0x00000001);
131 csig->rev = c->microcode; 133 csig->rev = c->microcode;
134
135 /*
136 * a patch could have been loaded early, set uci->mc so that
137 * mc_bp_resume() can call apply_microcode()
138 */
139 p = find_patch(cpu);
140 if (p && (p->patch_id == csig->rev))
141 uci->mc = p->data;
142
132 pr_info("CPU%d: patch_level=0x%08x\n", cpu, csig->rev); 143 pr_info("CPU%d: patch_level=0x%08x\n", cpu, csig->rev);
133 144
134 return 0; 145 return 0;
@@ -373,6 +384,17 @@ enum ucode_state load_microcode_amd(int cpu, const u8 *data, size_t size)
373 if (ret != UCODE_OK) 384 if (ret != UCODE_OK)
374 cleanup(); 385 cleanup();
375 386
387#if defined(CONFIG_MICROCODE_AMD_EARLY) && defined(CONFIG_X86_32)
388 /* save BSP's matching patch for early load */
389 if (cpu_data(cpu).cpu_index == boot_cpu_data.cpu_index) {
390 struct ucode_patch *p = find_patch(cpu);
391 if (p) {
392 memset(amd_bsp_mpb, 0, MPB_MAX_SIZE);
393 memcpy(amd_bsp_mpb, p->data, min_t(u32, ksize(p->data),
394 MPB_MAX_SIZE));
395 }
396 }
397#endif
376 return ret; 398 return ret;
377} 399}
378 400