History

x86, prctl: Hook L1D flushing in via prctl

Use the existing PR_GET/SET_SPECULATION_CTRL API to expose the L1D flush capability. For L1D flushing PR_SPEC_FORCE_DISABLE and PR_SPEC_DISABLE_NOEXEC are not supported. Enabling L1D flush does not check if the task is running on an SMT enabled core, rather a check is done at runtime (at the time of flush), if the task runs on a SMT sibling then the task is sent a SIGBUS which is executed before the task returns to user space or to a guest. This is better than the other alternatives of: a. Ensuring strict affinity of the task (hard to enforce without further changes in the scheduler) b. Silently skipping flush for tasks that move to SMT enabled cores. Hook up the core prctl and implement the x86 specific parts which in turn makes it functional.

Balbir Singh committed 5 years ago

Commit e893bb11 parent b5f06f62 files · +34 −0Browse files

Unified · Split

2 files
  1. arch/x86/kernel/cpu/bugs.c +33 −0
  2. include/uapi/linux/prctl.h +1 −0
arch/x86/kernel/cpu/bugs.c+33−0
@@ -1252,6 +1252,24 @@ static void task_update_spec_tif(struct task_struct *tsk) · 1251 unmodified lines
1252 speculation_ctrl_update_current();1252 speculation_ctrl_update_current();
1253}1253}
1254 1254
1255static int l1d_flush_prctl_set(struct task_struct *task, unsigned long ctrl)
1256{
1257
1258 if (!static_branch_unlikely(&switch_mm_cond_l1d_flush))
1259 return -EPERM;
1260
1261 switch (ctrl) {
1262 case PR_SPEC_ENABLE:
1263 set_ti_thread_flag(&task->thread_info, TIF_SPEC_L1D_FLUSH);
1264 return 0;
1265 case PR_SPEC_DISABLE:
1266 clear_ti_thread_flag(&task->thread_info, TIF_SPEC_L1D_FLUSH);
1267 return 0;
1268 default:
1269 return -ERANGE;
1270 }
1271}
1272
1255static int ssb_prctl_set(struct task_struct *task, unsigned long ctrl)1273static int ssb_prctl_set(struct task_struct *task, unsigned long ctrl)
1256{1274{
1257 if (ssb_mode != SPEC_STORE_BYPASS_PRCTL &&1275 if (ssb_mode != SPEC_STORE_BYPASS_PRCTL &&
@@ -1361,6 +1379,8 @@ int arch_prctl_spec_ctrl_set(struct task_struct *task, unsigned long which, · 103 unmodified lines
1361 return ssb_prctl_set(task, ctrl);1379 return ssb_prctl_set(task, ctrl);
1362 case PR_SPEC_INDIRECT_BRANCH:1380 case PR_SPEC_INDIRECT_BRANCH:
1363 return ib_prctl_set(task, ctrl);1381 return ib_prctl_set(task, ctrl);
1382 case PR_SPEC_L1D_FLUSH:
1383 return l1d_flush_prctl_set(task, ctrl);
1364 default:1384 default:
1365 return -ENODEV;1385 return -ENODEV;
1366 }1386 }
@@ -1377,6 +1397,17 @@ void arch_seccomp_spec_mitigate(struct task_struct *task) · 10 unmodified lines
1377}1397}
1378#endif1398#endif
1379 1399
1400static int l1d_flush_prctl_get(struct task_struct *task)
1401{
1402 if (!static_branch_unlikely(&switch_mm_cond_l1d_flush))
1403 return PR_SPEC_FORCE_DISABLE;
1404
1405 if (test_ti_thread_flag(&task->thread_info, TIF_SPEC_L1D_FLUSH))
1406 return PR_SPEC_PRCTL | PR_SPEC_ENABLE;
1407 else
1408 return PR_SPEC_PRCTL | PR_SPEC_DISABLE;
1409}
1410
1380static int ssb_prctl_get(struct task_struct *task)1411static int ssb_prctl_get(struct task_struct *task)
1381{1412{
1382 switch (ssb_mode) {1413 switch (ssb_mode) {
@@ -1427,6 +1458,8 @@ int arch_prctl_spec_ctrl_get(struct task_struct *task, unsigned long which) · 44 unmodified lines
1427 return ssb_prctl_get(task);1458 return ssb_prctl_get(task);
1428 case PR_SPEC_INDIRECT_BRANCH:1459 case PR_SPEC_INDIRECT_BRANCH:
1429 return ib_prctl_get(task);1460 return ib_prctl_get(task);
1461 case PR_SPEC_L1D_FLUSH:
1462 return l1d_flush_prctl_get(task);
1430 default:1463 default:
1431 return -ENODEV;1464 return -ENODEV;
1432 }1465 }
include/uapi/linux/prctl.h+1−0
@@ -213,6 +213,7 @@ struct prctl_mm_map { · 212 unmodified lines
213/* Speculation control variants */213/* Speculation control variants */
214# define PR_SPEC_STORE_BYPASS 0214# define PR_SPEC_STORE_BYPASS 0
215# define PR_SPEC_INDIRECT_BRANCH 1215# define PR_SPEC_INDIRECT_BRANCH 1
216# define PR_SPEC_L1D_FLUSH 2
216/* Return and control values for PR_SET/GET_SPECULATION_CTRL */217/* Return and control values for PR_SET/GET_SPECULATION_CTRL */
217# define PR_SPEC_NOT_AFFECTED 0218# define PR_SPEC_NOT_AFFECTED 0
218# define PR_SPEC_PRCTL (1UL << 0)219# define PR_SPEC_PRCTL (1UL << 0)