|
@@ -530,31 +530,35 @@ static void ssb_select_mitigation()
|
|
|
|
|
|
#undef pr_fmt
|
|
|
|
|
|
-static int ssb_prctl_set(unsigned long ctrl)
|
|
|
+static int ssb_prctl_set(struct task_struct *task, unsigned long ctrl)
|
|
|
{
|
|
|
- bool rds = !!test_tsk_thread_flag(current, TIF_RDS);
|
|
|
+ bool rds = !!test_tsk_thread_flag(task, TIF_RDS);
|
|
|
|
|
|
if (ssb_mode != SPEC_STORE_BYPASS_PRCTL)
|
|
|
return -ENXIO;
|
|
|
|
|
|
if (ctrl == PR_SPEC_ENABLE)
|
|
|
- clear_tsk_thread_flag(current, TIF_RDS);
|
|
|
+ clear_tsk_thread_flag(task, TIF_RDS);
|
|
|
else
|
|
|
- set_tsk_thread_flag(current, TIF_RDS);
|
|
|
+ set_tsk_thread_flag(task, TIF_RDS);
|
|
|
|
|
|
- if (rds != !!test_tsk_thread_flag(current, TIF_RDS))
|
|
|
+ /*
|
|
|
+ * If being set on non-current task, delay setting the CPU
|
|
|
+ * mitigation until it is next scheduled.
|
|
|
+ */
|
|
|
+ if (task == current && rds != !!test_tsk_thread_flag(task, TIF_RDS))
|
|
|
speculative_store_bypass_update();
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int ssb_prctl_get(void)
|
|
|
+static int ssb_prctl_get(struct task_struct *task)
|
|
|
{
|
|
|
switch (ssb_mode) {
|
|
|
case SPEC_STORE_BYPASS_DISABLE:
|
|
|
return PR_SPEC_DISABLE;
|
|
|
case SPEC_STORE_BYPASS_PRCTL:
|
|
|
- if (test_tsk_thread_flag(current, TIF_RDS))
|
|
|
+ if (test_tsk_thread_flag(task, TIF_RDS))
|
|
|
return PR_SPEC_PRCTL | PR_SPEC_DISABLE;
|
|
|
return PR_SPEC_PRCTL | PR_SPEC_ENABLE;
|
|
|
default:
|
|
@@ -564,24 +568,25 @@ static int ssb_prctl_get(void)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-int arch_prctl_spec_ctrl_set(unsigned long which, unsigned long ctrl)
|
|
|
+int arch_prctl_spec_ctrl_set(struct task_struct *task, unsigned long which,
|
|
|
+ unsigned long ctrl)
|
|
|
{
|
|
|
if (ctrl != PR_SPEC_ENABLE && ctrl != PR_SPEC_DISABLE)
|
|
|
return -ERANGE;
|
|
|
|
|
|
switch (which) {
|
|
|
case PR_SPEC_STORE_BYPASS:
|
|
|
- return ssb_prctl_set(ctrl);
|
|
|
+ return ssb_prctl_set(task, ctrl);
|
|
|
default:
|
|
|
return -ENODEV;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-int arch_prctl_spec_ctrl_get(unsigned long which)
|
|
|
+int arch_prctl_spec_ctrl_get(struct task_struct *task, unsigned long which)
|
|
|
{
|
|
|
switch (which) {
|
|
|
case PR_SPEC_STORE_BYPASS:
|
|
|
- return ssb_prctl_get();
|
|
|
+ return ssb_prctl_get(task);
|
|
|
default:
|
|
|
return -ENODEV;
|
|
|
}
|