@@ -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+
353362static __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)
663631static 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