@@ -92,6 +92,8 @@ static void __init bhi_select_mitigation(void);
92
92
static void __init bhi_update_mitigation (void );
93
93
static void __init bhi_apply_mitigation (void );
94
94
static void __init its_select_mitigation (void );
95
+ static void __init its_update_mitigation (void );
96
+ static void __init its_apply_mitigation (void );
95
97
96
98
/* The base value of the SPEC_CTRL MSR without task-specific bits set */
97
99
u64 x86_spec_ctrl_base ;
@@ -235,6 +237,11 @@ void __init cpu_select_mitigations(void)
235
237
* spectre_v2=ibrs.
236
238
*/
237
239
retbleed_update_mitigation ();
240
+ /*
241
+ * its_update_mitigation() depends on spectre_v2_update_mitigation()
242
+ * and retbleed_update_mitigation().
243
+ */
244
+ its_update_mitigation ();
238
245
239
246
/*
240
247
* spectre_v2_user_update_mitigation() depends on
@@ -263,6 +270,7 @@ void __init cpu_select_mitigations(void)
263
270
srbds_apply_mitigation ();
264
271
srso_apply_mitigation ();
265
272
gds_apply_mitigation ();
273
+ its_apply_mitigation ();
266
274
bhi_apply_mitigation ();
267
275
}
268
276
@@ -1115,6 +1123,17 @@ enum spectre_v2_mitigation spectre_v2_enabled __ro_after_init = SPECTRE_V2_NONE;
1115
1123
#undef pr_fmt
1116
1124
#define pr_fmt (fmt ) "RETBleed: " fmt
1117
1125
1126
+ enum its_mitigation {
1127
+ ITS_MITIGATION_OFF ,
1128
+ ITS_MITIGATION_AUTO ,
1129
+ ITS_MITIGATION_VMEXIT_ONLY ,
1130
+ ITS_MITIGATION_ALIGNED_THUNKS ,
1131
+ ITS_MITIGATION_RETPOLINE_STUFF ,
1132
+ };
1133
+
1134
+ static enum its_mitigation its_mitigation __ro_after_init =
1135
+ IS_ENABLED (CONFIG_MITIGATION_ITS ) ? ITS_MITIGATION_AUTO : ITS_MITIGATION_OFF ;
1136
+
1118
1137
enum retbleed_mitigation {
1119
1138
RETBLEED_MITIGATION_NONE ,
1120
1139
RETBLEED_MITIGATION_AUTO ,
@@ -1242,11 +1261,19 @@ static void __init retbleed_update_mitigation(void)
1242
1261
/*
1243
1262
* retbleed=stuff is only allowed on Intel. If stuffing can't be used
1244
1263
* then a different mitigation will be selected below.
1264
+ *
1265
+ * its=stuff will also attempt to enable stuffing.
1245
1266
*/
1246
- if (retbleed_mitigation == RETBLEED_MITIGATION_STUFF ) {
1267
+ if (retbleed_mitigation == RETBLEED_MITIGATION_STUFF ||
1268
+ its_mitigation == ITS_MITIGATION_RETPOLINE_STUFF ) {
1247
1269
if (spectre_v2_enabled != SPECTRE_V2_RETPOLINE ) {
1248
1270
pr_err ("WARNING: retbleed=stuff depends on spectre_v2=retpoline\n" );
1249
1271
retbleed_mitigation = RETBLEED_MITIGATION_AUTO ;
1272
+ } else {
1273
+ if (retbleed_mitigation != RETBLEED_MITIGATION_STUFF )
1274
+ pr_info ("Retbleed mitigation updated to stuffing\n" );
1275
+
1276
+ retbleed_mitigation = RETBLEED_MITIGATION_STUFF ;
1250
1277
}
1251
1278
}
1252
1279
/*
@@ -1338,32 +1365,13 @@ static void __init retbleed_apply_mitigation(void)
1338
1365
#undef pr_fmt
1339
1366
#define pr_fmt (fmt ) "ITS: " fmt
1340
1367
1341
- enum its_mitigation_cmd {
1342
- ITS_CMD_OFF ,
1343
- ITS_CMD_ON ,
1344
- ITS_CMD_VMEXIT ,
1345
- ITS_CMD_RSB_STUFF ,
1346
- };
1347
-
1348
- enum its_mitigation {
1349
- ITS_MITIGATION_OFF ,
1350
- ITS_MITIGATION_VMEXIT_ONLY ,
1351
- ITS_MITIGATION_ALIGNED_THUNKS ,
1352
- ITS_MITIGATION_RETPOLINE_STUFF ,
1353
- };
1354
-
1355
1368
static const char * const its_strings [] = {
1356
1369
[ITS_MITIGATION_OFF ] = "Vulnerable" ,
1357
1370
[ITS_MITIGATION_VMEXIT_ONLY ] = "Mitigation: Vulnerable, KVM: Not affected" ,
1358
1371
[ITS_MITIGATION_ALIGNED_THUNKS ] = "Mitigation: Aligned branch/return thunks" ,
1359
1372
[ITS_MITIGATION_RETPOLINE_STUFF ] = "Mitigation: Retpolines, Stuffing RSB" ,
1360
1373
};
1361
1374
1362
- static enum its_mitigation its_mitigation __ro_after_init = ITS_MITIGATION_ALIGNED_THUNKS ;
1363
-
1364
- static enum its_mitigation_cmd its_cmd __ro_after_init =
1365
- IS_ENABLED (CONFIG_MITIGATION_ITS ) ? ITS_CMD_ON : ITS_CMD_OFF ;
1366
-
1367
1375
static int __init its_parse_cmdline (char * str )
1368
1376
{
1369
1377
if (!str )
@@ -1375,16 +1383,16 @@ static int __init its_parse_cmdline(char *str)
1375
1383
}
1376
1384
1377
1385
if (!strcmp (str , "off" )) {
1378
- its_cmd = ITS_CMD_OFF ;
1386
+ its_mitigation = ITS_MITIGATION_OFF ;
1379
1387
} else if (!strcmp (str , "on" )) {
1380
- its_cmd = ITS_CMD_ON ;
1388
+ its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS ;
1381
1389
} else if (!strcmp (str , "force" )) {
1382
- its_cmd = ITS_CMD_ON ;
1390
+ its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS ;
1383
1391
setup_force_cpu_bug (X86_BUG_ITS );
1384
1392
} else if (!strcmp (str , "vmexit" )) {
1385
- its_cmd = ITS_CMD_VMEXIT ;
1393
+ its_mitigation = ITS_MITIGATION_VMEXIT_ONLY ;
1386
1394
} else if (!strcmp (str , "stuff" )) {
1387
- its_cmd = ITS_CMD_RSB_STUFF ;
1395
+ its_mitigation = ITS_MITIGATION_RETPOLINE_STUFF ;
1388
1396
} else {
1389
1397
pr_err ("Ignoring unknown indirect_target_selection option (%s)." , str );
1390
1398
}
@@ -1395,85 +1403,90 @@ early_param("indirect_target_selection", its_parse_cmdline);
1395
1403
1396
1404
static void __init its_select_mitigation (void )
1397
1405
{
1398
- enum its_mitigation_cmd cmd = its_cmd ;
1399
-
1400
1406
if (!boot_cpu_has_bug (X86_BUG_ITS ) || cpu_mitigations_off ()) {
1401
1407
its_mitigation = ITS_MITIGATION_OFF ;
1402
1408
return ;
1403
1409
}
1404
1410
1405
- /* Retpoline+CDT mitigates ITS, bail out */
1406
- if (boot_cpu_has (X86_FEATURE_RETPOLINE ) &&
1407
- boot_cpu_has (X86_FEATURE_CALL_DEPTH )) {
1408
- its_mitigation = ITS_MITIGATION_RETPOLINE_STUFF ;
1409
- goto out ;
1410
- }
1411
+ if (its_mitigation == ITS_MITIGATION_AUTO )
1412
+ its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS ;
1413
+
1414
+ if (its_mitigation == ITS_MITIGATION_OFF )
1415
+ return ;
1411
1416
1412
- /* Exit early to avoid irrelevant warnings */
1413
- if (cmd == ITS_CMD_OFF ) {
1414
- its_mitigation = ITS_MITIGATION_OFF ;
1415
- goto out ;
1416
- }
1417
- if (spectre_v2_enabled == SPECTRE_V2_NONE ) {
1418
- pr_err ("WARNING: Spectre-v2 mitigation is off, disabling ITS\n" );
1419
- its_mitigation = ITS_MITIGATION_OFF ;
1420
- goto out ;
1421
- }
1422
1417
if (!IS_ENABLED (CONFIG_MITIGATION_RETPOLINE ) ||
1423
1418
!IS_ENABLED (CONFIG_MITIGATION_RETHUNK )) {
1424
1419
pr_err ("WARNING: ITS mitigation depends on retpoline and rethunk support\n" );
1425
1420
its_mitigation = ITS_MITIGATION_OFF ;
1426
- goto out ;
1421
+ return ;
1427
1422
}
1423
+
1428
1424
if (IS_ENABLED (CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B )) {
1429
1425
pr_err ("WARNING: ITS mitigation is not compatible with CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B\n" );
1430
1426
its_mitigation = ITS_MITIGATION_OFF ;
1431
- goto out ;
1432
- }
1433
- if (boot_cpu_has (X86_FEATURE_RETPOLINE_LFENCE )) {
1434
- pr_err ("WARNING: ITS mitigation is not compatible with lfence mitigation\n" );
1435
- its_mitigation = ITS_MITIGATION_OFF ;
1436
- goto out ;
1427
+ return ;
1437
1428
}
1438
1429
1439
- if (cmd == ITS_CMD_RSB_STUFF &&
1440
- (! boot_cpu_has ( X86_FEATURE_RETPOLINE ) || ! IS_ENABLED (CONFIG_MITIGATION_CALL_DEPTH_TRACKING ) )) {
1430
+ if (its_mitigation == ITS_MITIGATION_RETPOLINE_STUFF &&
1431
+ ! IS_ENABLED (CONFIG_MITIGATION_CALL_DEPTH_TRACKING )) {
1441
1432
pr_err ("RSB stuff mitigation not supported, using default\n" );
1442
- cmd = ITS_CMD_ON ;
1433
+ its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS ;
1443
1434
}
1444
1435
1445
- switch (cmd ) {
1446
- case ITS_CMD_OFF :
1436
+ if (its_mitigation == ITS_MITIGATION_VMEXIT_ONLY &&
1437
+ !boot_cpu_has_bug (X86_BUG_ITS_NATIVE_ONLY ))
1438
+ its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS ;
1439
+ }
1440
+
1441
+ static void __init its_update_mitigation (void )
1442
+ {
1443
+ if (!boot_cpu_has_bug (X86_BUG_ITS ) || cpu_mitigations_off ())
1444
+ return ;
1445
+
1446
+ switch (spectre_v2_enabled ) {
1447
+ case SPECTRE_V2_NONE :
1448
+ pr_err ("WARNING: Spectre-v2 mitigation is off, disabling ITS\n" );
1447
1449
its_mitigation = ITS_MITIGATION_OFF ;
1448
1450
break ;
1449
- case ITS_CMD_VMEXIT :
1450
- if (boot_cpu_has_bug (X86_BUG_ITS_NATIVE_ONLY )) {
1451
- its_mitigation = ITS_MITIGATION_VMEXIT_ONLY ;
1452
- goto out ;
1453
- }
1454
- fallthrough ;
1455
- case ITS_CMD_ON :
1456
- its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS ;
1457
- if (!boot_cpu_has (X86_FEATURE_RETPOLINE ))
1458
- setup_force_cpu_cap (X86_FEATURE_INDIRECT_THUNK_ITS );
1459
- setup_force_cpu_cap (X86_FEATURE_RETHUNK );
1460
- set_return_thunk (its_return_thunk );
1451
+ case SPECTRE_V2_RETPOLINE :
1452
+ /* Retpoline+CDT mitigates ITS */
1453
+ if (retbleed_mitigation == RETBLEED_MITIGATION_STUFF )
1454
+ its_mitigation = ITS_MITIGATION_RETPOLINE_STUFF ;
1461
1455
break ;
1462
- case ITS_CMD_RSB_STUFF :
1463
- its_mitigation = ITS_MITIGATION_RETPOLINE_STUFF ;
1464
- setup_force_cpu_cap (X86_FEATURE_RETHUNK );
1465
- setup_force_cpu_cap (X86_FEATURE_CALL_DEPTH );
1466
- set_return_thunk (call_depth_return_thunk );
1467
- if (retbleed_mitigation == RETBLEED_MITIGATION_NONE ) {
1468
- retbleed_mitigation = RETBLEED_MITIGATION_STUFF ;
1469
- pr_info ("Retbleed mitigation updated to stuffing\n" );
1470
- }
1456
+ case SPECTRE_V2_LFENCE :
1457
+ case SPECTRE_V2_EIBRS_LFENCE :
1458
+ pr_err ("WARNING: ITS mitigation is not compatible with lfence mitigation\n" );
1459
+ its_mitigation = ITS_MITIGATION_OFF ;
1460
+ break ;
1461
+ default :
1471
1462
break ;
1472
1463
}
1473
- out :
1464
+
1465
+ /*
1466
+ * retbleed_update_mitigation() will try to do stuffing if its=stuff.
1467
+ * If it can't, such as if spectre_v2!=retpoline, then fall back to
1468
+ * aligned thunks.
1469
+ */
1470
+ if (its_mitigation == ITS_MITIGATION_RETPOLINE_STUFF &&
1471
+ retbleed_mitigation != RETBLEED_MITIGATION_STUFF )
1472
+ its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS ;
1473
+
1474
1474
pr_info ("%s\n" , its_strings [its_mitigation ]);
1475
1475
}
1476
1476
1477
+ static void __init its_apply_mitigation (void )
1478
+ {
1479
+ /* its=stuff forces retbleed stuffing and is enabled there. */
1480
+ if (its_mitigation != ITS_MITIGATION_ALIGNED_THUNKS )
1481
+ return ;
1482
+
1483
+ if (!boot_cpu_has (X86_FEATURE_RETPOLINE ))
1484
+ setup_force_cpu_cap (X86_FEATURE_INDIRECT_THUNK_ITS );
1485
+
1486
+ setup_force_cpu_cap (X86_FEATURE_RETHUNK );
1487
+ set_return_thunk (its_return_thunk );
1488
+ }
1489
+
1477
1490
#undef pr_fmt
1478
1491
#define pr_fmt (fmt ) "Spectre V2 : " fmt
1479
1492
0 commit comments