aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2018-11-25 13:33:51 -0500
committerThomas Gleixner <tglx@linutronix.de>2018-11-28 05:57:12 -0500
commite6da8bb6f9abb2628381904b24163c770e630bac (patch)
tree06a4922c7060624b441d10ec56347ab586faa3ee
parent46f7ecb1e7359f183f5bbd1e08b90e10e52164f9 (diff)
x86/speculation: Split out TIF update
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
-rw-r--r--arch/x86/kernel/cpu/bugs.c35
1 files changed, 23 insertions, 12 deletions
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index 7c946a9af947..3b65a53d2c33 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -702,10 +702,29 @@ static void ssb_select_mitigation(void)
702#undef pr_fmt 702#undef pr_fmt
703#define pr_fmt(fmt) "Speculation prctl: " fmt 703#define pr_fmt(fmt) "Speculation prctl: " fmt
704 704
705static int ssb_prctl_set(struct task_struct *task, unsigned long ctrl) 705static void task_update_spec_tif(struct task_struct *tsk, int tifbit, bool on)
706{ 706{
707 bool update; 707 bool update;
708 708
709 if (on)
710 update = !test_and_set_tsk_thread_flag(tsk, tifbit);
711 else
712 update = test_and_clear_tsk_thread_flag(tsk, tifbit);
713
714 /*
715 * Immediately update the speculation control MSRs for the current
716 * task, but for a non-current task delay setting the CPU
717 * mitigation until it is scheduled next.
718 *
719 * This can only happen for SECCOMP mitigation. For PRCTL it's
720 * always the current task.
721 */
722 if (tsk == current && update)
723 speculation_ctrl_update_current();
724}
725
726static int ssb_prctl_set(struct task_struct *task, unsigned long ctrl)
727{
709 if (ssb_mode != SPEC_STORE_BYPASS_PRCTL && 728 if (ssb_mode != SPEC_STORE_BYPASS_PRCTL &&
710 ssb_mode != SPEC_STORE_BYPASS_SECCOMP) 729 ssb_mode != SPEC_STORE_BYPASS_SECCOMP)
711 return -ENXIO; 730 return -ENXIO;
@@ -716,28 +735,20 @@ static int ssb_prctl_set(struct task_struct *task, unsigned long ctrl)
716 if (task_spec_ssb_force_disable(task)) 735 if (task_spec_ssb_force_disable(task))
717 return -EPERM; 736 return -EPERM;
718 task_clear_spec_ssb_disable(task); 737 task_clear_spec_ssb_disable(task);
719 update = test_and_clear_tsk_thread_flag(task, TIF_SSBD); 738 task_update_spec_tif(task, TIF_SSBD, false);
720 break; 739 break;
721 case PR_SPEC_DISABLE: 740 case PR_SPEC_DISABLE:
722 task_set_spec_ssb_disable(task); 741 task_set_spec_ssb_disable(task);
723 update = !test_and_set_tsk_thread_flag(task, TIF_SSBD); 742 task_update_spec_tif(task, TIF_SSBD, true);
724 break; 743 break;
725 case PR_SPEC_FORCE_DISABLE: 744 case PR_SPEC_FORCE_DISABLE:
726 task_set_spec_ssb_disable(task); 745 task_set_spec_ssb_disable(task);
727 task_set_spec_ssb_force_disable(task); 746 task_set_spec_ssb_force_disable(task);
728 update = !test_and_set_tsk_thread_flag(task, TIF_SSBD); 747 task_update_spec_tif(task, TIF_SSBD, true);
729 break; 748 break;
730 default: 749 default:
731 return -ERANGE; 750 return -ERANGE;
732 } 751 }
733
734 /*
735 * If being set on non-current task, delay setting the CPU
736 * mitigation until it is next scheduled.
737 */
738 if (task == current && update)
739 speculation_ctrl_update_current();
740
741 return 0; 752 return 0;
742} 753}
743 754