x86/speculation: Split out TIF update
authorThomas Gleixner <tglx@linutronix.de>
Sun, 25 Nov 2018 18:33:51 +0000 (19:33 +0100)
committerThomas Gleixner <tglx@linutronix.de>
Wed, 28 Nov 2018 10:57:12 +0000 (11:57 +0100)
The update of the TIF_SSBD flag and the conditional speculation control MSR
update is done in the ssb_prctl_set() function directly. The upcoming prctl
support for controlling indirect branch speculation via STIBP needs the
same mechanism.

Split the code out and make it reusable. Reword the comment about updates
for other tasks.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Ingo Molnar <mingo@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Jiri Kosina <jkosina@suse.cz>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: David Woodhouse <dwmw@amazon.co.uk>
Cc: Tim Chen <tim.c.chen@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Casey Schaufler <casey.schaufler@intel.com>
Cc: Asit Mallick <asit.k.mallick@intel.com>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Cc: Jon Masters <jcm@redhat.com>
Cc: Waiman Long <longman9394@gmail.com>
Cc: Greg KH <gregkh@linuxfoundation.org>
Cc: Dave Stewart <david.c.stewart@intel.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: stable@vger.kernel.org
Link: https://lkml.kernel.org/r/20181125185005.652305076@linutronix.de
arch/x86/kernel/cpu/bugs.c

index 7c946a9af947e7f9213e074369a6c8a8dbe1afb5..3b65a53d2c33ef5a46a9880522f45a197b6677e2 100644 (file)
@@ -702,10 +702,29 @@ static void ssb_select_mitigation(void)
 #undef pr_fmt
 #define pr_fmt(fmt)     "Speculation prctl: " fmt
 
-static int ssb_prctl_set(struct task_struct *task, unsigned long ctrl)
+static void task_update_spec_tif(struct task_struct *tsk, int tifbit, bool on)
 {
        bool update;
 
+       if (on)
+               update = !test_and_set_tsk_thread_flag(tsk, tifbit);
+       else
+               update = test_and_clear_tsk_thread_flag(tsk, tifbit);
+
+       /*
+        * Immediately update the speculation control MSRs for the current
+        * task, but for a non-current task delay setting the CPU
+        * mitigation until it is scheduled next.
+        *
+        * This can only happen for SECCOMP mitigation. For PRCTL it's
+        * always the current task.
+        */
+       if (tsk == current && update)
+               speculation_ctrl_update_current();
+}
+
+static int ssb_prctl_set(struct task_struct *task, unsigned long ctrl)
+{
        if (ssb_mode != SPEC_STORE_BYPASS_PRCTL &&
            ssb_mode != SPEC_STORE_BYPASS_SECCOMP)
                return -ENXIO;
@@ -716,28 +735,20 @@ static int ssb_prctl_set(struct task_struct *task, unsigned long ctrl)
                if (task_spec_ssb_force_disable(task))
                        return -EPERM;
                task_clear_spec_ssb_disable(task);
-               update = test_and_clear_tsk_thread_flag(task, TIF_SSBD);
+               task_update_spec_tif(task, TIF_SSBD, false);
                break;
        case PR_SPEC_DISABLE:
                task_set_spec_ssb_disable(task);
-               update = !test_and_set_tsk_thread_flag(task, TIF_SSBD);
+               task_update_spec_tif(task, TIF_SSBD, true);
                break;
        case PR_SPEC_FORCE_DISABLE:
                task_set_spec_ssb_disable(task);
                task_set_spec_ssb_force_disable(task);
-               update = !test_and_set_tsk_thread_flag(task, TIF_SSBD);
+               task_update_spec_tif(task, TIF_SSBD, true);
                break;
        default:
                return -ERANGE;
        }
-
-       /*
-        * If being set on non-current task, delay setting the CPU
-        * mitigation until it is next scheduled.
-        */
-       if (task == current && update)
-               speculation_ctrl_update_current();
-
        return 0;
 }