From: Andrew Cooper <andrew.cooper3@citrix.com>
To: Xen-devel <xen-devel@lists.xen.org>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Subject: [PATCH v6.5 26/26] x86/idle: Clear SPEC_CTRL while idle
Date: Thu, 4 Jan 2018 00:15:55 +0000 [thread overview]
Message-ID: <1515024955-13390-27-git-send-email-andrew.cooper3@citrix.com> (raw)
In-Reply-To: <1515024955-13390-1-git-send-email-andrew.cooper3@citrix.com>
On contemporary hardware, setting IBRS/STIBP has a performance impact on
adjacent hyperthreads. It is therefore recommended to clear the setting
before becoming idle, to avoid an idle core preventing adjacent userspace
execution from running at full performance.
Care must be taken to ensure there are no ret or indirect branch instructions
between spec_ctrl_{enter,exit}_idle() invocations, which are forced always
inline. Care must also be taken to avoid using spec_ctrl_enter_idle() between
flushing caches and becoming idle, in cases where that matters.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
v2:
* Use spec_ctrl_{enter,exit}_idle() rather than opencoding
v3:
* Reimplement almost from scratch.
v4:
* Spelling fixes.
* Drop k constraints. They aren't actually modifiers.
---
xen/arch/x86/acpi/cpu_idle.c | 21 +++++++++++++++++++++
xen/arch/x86/cpu/mwait-idle.c | 7 +++++++
xen/arch/x86/domain.c | 8 ++++++++
xen/include/asm-x86/spec_ctrl.h | 34 ++++++++++++++++++++++++++++++++++
4 files changed, 70 insertions(+)
diff --git a/xen/arch/x86/acpi/cpu_idle.c b/xen/arch/x86/acpi/cpu_idle.c
index cb1c5da..3f72bda 100644
--- a/xen/arch/x86/acpi/cpu_idle.c
+++ b/xen/arch/x86/acpi/cpu_idle.c
@@ -55,6 +55,7 @@
#include <asm/mwait.h>
#include <xen/notifier.h>
#include <xen/cpu.h>
+#include <asm/spec_ctrl.h>
/*#define DEBUG_PM_CX*/
@@ -414,8 +415,14 @@ void mwait_idle_with_hints(unsigned int eax, unsigned int ecx)
*/
if ( (expires > NOW() || expires == 0) && !softirq_pending(cpu) )
{
+ struct cpu_info *info = get_cpu_info();
+
cpumask_set_cpu(cpu, &cpuidle_mwait_flags);
+
+ spec_ctrl_enter_idle(info);
__mwait(eax, ecx);
+ spec_ctrl_exit_idle(info);
+
cpumask_clear_cpu(cpu, &cpuidle_mwait_flags);
}
@@ -430,6 +437,8 @@ static void acpi_processor_ffh_cstate_enter(struct acpi_processor_cx *cx)
static void acpi_idle_do_entry(struct acpi_processor_cx *cx)
{
+ struct cpu_info *info = get_cpu_info();
+
switch ( cx->entry_method )
{
case ACPI_CSTATE_EM_FFH:
@@ -437,15 +446,19 @@ static void acpi_idle_do_entry(struct acpi_processor_cx *cx)
acpi_processor_ffh_cstate_enter(cx);
return;
case ACPI_CSTATE_EM_SYSIO:
+ spec_ctrl_enter_idle(info);
/* IO port based C-state */
inb(cx->address);
/* Dummy wait op - must do something useless after P_LVL2 read
because chipsets cannot guarantee that STPCLK# signal
gets asserted in time to freeze execution properly. */
inl(pmtmr_ioport);
+ spec_ctrl_exit_idle(info);
return;
case ACPI_CSTATE_EM_HALT:
+ spec_ctrl_enter_idle(info);
safe_halt();
+ spec_ctrl_exit_idle(info);
local_irq_disable();
return;
}
@@ -573,7 +586,13 @@ static void acpi_processor_idle(void)
if ( pm_idle_save )
pm_idle_save();
else
+ {
+ struct cpu_info *info = get_cpu_info();
+
+ spec_ctrl_enter_idle(info);
safe_halt();
+ spec_ctrl_exit_idle(info);
+ }
return;
}
@@ -752,6 +771,7 @@ void acpi_dead_idle(void)
* Otherwise, CPU may still hold dirty data, breaking cache coherency,
* leading to strange errors.
*/
+ spec_ctrl_enter_idle(get_cpu_info());
wbinvd();
while ( 1 )
@@ -781,6 +801,7 @@ void acpi_dead_idle(void)
u32 address = cx->address;
u32 pmtmr_ioport_local = pmtmr_ioport;
+ spec_ctrl_enter_idle(get_cpu_info());
wbinvd();
while ( 1 )
diff --git a/xen/arch/x86/cpu/mwait-idle.c b/xen/arch/x86/cpu/mwait-idle.c
index 762dff1..e357f29 100644
--- a/xen/arch/x86/cpu/mwait-idle.c
+++ b/xen/arch/x86/cpu/mwait-idle.c
@@ -58,6 +58,7 @@
#include <asm/hpet.h>
#include <asm/mwait.h>
#include <asm/msr.h>
+#include <asm/spec_ctrl.h>
#include <acpi/cpufreq/cpufreq.h>
#define MWAIT_IDLE_VERSION "0.4.1"
@@ -736,7 +737,13 @@ static void mwait_idle(void)
if (pm_idle_save)
pm_idle_save();
else
+ {
+ struct cpu_info *info = get_cpu_info();
+
+ spec_ctrl_enter_idle(info);
safe_halt();
+ spec_ctrl_exit_idle(info);
+ }
return;
}
diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index 62002f1..392e4f3 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -55,6 +55,7 @@
#include <asm/hvm/viridian.h>
#include <asm/debugreg.h>
#include <asm/msr.h>
+#include <asm/spec_ctrl.h>
#include <asm/traps.h>
#include <asm/nmi.h>
#include <asm/mce.h>
@@ -74,9 +75,15 @@ void (*dead_idle) (void) __read_mostly = default_dead_idle;
static void default_idle(void)
{
+ struct cpu_info *info = get_cpu_info();
+
local_irq_disable();
if ( cpu_is_haltable(smp_processor_id()) )
+ {
+ spec_ctrl_enter_idle(info);
safe_halt();
+ spec_ctrl_exit_idle(info);
+ }
else
local_irq_enable();
}
@@ -88,6 +95,7 @@ void default_dead_idle(void)
* held by the CPUs spinning here indefinitely, and get discarded by
* a subsequent INIT.
*/
+ spec_ctrl_enter_idle(get_cpu_info());
wbinvd();
for ( ; ; )
halt();
diff --git a/xen/include/asm-x86/spec_ctrl.h b/xen/include/asm-x86/spec_ctrl.h
index 29a31a9..20e9a5b 100644
--- a/xen/include/asm-x86/spec_ctrl.h
+++ b/xen/include/asm-x86/spec_ctrl.h
@@ -20,7 +20,9 @@
#ifndef __X86_SPEC_CTRL_H__
#define __X86_SPEC_CTRL_H__
+#include <asm/alternative.h>
#include <asm/current.h>
+#include <asm/msr-index.h>
void init_speculation_mitigations(void);
@@ -31,6 +33,38 @@ static inline void init_shadow_spec_ctrl_state(void)
info->shadow_spec_ctrl = info->use_shadow_spec_ctrl = 0;
}
+/* WARNING! `ret`, `call *`, `jmp *` not safe after this call. */
+static always_inline void spec_ctrl_enter_idle(struct cpu_info *info)
+{
+ uint32_t val = 0;
+
+ /*
+ * Latch the new shadow value, then enable shadowing, then update the MSR.
+ * There are no SMP issues here; only local processor ordering concerns.
+ */
+ info->shadow_spec_ctrl = val;
+ barrier();
+ info->use_shadow_spec_ctrl = true;
+ barrier();
+ asm volatile (ALTERNATIVE(ASM_NOP3, "wrmsr", X86_FEATURE_XEN_IBRS_SET)
+ :: "a" (val), "c" (MSR_SPEC_CTRL), "d" (0) : "memory");
+}
+
+/* WARNING! `ret`, `call *`, `jmp *` not safe before this call. */
+static always_inline void spec_ctrl_exit_idle(struct cpu_info *info)
+{
+ uint32_t val = SPEC_CTRL_IBRS;
+
+ /*
+ * Disable shadowing before updating the MSR. There are no SMP issues
+ * here; only local processor ordering concerns.
+ */
+ info->use_shadow_spec_ctrl = false;
+ barrier();
+ asm volatile (ALTERNATIVE(ASM_NOP3, "wrmsr", X86_FEATURE_XEN_IBRS_SET)
+ :: "a" (val), "c" (MSR_SPEC_CTRL), "d" (0) : "memory");
+}
+
#endif /* !__X86_SPEC_CTRL_H__ */
/*
--
2.1.4
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
next prev parent reply other threads:[~2018-01-04 0:15 UTC|newest]
Thread overview: 69+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-01-04 0:15 [PATCH v6.5 00/26] x86: Mitigations for SP2/CVE-2017-5715/Branch Target Injection Andrew Cooper
2018-01-04 0:15 ` [PATCH v6.5 01/26] x86/alt: Break out alternative-asm into a separate header file Andrew Cooper
2018-01-04 0:15 ` [PATCH v6.5 02/26] x86/alt: Introduce ALTERNATIVE{, _2} macros Andrew Cooper
2018-01-04 0:15 ` [PATCH v6.5 03/26] x86/hvm: Rename update_guest_vendor() callback to cpuid_policy_changed() Andrew Cooper
2018-01-04 0:15 ` [PATCH v6.5 04/26] x86: Introduce a common cpuid_policy_updated() Andrew Cooper
2018-01-04 0:15 ` [PATCH v6.5 05/26] x86/entry: Remove support for partial cpu_user_regs frames Andrew Cooper
2018-01-04 8:51 ` Jan Beulich
2018-01-04 0:15 ` [PATCH v6.5 06/26] x86/entry: Rearrange RESTORE_ALL to restore register in stack order Andrew Cooper
2018-01-04 0:15 ` [PATCH v6.5 07/26] x86/hvm: Use SAVE_ALL to construct the cpu_user_regs frame after VMExit Andrew Cooper
2018-01-04 0:15 ` [PATCH v6.5 08/26] x86/entry: Erase guest GPR state on entry to Xen Andrew Cooper
2018-01-22 10:04 ` David Woodhouse
2018-01-22 10:18 ` Andrew Cooper
2018-01-22 10:27 ` David Woodhouse
2018-01-04 0:15 ` [PATCH v6.5 09/26] x86: Support compiling with indirect branch thunks Andrew Cooper
2018-01-04 9:02 ` Jan Beulich
2018-01-04 0:15 ` [PATCH v6.5 10/26] common/wait: Clarifications to wait infrastructure Andrew Cooper
2018-01-04 0:15 ` [PATCH v6.5 11/26] x86: Support indirect thunks from assembly code Andrew Cooper
2018-01-04 9:23 ` Jan Beulich
2018-01-08 18:24 ` Andrew Cooper
2018-01-09 8:36 ` Jan Beulich
2018-01-09 11:23 ` Andrew Cooper
2018-01-09 13:18 ` Jan Beulich
2018-01-11 13:03 ` David Woodhouse
2018-01-11 13:41 ` Andrew Cooper
2018-01-11 13:46 ` David Woodhouse
2018-01-04 0:15 ` [PATCH v6.5 12/26] x86/boot: Report details of speculative mitigations Andrew Cooper
2018-01-04 9:29 ` Jan Beulich
2018-01-04 0:15 ` [PATCH v6.5 13/26] x86/amd: Try to set lfence as being Dispatch Serialising Andrew Cooper
2018-01-04 9:32 ` Jan Beulich
2018-01-08 19:01 ` Andrew Cooper
2018-01-09 8:38 ` Jan Beulich
2018-01-04 0:15 ` [PATCH v6.5 14/26] x86: Introduce alternative indirect thunks Andrew Cooper
2018-01-04 9:40 ` Jan Beulich
2018-01-09 11:44 ` Andrew Cooper
2018-01-09 13:24 ` Jan Beulich
2018-01-09 13:30 ` Andrew Cooper
2018-01-04 0:15 ` [PATCH v6.5 15/26] x86/feature: Definitions for Indirect Branch Controls Andrew Cooper
2018-01-04 1:14 ` Doug Goldstein
2018-01-04 1:16 ` Andrew Cooper
2018-01-04 4:05 ` Anthony Liguori
2018-01-04 9:42 ` Jan Beulich
2018-01-04 18:51 ` Wei Liu
2018-01-04 0:15 ` [PATCH v6.5 16/26] x86/cmdline: Introduce a command line option to disable IBRS/IBPB, STIBP and IBPB Andrew Cooper
2018-01-04 9:43 ` Jan Beulich
2018-01-04 0:15 ` [PATCH v6.5 17/26] x86/msr: Emulation of MSR_{SPEC_CTRL, PRED_CMD} for guests Andrew Cooper
2018-01-04 0:15 ` [PATCH v6.5 18/26] x86/migrate: Move MSR_SPEC_CTRL on migrate Andrew Cooper
2018-01-04 0:15 ` [PATCH v6.5 19/26] x86/hvm: Permit guests direct access to MSR_{SPEC_CTRL, PRED_CMD} Andrew Cooper
2018-01-04 9:52 ` Jan Beulich
2018-01-09 12:03 ` Andrew Cooper
2018-01-09 13:28 ` Jan Beulich
2018-01-09 13:34 ` Andrew Cooper
2018-01-09 13:58 ` Jan Beulich
2018-01-04 0:15 ` [PATCH v6.5 20/26] x86: Protect unaware domains from meddling hyperthreads Andrew Cooper
2018-01-04 9:59 ` Jan Beulich
2018-01-09 14:21 ` Andrew Cooper
2018-01-09 14:29 ` Jan Beulich
2018-01-04 0:15 ` [PATCH v6.5 21/26] x86/entry: Use MSR_SPEC_CTRL at each entry/exit point Andrew Cooper
2018-01-04 10:14 ` Jan Beulich
2018-01-04 0:15 ` [PATCH v6.5 22/26] x86/boot: Calculate the most appropriate BTI mitigation to use Andrew Cooper
2018-01-04 10:17 ` Jan Beulich
2018-01-04 0:15 ` [PATCH v6.5 23/26] x86/entry: Clobber the Return Stack Buffer on entry to Xen Andrew Cooper
2018-01-04 10:22 ` Jan Beulich
2018-01-04 0:15 ` [PATCH v6.5 24/26] x86/ctxt: Issue a speculation barrier between vcpu contexts Andrew Cooper
2018-01-04 10:25 ` Jan Beulich
2018-01-04 0:15 ` [PATCH v6.5 25/26] x86/cpuid: Offer Indirect Branch Controls to guests Andrew Cooper
2018-01-09 11:44 ` Wei Liu
2018-01-04 0:15 ` Andrew Cooper [this message]
2018-01-04 10:29 ` [PATCH v6.5 26/26] x86/idle: Clear SPEC_CTRL while idle Jan Beulich
2018-01-04 10:41 ` Jan Beulich
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=1515024955-13390-27-git-send-email-andrew.cooper3@citrix.com \
--to=andrew.cooper3@citrix.com \
--cc=xen-devel@lists.xen.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).