linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Tim Chen <tim.c.chen@linux.intel.com>
To: Thomas Gleixner <tglx@linutronix.de>,
	Andy Lutomirski <luto@kernel.org>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Greg KH <gregkh@linuxfoundation.org>
Cc: Tim Chen <tim.c.chen@linux.intel.com>,
	Dave Hansen <dave.hansen@intel.com>,
	Andrea Arcangeli <aarcange@redhat.com>,
	Andi Kleen <ak@linux.intel.com>,
	Arjan Van De Ven <arjan.van.de.ven@intel.com>,
	David Woodhouse <dwmw@amazon.co.uk>,
	Peter Zijlstra <peterz@infradead.org>,
	Dan Williams <dan.j.williams@intel.com>,
	Paolo Bonzini <pbonzini@redhat.com>,
	Ashok Raj <ashok.raj@intel.com>,
	linux-kernel@vger.kernel.org
Subject: [PATCH v3 5/5] x86/idle: Disable IBRS entering idle and enable it on wakeup
Date: Tue,  9 Jan 2018 18:26:49 -0800	[thread overview]
Message-ID: <4a460698535c0d5bb939db076fc952270033ac8d.1515542293.git.tim.c.chen@linux.intel.com> (raw)
In-Reply-To: <cover.1515542293.git.tim.c.chen@linux.intel.com>
In-Reply-To: <cover.1515542293.git.tim.c.chen@linux.intel.com>

Clear IBRS on idle entry and set it on idle exit into kernel on mwait.
When we are in mwait, we are not running but if we leave IBRS on,
it will affect the performance on the sibling hardware thread.  So
we disable IBRS and reenable it when we wake up.

Thanks to Peter Zijlstra and Andrea Arcangeli's suggestion of using
static key to improve IBRS toggling.

Signed-off-by: Tim Chen <tim.c.chen@linux.intel.com>
---
 arch/x86/include/asm/mwait.h    | 13 +++++++++++++
 arch/x86/kernel/cpu/spec_ctrl.c | 27 ++++++++++++++++++++++++++-
 arch/x86/kernel/process.c       |  9 +++++++--
 3 files changed, 46 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/mwait.h b/arch/x86/include/asm/mwait.h
index 39a2fb2..870299a 100644
--- a/arch/x86/include/asm/mwait.h
+++ b/arch/x86/include/asm/mwait.h
@@ -6,6 +6,7 @@
 #include <linux/sched/idle.h>
 
 #include <asm/cpufeature.h>
+#include <asm/spec_ctrl.h>
 
 #define MWAIT_SUBSTATE_MASK		0xf
 #define MWAIT_CSTATE_MASK		0xf
@@ -106,9 +107,21 @@ static inline void mwait_idle_with_hints(unsigned long eax, unsigned long ecx)
 			mb();
 		}
 
+	       /*
+		* CPUs run faster with speculation protection
+		* disabled.  All CPU threads in a core must
+		* disable speculation protection for it to be
+		* disabled.  Disable it while we are idle so the
+		* other hyperthread can run fast.
+		*
+		* Interrupts have been disabled at this point.
+		*/
+
+		spec_ctrl_unprotected_begin();
 		__monitor((void *)&current_thread_info()->flags, 0, 0);
 		if (!need_resched())
 			__mwait(eax, ecx);
+		spec_ctrl_unprotected_end();
 	}
 	current_clr_polling();
 }
diff --git a/arch/x86/kernel/cpu/spec_ctrl.c b/arch/x86/kernel/cpu/spec_ctrl.c
index 2f3d6ca..843b4e6 100644
--- a/arch/x86/kernel/cpu/spec_ctrl.c
+++ b/arch/x86/kernel/cpu/spec_ctrl.c
@@ -4,12 +4,16 @@
 #include <asm/cpufeature.h>
 
 static bool ibrs_admin_enabled;
