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 <sbl...@amazon.com>
AuthorDate:    Sat, 16 May 2020 20:34:29 +10:00
Committer:     Thomas Gleixner <t...@linutronix.de>
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 <t...@linutronix.de>
Signed-off-by: Balbir Singh <sbl...@amazon.com>
Signed-off-by: Thomas Gleixner <t...@linutronix.de>
Link: https://lkml.kernel.org/r/20200516103430.26527-3-sbl...@amazon.com

---
 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)

Reply via email to