The following commit has been merged into the x86/mm branch of tip: Commit-ID: edf7ce0b231cb6cdc170125588cf71c70358fc74 Gitweb: https://git.kernel.org/tip/edf7ce0b231cb6cdc170125588cf71c70358fc74 Author: Balbir Singh <sblbir@xxxxxxxxxx> AuthorDate: Sat, 16 May 2020 20:34:29 +10:00 Committer: Thomas Gleixner <tglx@xxxxxxxxxxxxx> CommitterDate: Fri, 22 May 2020 10:36:48 +02:00 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. There is also no seccomp integration for the feature. Suggested-by: Thomas Gleixner <tglx@xxxxxxxxxxxxx> Signed-off-by: Balbir Singh <sblbir@xxxxxxxxxx> Signed-off-by: Thomas Gleixner <tglx@xxxxxxxxxxxxx> Link: https://lkml.kernel.org/r/20200516103430.26527-3-sblbir@xxxxxxxxxx --- arch/x86/kernel/cpu/bugs.c | 28 ++++++++++++++++++++++++++++ include/uapi/linux/prctl.h | 1 + 2 files changed, 29 insertions(+) diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index ed54b3b..3eb9139 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -1121,6 +1121,19 @@ static void task_update_spec_tif(struct task_struct *tsk) speculation_ctrl_update_current(); } +static int l1d_flush_out_prctl_set(struct task_struct *task, unsigned long ctrl) +{ + switch (ctrl) { + case PR_SPEC_ENABLE: + return enable_l1d_flush_for_task(task); + case PR_SPEC_DISABLE: + return disable_l1d_flush_for_task(task); + default: + return -ERANGE; + } + return 0; +} + static int ssb_prctl_set(struct task_struct *task, unsigned long ctrl) { if (ssb_mode != SPEC_STORE_BYPASS_PRCTL && @@ -1206,6 +1219,8 @@ int arch_prctl_spec_ctrl_set(struct task_struct *task, unsigned long which, return ssb_prctl_set(task, ctrl); case PR_SPEC_INDIRECT_BRANCH: return ib_prctl_set(task, ctrl); + case PR_SPEC_L1D_FLUSH_OUT: + return l1d_flush_out_prctl_set(task, ctrl); default: return -ENODEV; } @@ -1221,6 +1236,17 @@ void arch_seccomp_spec_mitigate(struct task_struct *task) } #endif +static int l1d_flush_out_prctl_get(struct task_struct *task) +{ + int ret; + + ret = test_ti_thread_flag(&task->thread_info, TIF_SPEC_L1D_FLUSH); + if (ret) + return PR_SPEC_PRCTL | PR_SPEC_ENABLE; + else + return PR_SPEC_PRCTL | PR_SPEC_DISABLE; +} + static int ssb_prctl_get(struct task_struct *task) { switch (ssb_mode) { @@ -1272,6 +1298,8 @@ int arch_prctl_spec_ctrl_get(struct task_struct *task, unsigned long which) return ssb_prctl_get(task); case PR_SPEC_INDIRECT_BRANCH: return ib_prctl_get(task); + case PR_SPEC_L1D_FLUSH_OUT: + return l1d_flush_out_prctl_get(task); default: return -ENODEV; } diff --git a/include/uapi/linux/prctl.h b/include/uapi/linux/prctl.h index 07b4f81..1e86486 100644 --- a/include/uapi/linux/prctl.h +++ b/include/uapi/linux/prctl.h @@ -213,6 +213,7 @@ struct prctl_mm_map { /* Speculation control variants */ # define PR_SPEC_STORE_BYPASS 0 # define PR_SPEC_INDIRECT_BRANCH 1 +# define PR_SPEC_L1D_FLUSH_OUT 2 /* Return and control values for PR_SET/GET_SPECULATION_CTRL */ # define PR_SPEC_NOT_AFFECTED 0 # define PR_SPEC_PRCTL (1UL << 0)
![]() |