@@ -70,11 +70,6 @@ LIST_HEAD(microcode_cache);
70
70
*/
71
71
static DEFINE_MUTEX (microcode_mutex );
72
72
73
- /*
74
- * Serialize late loading so that CPUs get updated one-by-one.
75
- */
76
- static DEFINE_RAW_SPINLOCK (update_lock );
77
-
78
73
struct ucode_cpu_info ucode_cpu_info [NR_CPUS ];
79
74
80
75
struct cpu_info_ctx {
@@ -579,11 +574,18 @@ static int __reload_late(void *info)
579
574
if (__wait_for_cpus (& late_cpus_in , NSEC_PER_SEC ))
580
575
return -1 ;
581
576
582
- raw_spin_lock (& update_lock );
583
- apply_microcode_local (& err );
584
- raw_spin_unlock (& update_lock );
577
+ /*
578
+ * On an SMT system, it suffices to load the microcode on one sibling of
579
+ * the core because the microcode engine is shared between the threads.
580
+ * Synchronization still needs to take place so that no concurrent
581
+ * loading attempts happen on multiple threads of an SMT core. See
582
+ * below.
583
+ */
584
+ if (cpumask_first (topology_sibling_cpumask (cpu )) == cpu )
585
+ apply_microcode_local (& err );
586
+ else
587
+ goto wait_for_siblings ;
585
588
586
- /* siblings return UCODE_OK because their engine got updated already */
587
589
if (err > UCODE_NFOUND ) {
588
590
pr_warn ("Error reloading microcode on CPU %d\n" , cpu );
589
591
ret = -1 ;
@@ -597,14 +599,18 @@ static int __reload_late(void *info)
597
599
memcpy (& boot_cpu_data , c , sizeof (boot_cpu_data ));
598
600
}
599
601
602
+ wait_for_siblings :
603
+ if (__wait_for_cpus (& late_cpus_out , NSEC_PER_SEC ))
604
+ panic ("Timeout during microcode update!\n" );
605
+
600
606
/*
601
- * Increase the wait timeout to a safe value here since we're
602
- * serializing the microcode update and that could take a while on a
603
- * large number of CPUs. And that is fine as the *actual* timeout will
604
- * be determined by the last CPU finished updating and thus cut short .
607
+ * At least one thread has completed update on each core.
608
+ * For others, simply call the update to make sure the
609
+ * per-cpu cpuinfo can be updated with right microcode
610
+ * revision .
605
611
*/
606
- if (__wait_for_cpus ( & late_cpus_out , NSEC_PER_SEC * num_online_cpus ()) )
607
- panic ( "Timeout during microcode update!\n" );
612
+ if (cpumask_first ( topology_sibling_cpumask ( cpu )) != cpu )
613
+ apply_microcode_local ( & err );
608
614
609
615
return ret ;
610
616
}
0 commit comments