@@ -272,54 +272,65 @@ struct microcode_ctrl {
272272
273273DEFINE_STATIC_KEY_FALSE (microcode_nmi_handler_enable );
274274static DEFINE_PER_CPU (struct microcode_ctrl , ucode_ctrl ) ;
275+ static unsigned int loops_per_usec ;
275276static atomic_t late_cpus_in ;
276277
277- static bool wait_for_cpus (atomic_t * cnt )
278+ static noinstr bool wait_for_cpus (atomic_t * cnt )
278279{
279- unsigned int timeout ;
280+ unsigned int timeout , loops ;
280281
281- WARN_ON_ONCE (atomic_dec_return (cnt ) < 0 );
282+ WARN_ON_ONCE (raw_atomic_dec_return (cnt ) < 0 );
282283
283284 for (timeout = 0 ; timeout < USEC_PER_SEC ; timeout ++ ) {
284- if (!atomic_read (cnt ))
285+ if (!raw_atomic_read (cnt ))
285286 return true;
286287
287- udelay (1 );
288+ for (loops = 0 ; loops < loops_per_usec ; loops ++ )
289+ cpu_relax ();
288290
289291 /* If invoked directly, tickle the NMI watchdog */
290- if (!microcode_ops -> use_nmi && !(timeout % USEC_PER_MSEC ))
292+ if (!microcode_ops -> use_nmi && !(timeout % USEC_PER_MSEC )) {
293+ instrumentation_begin ();
291294 touch_nmi_watchdog ();
295+ instrumentation_end ();
296+ }
292297 }
293298 /* Prevent the late comers from making progress and let them time out */
294- atomic_inc (cnt );
299+ raw_atomic_inc (cnt );
295300 return false;
296301}
297302
298- static bool wait_for_ctrl (void )
303+ static noinstr bool wait_for_ctrl (void )
299304{
300- unsigned int timeout ;
305+ unsigned int timeout , loops ;
301306
302307 for (timeout = 0 ; timeout < USEC_PER_SEC ; timeout ++ ) {
303- if (this_cpu_read (ucode_ctrl .ctrl ) != SCTRL_WAIT )
308+ if (raw_cpu_read (ucode_ctrl .ctrl ) != SCTRL_WAIT )
304309 return true;
305- udelay (1 );
310+
311+ for (loops = 0 ; loops < loops_per_usec ; loops ++ )
312+ cpu_relax ();
313+
306314 /* If invoked directly, tickle the NMI watchdog */
307- if (!microcode_ops -> use_nmi && !(timeout % 1000 ))
315+ if (!microcode_ops -> use_nmi && !(timeout % USEC_PER_MSEC )) {
316+ instrumentation_begin ();
308317 touch_nmi_watchdog ();
318+ instrumentation_end ();
319+ }
309320 }
310321 return false;
311322}
312323
313- static void load_secondary (unsigned int cpu )
324+ /*
325+ * Protected against instrumentation up to the point where the primary
326+ * thread completed the update. See microcode_nmi_handler() for details.
327+ */
328+ static noinstr bool load_secondary_wait (unsigned int ctrl_cpu )
314329{
315- unsigned int ctrl_cpu = this_cpu_read (ucode_ctrl .ctrl_cpu );
316- enum ucode_state ret ;
317-
318330 /* Initial rendezvous to ensure that all CPUs have arrived */
319331 if (!wait_for_cpus (& late_cpus_in )) {
320- pr_err_once ("load: %d CPUs timed out\n" , atomic_read (& late_cpus_in ) - 1 );
321- this_cpu_write (ucode_ctrl .result , UCODE_TIMEOUT );
322- return ;
332+ raw_cpu_write (ucode_ctrl .result , UCODE_TIMEOUT );
333+ return false;
323334 }
324335
325336 /*
@@ -329,9 +340,33 @@ static void load_secondary(unsigned int cpu)
329340 * scheduler, watchdogs etc. There is no way to safely evacuate the
330341 * machine.
331342 */
332- if (!wait_for_ctrl ())
333- panic ("Microcode load: Primary CPU %d timed out\n" , ctrl_cpu );
343+ if (wait_for_ctrl ())
344+ return true;
345+
346+ instrumentation_begin ();
347+ panic ("Microcode load: Primary CPU %d timed out\n" , ctrl_cpu );
348+ instrumentation_end ();
349+ }
334350
351+ /*
352+ * Protected against instrumentation up to the point where the primary
353+ * thread completed the update. See microcode_nmi_handler() for details.
354+ */
355+ static noinstr void load_secondary (unsigned int cpu )
356+ {
357+ unsigned int ctrl_cpu = raw_cpu_read (ucode_ctrl .ctrl_cpu );
358+ enum ucode_state ret ;
359+
360+ if (!load_secondary_wait (ctrl_cpu )) {
361+ instrumentation_begin ();
362+ pr_err_once ("load: %d CPUs timed out\n" ,
363+ atomic_read (& late_cpus_in ) - 1 );
364+ instrumentation_end ();
365+ return ;
366+ }
367+
368+ /* Primary thread completed. Allow to invoke instrumentable code */
369+ instrumentation_begin ();
335370 /*
336371 * If the primary succeeded then invoke the apply() callback,
337372 * otherwise copy the state from the primary thread.
@@ -343,6 +378,7 @@ static void load_secondary(unsigned int cpu)
343378
344379 this_cpu_write (ucode_ctrl .result , ret );
345380 this_cpu_write (ucode_ctrl .ctrl , SCTRL_DONE );
381+ instrumentation_end ();
346382}
347383
348384static void load_primary (unsigned int cpu )
@@ -380,25 +416,43 @@ static void load_primary(unsigned int cpu)
380416 }
381417}
382418
383- static bool microcode_update_handler (void )
419+ static noinstr bool microcode_update_handler (void )
384420{
385- unsigned int cpu = smp_processor_id ();
421+ unsigned int cpu = raw_smp_processor_id ();
386422
387- if (this_cpu_read (ucode_ctrl .ctrl_cpu ) == cpu )
423+ if (raw_cpu_read (ucode_ctrl .ctrl_cpu ) == cpu ) {
424+ instrumentation_begin ();
388425 load_primary (cpu );
389- else
426+ instrumentation_end ();
427+ } else {
390428 load_secondary (cpu );
429+ }
391430
431+ instrumentation_begin ();
392432 touch_nmi_watchdog ();
433+ instrumentation_end ();
434+
393435 return true;
394436}
395437
396- bool microcode_nmi_handler (void )
438+ /*
439+ * Protection against instrumentation is required for CPUs which are not
440+ * safe against an NMI which is delivered to the secondary SMT sibling
441+ * while the primary thread updates the microcode. Instrumentation can end
442+ * up in #INT3, #DB and #PF. The IRET from those exceptions reenables NMI
443+ * which is the opposite of what the NMI rendezvous is trying to achieve.
444+ *
445+ * The primary thread is safe versus instrumentation as the actual
446+ * microcode update handles this correctly. It's only the sibling code
447+ * path which must be NMI safe until the primary thread completed the
448+ * update.
449+ */
450+ bool noinstr microcode_nmi_handler (void )
397451{
398- if (!this_cpu_read (ucode_ctrl .nmi_enabled ))
452+ if (!raw_cpu_read (ucode_ctrl .nmi_enabled ))
399453 return false;
400454
401- this_cpu_write (ucode_ctrl .nmi_enabled , false);
455+ raw_cpu_write (ucode_ctrl .nmi_enabled , false);
402456 return microcode_update_handler ();
403457}
404458
@@ -425,6 +479,7 @@ static int load_late_stop_cpus(void)
425479 pr_err ("You should switch to early loading, if possible.\n" );
426480
427481 atomic_set (& late_cpus_in , num_online_cpus ());
482+ loops_per_usec = loops_per_jiffy / (TICK_NSEC / 1000 );
428483
429484 /*
430485 * Take a snapshot before the microcode update in order to compare and
0 commit comments