+DEFINE_STATIC_KEY_FALSE(spec_ctrl_dynamic_ibrs);
 
 void spec_ctrl_scan_feature(struct cpuinfo_x86 *c)
 {
 	if (boot_cpu_has(X86_FEATURE_SPEC_CTRL)) {
-		if (ibrs_admin_enabled)
+		if (ibrs_admin_enabled) {
 			set_cpu_cap(c, X86_FEATURE_SPEC_CTRL_IBRS);
+			if (!c->cpu_index)
+				static_branch_enable(&spec_ctrl_dynamic_ibrs);
+		}
 	}
 }
 
@@ -21,3 +25,24 @@ static int __init check_ibrs_param(char *str)
 	return 0;
 }
 early_param("spectre_v2", check_ibrs_param);
+
+/*
+ * Interrupts must be disabled to begin unprotected speculation.
+ * Otherwise interrupts could come in and start running in unprotected mode.
+ */
+
+void spec_ctrl_unprotected_begin(void)
+{
+	/* should use lockdep_assert_irqs_disabled() when available */
+	WARN_ON_ONCE(!irqs_disabled());
+	if (static_branch_unlikely(&spec_ctrl_dynamic_ibrs))
+		__enable_indirect_speculation();
+}
+EXPORT_SYMBOL_GPL(spec_ctrl_unprotected_begin);
+
+void spec_ctrl_unprotected_end(void)
+{
+	if (static_branch_unlikely(&spec_ctrl_dynamic_ibrs))
+		__disable_indirect_speculation();
+}
+EXPORT_SYMBOL_GPL(spec_ctrl_unprotected_end);
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 3cb2486..87a1121 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -39,6 +39,7 @@
 #include <asm/switch_to.h>
 #include <asm/desc.h>
 #include <asm/prctl.h>
+#include <asm/spec_ctrl.h>
 
 /*
  * per-CPU TSS segments. Threads are completely 'soft' on Linux,
@@ -461,11 +462,15 @@ static __cpuidle void mwait_idle(void)
 			mb(); /* quirk */
 		}
 
+		spec_ctrl_unprotected_begin();
 		__monitor((void *)&current_thread_info()->flags, 0, 0);
-		if (!need_resched())
+		if (!need_resched()) {
 			__sti_mwait(0, 0);
-		else
+			spec_ctrl_unprotected_end();
+		} else {
+			spec_ctrl_unprotected_end();
 			local_irq_enable();
+		}
 		trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id());
 	} else {
 		local_irq_enable();
-- 
2.9.4

      parent reply	other threads:[~2018-01-10  2:47 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-01-10  2:26 [PATCH v3 0/5] IBRS patch series Tim Chen
2018-01-10  2:26 ` [PATCH v3 1/5] x86/feature: Detect the x86 IBRS feature to control Speculation Tim Chen
2018-01-10  2:26 ` [PATCH v3 2/5] x86/enter: Create macros to set/clear IBRS Tim Chen
2018-01-11 16:04   ` Thomas Gleixner
2018-01-11 21:05     ` Tim Chen
2018-01-11 21:24       ` Tim Chen
2018-01-10  2:26 ` [PATCH v3 3/5] x86/enter: Use IBRS on syscall and interrupts Tim Chen
2018-01-10 10:04   ` Peter Zijlstra
2018-01-10 11:27     ` Paolo Bonzini
2018-01-10 18:16     ` Tim Chen
2018-01-10 18:28       ` Peter Zijlstra
2018-01-10 18:44         ` Tim Chen
2018-01-10 18:47         ` Van De Ven, Arjan
2018-01-11 12:45   ` Woodhouse, David
2018-01-10  2:26 ` [PATCH v3 4/5] x86/ibrs: Create boot option for IBRS Tim Chen
2018-01-10  2:26 ` Tim Chen [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4a460698535c0d5bb939db076fc952270033ac8d.1515542293.git.tim.c.chen@linux.intel.com \
    --to=tim.c.chen@linux.intel.com \
    --cc=aarcange@redhat.com \
    --cc=ak@linux.intel.com \
    --cc=arjan.van.de.ven@intel.com \
    --cc=ashok.raj@intel.com \
    --cc=dan.j.williams@intel.com \
    --cc=dave.hansen@intel.com \
    --cc=dwmw@amazon.co.uk \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=peterz@infradead.org \
    --cc=tglx@linutronix.de \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).