*/
 static DEFINE_MUTEX(microcode_mutex);
 
-/*
- * Serialize late loading so that CPUs get updated one-by-one.
- */
-static DEFINE_RAW_SPINLOCK(update_lock);
-
 struct ucode_cpu_info          ucode_cpu_info[NR_CPUS];
 
 struct cpu_info_ctx {
        if (__wait_for_cpus(&late_cpus_in, NSEC_PER_SEC))
                return -1;
 
-       raw_spin_lock(&update_lock);
-       apply_microcode_local(&err);
-       raw_spin_unlock(&update_lock);
+       /*
+        * On an SMT system, it suffices to load the microcode on one sibling of
+        * the core because the microcode engine is shared between the threads.
+        * Synchronization still needs to take place so that no concurrent
+        * loading attempts happen on multiple threads of an SMT core. See
+        * below.
+        */
+       if (cpumask_first(topology_sibling_cpumask(cpu)) == cpu)
+               apply_microcode_local(&err);
+       else
+               goto wait_for_siblings;
 
-       /* siblings return UCODE_OK because their engine got updated already */
        if (err > UCODE_NFOUND) {
                pr_warn("Error reloading microcode on CPU %d\n", cpu);
                ret = -1;
                ret = 1;
        }
 
+wait_for_siblings:
+       if (__wait_for_cpus(&late_cpus_out, NSEC_PER_SEC))
+               panic("Timeout during microcode update!\n");
+
        /*
-        * Increase the wait timeout to a safe value here since we're
-        * serializing the microcode update and that could take a while on a
-        * large number of CPUs. And that is fine as the *actual* timeout will
-        * be determined by the last CPU finished updating and thus cut short.
+        * At least one thread has completed update on each core.
+        * For others, simply call the update to make sure the
+        * per-cpu cpuinfo can be updated with right microcode
+        * revision.
         */
-       if (__wait_for_cpus(&late_cpus_out, NSEC_PER_SEC * num_online_cpus()))
-               panic("Timeout during microcode update!\n");
+       if (cpumask_first(topology_sibling_cpumask(cpu)) != cpu)
+               apply_microcode_local(&err);
 
        return ret;
 }