@@ -1180,13 +1180,14 @@ static noinstr bool mce_check_crashing_cpu(void)
1180
1180
return false;
1181
1181
}
1182
1182
1183
- static void __mc_scan_banks (struct mce * m , struct pt_regs * regs , struct mce * final ,
1184
- unsigned long * toclear , unsigned long * valid_banks ,
1185
- int no_way_out , int * worst )
1183
+ static __always_inline int
1184
+ __mc_scan_banks (struct mce * m , struct pt_regs * regs , struct mce * final ,
1185
+ unsigned long * toclear , unsigned long * valid_banks , int no_way_out ,
1186
+ int * worst )
1186
1187
{
1187
1188
struct mce_bank * mce_banks = this_cpu_ptr (mce_banks_array );
1188
1189
struct mca_config * cfg = & mca_cfg ;
1189
- int severity , i ;
1190
+ int severity , i , taint = 0 ;
1190
1191
1191
1192
for (i = 0 ; i < this_cpu_read (mce_num_banks ); i ++ ) {
1192
1193
__clear_bit (i , toclear );
@@ -1213,7 +1214,7 @@ static void __mc_scan_banks(struct mce *m, struct pt_regs *regs, struct mce *fin
1213
1214
continue ;
1214
1215
1215
1216
/* Set taint even when machine check was not enabled. */
1216
- add_taint ( TAINT_MACHINE_CHECK , LOCKDEP_NOW_UNRELIABLE ) ;
1217
+ taint ++ ;
1217
1218
1218
1219
severity = mce_severity (m , regs , cfg -> tolerant , NULL , true);
1219
1220
@@ -1236,7 +1237,13 @@ static void __mc_scan_banks(struct mce *m, struct pt_regs *regs, struct mce *fin
1236
1237
/* assuming valid severity level != 0 */
1237
1238
m -> severity = severity ;
1238
1239
1240
+ /*
1241
+ * Enable instrumentation around the mce_log() call which is
1242
+ * done in #MC context, where instrumentation is disabled.
1243
+ */
1244
+ instrumentation_begin ();
1239
1245
mce_log (m );
1246
+ instrumentation_end ();
1240
1247
1241
1248
if (severity > * worst ) {
1242
1249
* final = * m ;
@@ -1246,6 +1253,8 @@ static void __mc_scan_banks(struct mce *m, struct pt_regs *regs, struct mce *fin
1246
1253
1247
1254
/* mce_clear_state will clear *final, save locally for use later */
1248
1255
* m = * final ;
1256
+
1257
+ return taint ;
1249
1258
}
1250
1259
1251
1260
static void kill_me_now (struct callback_head * ch )
@@ -1362,7 +1371,7 @@ static noinstr void unexpected_machine_check(struct pt_regs *regs)
1362
1371
*/
1363
1372
noinstr void do_machine_check (struct pt_regs * regs )
1364
1373
{
1365
- int worst = 0 , order , no_way_out , kill_current_task , lmce ;
1374
+ int worst = 0 , order , no_way_out , kill_current_task , lmce , taint = 0 ;
1366
1375
DECLARE_BITMAP (valid_banks , MAX_NR_BANKS ) = { 0 };
1367
1376
DECLARE_BITMAP (toclear , MAX_NR_BANKS ) = { 0 };
1368
1377
struct mca_config * cfg = & mca_cfg ;
@@ -1441,7 +1450,7 @@ noinstr void do_machine_check(struct pt_regs *regs)
1441
1450
order = mce_start (& no_way_out );
1442
1451
}
1443
1452
1444
- __mc_scan_banks (& m , regs , final , toclear , valid_banks , no_way_out , & worst );
1453
+ taint = __mc_scan_banks (& m , regs , final , toclear , valid_banks , no_way_out , & worst );
1445
1454
1446
1455
if (!no_way_out )
1447
1456
mce_clear_state (toclear );
@@ -1473,17 +1482,19 @@ noinstr void do_machine_check(struct pt_regs *regs)
1473
1482
}
1474
1483
}
1475
1484
1476
- if (worst != MCE_AR_SEVERITY && !kill_current_task )
1477
- goto out ;
1478
-
1479
1485
/*
1480
- * Enable instrumentation around the external facilities like
1481
- * task_work_add() (via queue_task_work()), fixup_exception() etc.
1482
- * For now, that is. Fixing this properly would need a lot more involved
1483
- * reorganization.
1486
+ * Enable instrumentation around the external facilities like task_work_add()
1487
+ * (via queue_task_work()), fixup_exception() etc. For now, that is. Fixing this
1488
+ * properly would need a lot more involved reorganization.
1484
1489
*/
1485
1490
instrumentation_begin ();
1486
1491
1492
+ if (taint )
1493
+ add_taint (TAINT_MACHINE_CHECK , LOCKDEP_NOW_UNRELIABLE );
1494
+
1495
+ if (worst != MCE_AR_SEVERITY && !kill_current_task )
1496
+ goto out ;
1497
+
1487
1498
/* Fault was in user mode and we need to take some action */
1488
1499
if ((m .cs & 3 ) == 3 ) {
1489
1500
/* If this triggers there is no way to recover. Die hard. */
@@ -1513,9 +1524,9 @@ noinstr void do_machine_check(struct pt_regs *regs)
1513
1524
queue_task_work (& m , msg , kill_me_never );
1514
1525
}
1515
1526
1527
+ out :
1516
1528
instrumentation_end ();
1517
1529
1518
- out :
1519
1530
mce_wrmsrl (MSR_IA32_MCG_STATUS , 0 );
1520
1531
}
1521
1532
EXPORT_SYMBOL_GPL (do_machine_check );
0 commit comments