Skip to content

Commit 3973718

Browse files
KAGA-KOKObp3tk0v
authored andcommitted
x86/microcode/intel: Unify microcode apply() functions
Deduplicate the early and late apply() functions. [ bp: Rename the function which does the actual application to __apply_microcode() to differentiate it from microcode_ops.apply_microcode(). ] Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Link: https://lore.kernel.org/r/20231017211722.795508212@linutronix.de
1 parent f24f204 commit 3973718

1 file changed

Lines changed: 36 additions & 68 deletions

File tree

  • arch/x86/kernel/cpu/microcode

arch/x86/kernel/cpu/microcode/intel.c

Lines changed: 36 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -307,12 +307,12 @@ static __init struct microcode_intel *scan_microcode(void *data, size_t size,
307307
return size ? NULL : patch;
308308
}
309309

310-
static enum ucode_state apply_microcode_early(struct ucode_cpu_info *uci)
310+
static enum ucode_state __apply_microcode(struct ucode_cpu_info *uci,
311+
struct microcode_intel *mc,
312+
u32 *cur_rev)
311313
{
312-
struct microcode_intel *mc;
313-
u32 rev, old_rev, date;
314+
u32 rev;
314315

315-
mc = uci->mc;
316316
if (!mc)
317317
return UCODE_NFOUND;
318318

@@ -321,14 +321,12 @@ static enum ucode_state apply_microcode_early(struct ucode_cpu_info *uci)
321321
* operation - when the other hyperthread has updated the microcode
322322
* already.
323323
*/
324-
rev = intel_get_microcode_revision();
325-
if (rev >= mc->hdr.rev) {
326-
uci->cpu_sig.rev = rev;
324+
*cur_rev = intel_get_microcode_revision();
325+
if (*cur_rev >= mc->hdr.rev) {
326+
uci->cpu_sig.rev = *cur_rev;
327327
return UCODE_OK;
328328
}
329329

330-
old_rev = rev;
331-
332330
/*
333331
* Writeback and invalidate caches before updating microcode to avoid
334332
* internal issues depending on what the microcode is updating.
@@ -343,13 +341,24 @@ static enum ucode_state apply_microcode_early(struct ucode_cpu_info *uci)
343341
return UCODE_ERROR;
344342

345343
uci->cpu_sig.rev = rev;
346-
347-
date = mc->hdr.date;
348-
pr_info_once("updated early: 0x%x -> 0x%x, date = %04x-%02x-%02x\n",
349-
old_rev, rev, date & 0xffff, date >> 24, (date >> 16) & 0xff);
350344
return UCODE_UPDATED;
351345
}
352346

347+
static enum ucode_state apply_microcode_early(struct ucode_cpu_info *uci)
348+
{
349+
struct microcode_intel *mc = uci->mc;
350+
enum ucode_state ret;
351+
u32 cur_rev, date;
352+
353+
ret = __apply_microcode(uci, mc, &cur_rev);
354+
if (ret == UCODE_UPDATED) {
355+
date = mc->hdr.date;
356+
pr_info_once("updated early: 0x%x -> 0x%x, date = %04x-%02x-%02x\n",
357+
cur_rev, mc->hdr.rev, date & 0xffff, date >> 24, (date >> 16) & 0xff);
358+
}
359+
return ret;
360+
}
361+
353362
static __init bool load_builtin_intel_microcode(struct cpio_data *cp)
354363
{
355364
unsigned int eax = 1, ebx, ecx = 0, edx;
@@ -459,70 +468,29 @@ static int collect_cpu_info(int cpu_num, struct cpu_signature *csig)
459468
return 0;
460469
}
461470

462-
static enum ucode_state apply_microcode_intel(int cpu)
471+
static enum ucode_state apply_microcode_late(int cpu)
463472
{
464473
struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
465-
struct cpuinfo_x86 *c = &cpu_data(cpu);
466-
bool bsp = c->cpu_index == boot_cpu_data.cpu_index;
467-
struct microcode_intel *mc;
474+
struct microcode_intel *mc = ucode_patch_late;
468475
enum ucode_state ret;
469-
static int prev_rev;
470-
u32 rev;
476+
u32 cur_rev;
471477

472-
/* We should bind the task to the CPU */
473-
if (WARN_ON(raw_smp_processor_id() != cpu))
478+
if (WARN_ON_ONCE(smp_processor_id() != cpu))
474479
return UCODE_ERROR;
475480

476-
mc = ucode_patch_late;
477-
if (!mc)
478-
return UCODE_NFOUND;
481+
ret = __apply_microcode(uci, mc, &cur_rev);
482+
if (ret != UCODE_UPDATED && ret != UCODE_OK)
483+
return ret;
479484

480-
/*
481-
* Save us the MSR write below - which is a particular expensive
482-
* operation - when the other hyperthread has updated the microcode
483-
* already.
484-
*/
485-
rev = intel_get_microcode_revision();
486-
if (rev >= mc->hdr.rev) {
487-
ret = UCODE_OK;
488-
goto out;
489-
}
490-
491-
/*
492-
* Writeback and invalidate caches before updating microcode to avoid
493-
* internal issues depending on what the microcode is updating.
494-
*/
495-
native_wbinvd();
496-
497-
/* write microcode via MSR 0x79 */
498-
wrmsrl(MSR_IA32_UCODE_WRITE, (unsigned long)mc->bits);
499-
500-
rev = intel_get_microcode_revision();
501-
502-
if (rev != mc->hdr.rev) {
503-
pr_err("CPU%d update to revision 0x%x failed\n",
504-
cpu, mc->hdr.rev);
505-
return UCODE_ERROR;
506-
}
507-
508-
if (bsp && rev != prev_rev) {
509-
pr_info("updated to revision 0x%x, date = %04x-%02x-%02x\n",
510-
rev,
511-
mc->hdr.date & 0xffff,
512-
mc->hdr.date >> 24,
485+
if (!cpu && uci->cpu_sig.rev != cur_rev) {
486+
pr_info("Updated to revision 0x%x, date = %04x-%02x-%02x\n",
487+
uci->cpu_sig.rev, mc->hdr.date & 0xffff, mc->hdr.date >> 24,
513488
(mc->hdr.date >> 16) & 0xff);
514-
prev_rev = rev;
515489
}
516490

517-
ret = UCODE_UPDATED;
518-
519-
out:
520-
uci->cpu_sig.rev = rev;
521-
c->microcode = rev;
522-
523-
/* Update boot_cpu_data's revision too, if we're on the BSP: */
524-
if (bsp)
525-
boot_cpu_data.microcode = rev;
491+
cpu_data(cpu).microcode = uci->cpu_sig.rev;
492+
if (!cpu)
493+
boot_cpu_data.microcode = uci->cpu_sig.rev;
526494

527495
return ret;
528496
}
@@ -663,7 +631,7 @@ static void finalize_late_load(int result)
663631
static struct microcode_ops microcode_intel_ops = {
664632
.request_microcode_fw = request_microcode_fw,
665633
.collect_cpu_info = collect_cpu_info,
666-
.apply_microcode = apply_microcode_intel,
634+
.apply_microcode = apply_microcode_late,
667635
.finalize_late_load = finalize_late_load,
668636
};
669637

0 commit comments

Comments
 (0)