diff options
25 files changed, 4078 insertions, 1 deletions
diff --git a/main/xen/0001-x86-spec_ctrl-Read-MSR_ARCH_CAPABILITIES-only-once.patch b/main/xen/0001-x86-spec_ctrl-Read-MSR_ARCH_CAPABILITIES-only-once.patch new file mode 100644 index 0000000000..747b93dca0 --- /dev/null +++ b/main/xen/0001-x86-spec_ctrl-Read-MSR_ARCH_CAPABILITIES-only-once.patch @@ -0,0 +1,110 @@ +From 79570591b03f3a52ed7c7d923dc943a6b9912f63 Mon Sep 17 00:00:00 2001 +From: Andrew Cooper <andrew.cooper3@citrix.com> +Date: Thu, 26 Apr 2018 12:21:00 +0100 +Subject: [PATCH] x86/spec_ctrl: Read MSR_ARCH_CAPABILITIES only once + +Make it available from the beginning of init_speculation_mitigations(), and +pass it into appropriate functions. Fix an RSBA typo while moving the +affected comment. + +Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> +Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> +Reviewed-by: Wei Liu <wei.liu2@citrix.com> +Reviewed-by: Jan Beulich <jbeulich@suse.com> +Release-acked-by: Juergen Gross <jgross@suse.com> +(cherry picked from commit d6c65187252a6c1810fd24c4d46f812840de8d3c) +--- + xen/arch/x86/spec_ctrl.c | 34 ++++++++++++++-------------------- + 1 file changed, 14 insertions(+), 20 deletions(-) + +diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c +index fa67a0f..dc90743 100644 +--- a/xen/arch/x86/spec_ctrl.c ++++ b/xen/arch/x86/spec_ctrl.c +@@ -81,18 +81,15 @@ static int __init parse_bti(const char *s) + } + custom_param("bti", parse_bti); + +-static void __init print_details(enum ind_thunk thunk) ++static void __init print_details(enum ind_thunk thunk, uint64_t caps) + { + unsigned int _7d0 = 0, e8b = 0, tmp; +- uint64_t caps = 0; + + /* Collect diagnostics about available mitigations. */ + if ( boot_cpu_data.cpuid_level >= 7 ) + cpuid_count(7, 0, &tmp, &tmp, &tmp, &_7d0); + if ( boot_cpu_data.extended_cpuid_level >= 0x80000008 ) + cpuid(0x80000008, &tmp, &e8b, &tmp, &tmp); +- if ( _7d0 & cpufeat_mask(X86_FEATURE_ARCH_CAPS) ) +- rdmsrl(MSR_ARCH_CAPABILITIES, caps); + + printk(XENLOG_DEBUG "Speculative mitigation facilities:\n"); + +@@ -125,7 +122,7 @@ static void __init print_details(enum ind_thunk thunk) + } + + /* Calculate whether Retpoline is known-safe on this CPU. */ +-static bool __init retpoline_safe(void) ++static bool __init retpoline_safe(uint64_t caps) + { + unsigned int ucode_rev = this_cpu(ucode_cpu_info).cpu_sig.rev; + +@@ -136,19 +133,12 @@ static bool __init retpoline_safe(void) + boot_cpu_data.x86 != 6 ) + return false; + +- if ( boot_cpu_has(X86_FEATURE_ARCH_CAPS) ) +- { +- uint64_t caps; +- +- rdmsrl(MSR_ARCH_CAPABILITIES, caps); +- +- /* +- * RBSA may be set by a hypervisor to indicate that we may move to a +- * processor which isn't retpoline-safe. +- */ +- if ( caps & ARCH_CAPS_RSBA ) +- return false; +- } ++ /* ++ * RSBA may be set by a hypervisor to indicate that we may move to a ++ * processor which isn't retpoline-safe. ++ */ ++ if ( caps & ARCH_CAPS_RSBA ) ++ return false; + + switch ( boot_cpu_data.x86_model ) + { +@@ -218,6 +208,10 @@ void __init init_speculation_mitigations(void) + { + enum ind_thunk thunk = THUNK_DEFAULT; + bool ibrs = false; ++ uint64_t caps = 0; ++ ++ if ( boot_cpu_has(X86_FEATURE_ARCH_CAPS) ) ++ rdmsrl(MSR_ARCH_CAPABILITIES, caps); + + /* + * Has the user specified any custom BTI mitigations? If so, follow their +@@ -246,7 +240,7 @@ void __init init_speculation_mitigations(void) + * On Intel hardware, we'd like to use retpoline in preference to + * IBRS, but only if it is safe on this hardware. + */ +- else if ( retpoline_safe() ) ++ else if ( retpoline_safe(caps) ) + thunk = THUNK_RETPOLINE; + else if ( boot_cpu_has(X86_FEATURE_IBRSB) ) + ibrs = true; +@@ -331,7 +325,7 @@ void __init init_speculation_mitigations(void) + /* (Re)init BSP state now that default_bti_ist_info has been calculated. */ + init_shadow_spec_ctrl_state(); + +- print_details(thunk); ++ print_details(thunk, caps); + } + + static void __init __maybe_unused build_assertions(void) +-- +2.1.4 + diff --git a/main/xen/0002-x86-spec_ctrl-Express-Xen-s-choice-of-MSR_SPEC_CTRL-.patch b/main/xen/0002-x86-spec_ctrl-Express-Xen-s-choice-of-MSR_SPEC_CTRL-.patch new file mode 100644 index 0000000000..a17d07234d --- /dev/null +++ b/main/xen/0002-x86-spec_ctrl-Express-Xen-s-choice-of-MSR_SPEC_CTRL-.patch @@ -0,0 +1,138 @@ +From c7bf6074ea8c3496894d517371ea6d9d3bd90c98 Mon Sep 17 00:00:00 2001 +From: Andrew Cooper <andrew.cooper3@citrix.com> +Date: Tue, 17 Apr 2018 14:15:04 +0100 +Subject: [PATCH] x86/spec_ctrl: Express Xen's choice of MSR_SPEC_CTRL value as + a variable + +At the moment, we have two different encodings of Xen's MSR_SPEC_CTRL value, +which is a side effect of how the Spectre series developed. One encoding is +via an alias with the bottom bit of bti_ist_info, and can encode IBRS or not, +but not other configurations such as STIBP. + +Break Xen's value out into a separate variable (in the top of stack block for +XPTI reasons) and use this instead of bti_ist_info in the IST path. + +Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> +Reviewed-by: Wei Liu <wei.liu2@citrix.com> +Reviewed-by: Jan Beulich <jbeulich@suse.com> +Release-acked-by: Juergen Gross <jgross@suse.com> +(cherry picked from commit 66dfae0f32bfbc899c2f3446d5ee57068cb7f957) +--- + xen/arch/x86/spec_ctrl.c | 8 +++++--- + xen/arch/x86/x86_64/asm-offsets.c | 1 + + xen/include/asm-x86/current.h | 1 + + xen/include/asm-x86/spec_ctrl.h | 2 ++ + xen/include/asm-x86/spec_ctrl_asm.h | 8 ++------ + 5 files changed, 11 insertions(+), 9 deletions(-) + +diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c +index dc90743..1143521 100644 +--- a/xen/arch/x86/spec_ctrl.c ++++ b/xen/arch/x86/spec_ctrl.c +@@ -38,6 +38,7 @@ static int8_t __initdata opt_ibrs = -1; + static bool __initdata opt_rsb_native = true; + static bool __initdata opt_rsb_vmexit = true; + bool __read_mostly opt_ibpb = true; ++uint8_t __read_mostly default_xen_spec_ctrl; + uint8_t __read_mostly default_bti_ist_info; + + static int __init parse_bti(const char *s) +@@ -285,11 +286,14 @@ void __init init_speculation_mitigations(void) + * guests. + */ + if ( ibrs ) ++ { ++ default_xen_spec_ctrl |= SPEC_CTRL_IBRS; + setup_force_cpu_cap(X86_FEATURE_XEN_IBRS_SET); ++ } + else + setup_force_cpu_cap(X86_FEATURE_XEN_IBRS_CLEAR); + +- default_bti_ist_info |= BTI_IST_WRMSR | ibrs; ++ default_bti_ist_info |= BTI_IST_WRMSR; + } + + /* +@@ -330,8 +334,6 @@ void __init init_speculation_mitigations(void) + + static void __init __maybe_unused build_assertions(void) + { +- /* The optimised assembly relies on this alias. */ +- BUILD_BUG_ON(BTI_IST_IBRS != SPEC_CTRL_IBRS); + } + + /* +diff --git a/xen/arch/x86/x86_64/asm-offsets.c b/xen/arch/x86/x86_64/asm-offsets.c +index d66dbf0..6dd0476 100644 +--- a/xen/arch/x86/x86_64/asm-offsets.c ++++ b/xen/arch/x86/x86_64/asm-offsets.c +@@ -142,6 +142,7 @@ void __dummy__(void) + OFFSET(CPUINFO_xen_cr3, struct cpu_info, xen_cr3); + OFFSET(CPUINFO_pv_cr3, struct cpu_info, pv_cr3); + OFFSET(CPUINFO_shadow_spec_ctrl, struct cpu_info, shadow_spec_ctrl); ++ OFFSET(CPUINFO_xen_spec_ctrl, struct cpu_info, xen_spec_ctrl); + OFFSET(CPUINFO_use_shadow_spec_ctrl, struct cpu_info, use_shadow_spec_ctrl); + OFFSET(CPUINFO_bti_ist_info, struct cpu_info, bti_ist_info); + DEFINE(CPUINFO_sizeof, sizeof(struct cpu_info)); +diff --git a/xen/include/asm-x86/current.h b/xen/include/asm-x86/current.h +index 4678a0f..d10b13c 100644 +--- a/xen/include/asm-x86/current.h ++++ b/xen/include/asm-x86/current.h +@@ -56,6 +56,7 @@ struct cpu_info { + + /* See asm-x86/spec_ctrl_asm.h for usage. */ + unsigned int shadow_spec_ctrl; ++ uint8_t xen_spec_ctrl; + bool use_shadow_spec_ctrl; + uint8_t bti_ist_info; + +diff --git a/xen/include/asm-x86/spec_ctrl.h b/xen/include/asm-x86/spec_ctrl.h +index 5ab4ff3..5e4fc84 100644 +--- a/xen/include/asm-x86/spec_ctrl.h ++++ b/xen/include/asm-x86/spec_ctrl.h +@@ -27,6 +27,7 @@ + void init_speculation_mitigations(void); + + extern bool opt_ibpb; ++extern uint8_t default_xen_spec_ctrl; + extern uint8_t default_bti_ist_info; + + static inline void init_shadow_spec_ctrl_state(void) +@@ -34,6 +35,7 @@ static inline void init_shadow_spec_ctrl_state(void) + struct cpu_info *info = get_cpu_info(); + + info->shadow_spec_ctrl = info->use_shadow_spec_ctrl = 0; ++ info->xen_spec_ctrl = default_xen_spec_ctrl; + info->bti_ist_info = default_bti_ist_info; + } + +diff --git a/xen/include/asm-x86/spec_ctrl_asm.h b/xen/include/asm-x86/spec_ctrl_asm.h +index 69cf3cc..9c16945 100644 +--- a/xen/include/asm-x86/spec_ctrl_asm.h ++++ b/xen/include/asm-x86/spec_ctrl_asm.h +@@ -21,7 +21,6 @@ + #define __X86_SPEC_CTRL_ASM_H__ + + /* Encoding of the bottom bits in cpuinfo.bti_ist_info */ +-#define BTI_IST_IBRS (1 << 0) + #define BTI_IST_WRMSR (1 << 1) + #define BTI_IST_RSB (1 << 2) + +@@ -285,12 +284,9 @@ + setz %dl + and %dl, STACK_CPUINFO_FIELD(use_shadow_spec_ctrl)(%r14) + +- /* +- * Load Xen's intended value. SPEC_CTRL_IBRS vs 0 is encoded in the +- * bottom bit of bti_ist_info, via a deliberate alias with BTI_IST_IBRS. +- */ ++ /* Load Xen's intended value. */ + mov $MSR_SPEC_CTRL, %ecx +- and $BTI_IST_IBRS, %eax ++ movzbl STACK_CPUINFO_FIELD(xen_spec_ctrl)(%r14), %eax + xor %edx, %edx + wrmsr + +-- +2.1.4 + diff --git a/main/xen/0003-x86-spec_ctrl-Merge-bti_ist_info-and-use_shadow_spec.patch b/main/xen/0003-x86-spec_ctrl-Merge-bti_ist_info-and-use_shadow_spec.patch new file mode 100644 index 0000000000..590a3b9bea --- /dev/null +++ b/main/xen/0003-x86-spec_ctrl-Merge-bti_ist_info-and-use_shadow_spec.patch @@ -0,0 +1,340 @@ +From e57b5ea6fa2b2d93fde033cec11d6ec6d524ade3 Mon Sep 17 00:00:00 2001 +From: Andrew Cooper <andrew.cooper3@citrix.com> +Date: Tue, 17 Apr 2018 14:15:04 +0100 +Subject: [PATCH] x86/spec_ctrl: Merge bti_ist_info and use_shadow_spec_ctrl + into spec_ctrl_flags + +All 3 bits of information here are control flags for the entry/exit code +behaviour. Treat them as such, rather than having two different variables. + +Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> +Reviewed-by: Wei Liu <wei.liu2@citrix.com> +Reviewed-by: Jan Beulich <jbeulich@suse.com> +Release-acked-by: Juergen Gross <jgross@suse.com> +(cherry picked from commit 5262ba2e7799001402dfe139ff944e035dfff928) +--- + xen/arch/x86/acpi/power.c | 4 +-- + xen/arch/x86/spec_ctrl.c | 10 ++++--- + xen/arch/x86/x86_64/asm-offsets.c | 3 +-- + xen/include/asm-x86/current.h | 3 +-- + xen/include/asm-x86/nops.h | 5 ++-- + xen/include/asm-x86/spec_ctrl.h | 10 +++---- + xen/include/asm-x86/spec_ctrl_asm.h | 52 ++++++++++++++++++++----------------- + 7 files changed, 45 insertions(+), 42 deletions(-) + +diff --git a/xen/arch/x86/acpi/power.c b/xen/arch/x86/acpi/power.c +index f7085d3..f3480aa 100644 +--- a/xen/arch/x86/acpi/power.c ++++ b/xen/arch/x86/acpi/power.c +@@ -215,7 +215,7 @@ static int enter_state(u32 state) + ci = get_cpu_info(); + spec_ctrl_enter_idle(ci); + /* Avoid NMI/#MC using MSR_SPEC_CTRL until we've reloaded microcode. */ +- ci->bti_ist_info = 0; ++ ci->spec_ctrl_flags &= ~SCF_ist_wrmsr; + + ACPI_FLUSH_CPU_CACHE(); + +@@ -256,7 +256,7 @@ static int enter_state(u32 state) + microcode_resume_cpu(0); + + /* Re-enabled default NMI/#MC use of MSR_SPEC_CTRL. */ +- ci->bti_ist_info = default_bti_ist_info; ++ ci->spec_ctrl_flags |= (default_spec_ctrl_flags & SCF_ist_wrmsr); + spec_ctrl_exit_idle(ci); + + done: +diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c +index 1143521..2d69910 100644 +--- a/xen/arch/x86/spec_ctrl.c ++++ b/xen/arch/x86/spec_ctrl.c +@@ -39,7 +39,7 @@ static bool __initdata opt_rsb_native = true; + static bool __initdata opt_rsb_vmexit = true; + bool __read_mostly opt_ibpb = true; + uint8_t __read_mostly default_xen_spec_ctrl; +-uint8_t __read_mostly default_bti_ist_info; ++uint8_t __read_mostly default_spec_ctrl_flags; + + static int __init parse_bti(const char *s) + { +@@ -293,7 +293,7 @@ void __init init_speculation_mitigations(void) + else + setup_force_cpu_cap(X86_FEATURE_XEN_IBRS_CLEAR); + +- default_bti_ist_info |= BTI_IST_WRMSR; ++ default_spec_ctrl_flags |= SCF_ist_wrmsr; + } + + /* +@@ -312,7 +312,7 @@ void __init init_speculation_mitigations(void) + if ( opt_rsb_native ) + { + setup_force_cpu_cap(X86_FEATURE_RSB_NATIVE); +- default_bti_ist_info |= BTI_IST_RSB; ++ default_spec_ctrl_flags |= SCF_ist_rsb; + } + + /* +@@ -326,7 +326,7 @@ void __init init_speculation_mitigations(void) + if ( !boot_cpu_has(X86_FEATURE_IBRSB) && !boot_cpu_has(X86_FEATURE_IBPB) ) + opt_ibpb = false; + +- /* (Re)init BSP state now that default_bti_ist_info has been calculated. */ ++ /* (Re)init BSP state now that default_spec_ctrl_flags has been calculated. */ + init_shadow_spec_ctrl_state(); + + print_details(thunk, caps); +@@ -334,6 +334,8 @@ void __init init_speculation_mitigations(void) + + static void __init __maybe_unused build_assertions(void) + { ++ /* The optimised assembly relies on this alias. */ ++ BUILD_BUG_ON(SCF_use_shadow != 1); + } + + /* +diff --git a/xen/arch/x86/x86_64/asm-offsets.c b/xen/arch/x86/x86_64/asm-offsets.c +index 6dd0476..cc97d75 100644 +--- a/xen/arch/x86/x86_64/asm-offsets.c ++++ b/xen/arch/x86/x86_64/asm-offsets.c +@@ -143,8 +143,7 @@ void __dummy__(void) + OFFSET(CPUINFO_pv_cr3, struct cpu_info, pv_cr3); + OFFSET(CPUINFO_shadow_spec_ctrl, struct cpu_info, shadow_spec_ctrl); + OFFSET(CPUINFO_xen_spec_ctrl, struct cpu_info, xen_spec_ctrl); +- OFFSET(CPUINFO_use_shadow_spec_ctrl, struct cpu_info, use_shadow_spec_ctrl); +- OFFSET(CPUINFO_bti_ist_info, struct cpu_info, bti_ist_info); ++ OFFSET(CPUINFO_spec_ctrl_flags, struct cpu_info, spec_ctrl_flags); + DEFINE(CPUINFO_sizeof, sizeof(struct cpu_info)); + BLANK(); + +diff --git a/xen/include/asm-x86/current.h b/xen/include/asm-x86/current.h +index d10b13c..7afff0e 100644 +--- a/xen/include/asm-x86/current.h ++++ b/xen/include/asm-x86/current.h +@@ -57,8 +57,7 @@ struct cpu_info { + /* See asm-x86/spec_ctrl_asm.h for usage. */ + unsigned int shadow_spec_ctrl; + uint8_t xen_spec_ctrl; +- bool use_shadow_spec_ctrl; +- uint8_t bti_ist_info; ++ uint8_t spec_ctrl_flags; + + unsigned long __pad; + /* get_stack_bottom() must be 16-byte aligned */ +diff --git a/xen/include/asm-x86/nops.h b/xen/include/asm-x86/nops.h +index 37f9819..b744895 100644 +--- a/xen/include/asm-x86/nops.h ++++ b/xen/include/asm-x86/nops.h +@@ -62,10 +62,9 @@ + #define ASM_NOP8 _ASM_MK_NOP(K8_NOP8) + + #define ASM_NOP17 ASM_NOP8; ASM_NOP7; ASM_NOP2 +-#define ASM_NOP21 ASM_NOP8; ASM_NOP8; ASM_NOP5 ++#define ASM_NOP22 ASM_NOP8; ASM_NOP8; ASM_NOP6 + #define ASM_NOP24 ASM_NOP8; ASM_NOP8; ASM_NOP8 +-#define ASM_NOP29 ASM_NOP8; ASM_NOP8; ASM_NOP8; ASM_NOP5 +-#define ASM_NOP32 ASM_NOP8; ASM_NOP8; ASM_NOP8; ASM_NOP8 ++#define ASM_NOP33 ASM_NOP8; ASM_NOP8; ASM_NOP8; ASM_NOP7; ASM_NOP2 + #define ASM_NOP40 ASM_NOP8; ASM_NOP8; ASM_NOP8; ASM_NOP8; ASM_NOP8 + + #define ASM_NOP_MAX 8 +diff --git a/xen/include/asm-x86/spec_ctrl.h b/xen/include/asm-x86/spec_ctrl.h +index 5e4fc84..059e291 100644 +--- a/xen/include/asm-x86/spec_ctrl.h ++++ b/xen/include/asm-x86/spec_ctrl.h +@@ -28,15 +28,15 @@ void init_speculation_mitigations(void); + + extern bool opt_ibpb; + extern uint8_t default_xen_spec_ctrl; +-extern uint8_t default_bti_ist_info; ++extern uint8_t default_spec_ctrl_flags; + + static inline void init_shadow_spec_ctrl_state(void) + { + struct cpu_info *info = get_cpu_info(); + +- info->shadow_spec_ctrl = info->use_shadow_spec_ctrl = 0; ++ info->shadow_spec_ctrl = 0; + info->xen_spec_ctrl = default_xen_spec_ctrl; +- info->bti_ist_info = default_bti_ist_info; ++ info->spec_ctrl_flags = default_spec_ctrl_flags; + } + + /* WARNING! `ret`, `call *`, `jmp *` not safe after this call. */ +@@ -50,7 +50,7 @@ static always_inline void spec_ctrl_enter_idle(struct cpu_info *info) + */ + info->shadow_spec_ctrl = val; + barrier(); +- info->use_shadow_spec_ctrl = true; ++ info->spec_ctrl_flags |= SCF_use_shadow; + barrier(); + asm volatile ( ALTERNATIVE(ASM_NOP3, "wrmsr", X86_FEATURE_XEN_IBRS_SET) + :: "a" (val), "c" (MSR_SPEC_CTRL), "d" (0) : "memory" ); +@@ -65,7 +65,7 @@ static always_inline void spec_ctrl_exit_idle(struct cpu_info *info) + * Disable shadowing before updating the MSR. There are no SMP issues + * here; only local processor ordering concerns. + */ +- info->use_shadow_spec_ctrl = false; ++ info->spec_ctrl_flags &= ~SCF_use_shadow; + barrier(); + asm volatile ( ALTERNATIVE(ASM_NOP3, "wrmsr", X86_FEATURE_XEN_IBRS_SET) + :: "a" (val), "c" (MSR_SPEC_CTRL), "d" (0) : "memory" ); +diff --git a/xen/include/asm-x86/spec_ctrl_asm.h b/xen/include/asm-x86/spec_ctrl_asm.h +index 9c16945..582403a 100644 +--- a/xen/include/asm-x86/spec_ctrl_asm.h ++++ b/xen/include/asm-x86/spec_ctrl_asm.h +@@ -20,9 +20,10 @@ + #ifndef __X86_SPEC_CTRL_ASM_H__ + #define __X86_SPEC_CTRL_ASM_H__ + +-/* Encoding of the bottom bits in cpuinfo.bti_ist_info */ +-#define BTI_IST_WRMSR (1 << 1) +-#define BTI_IST_RSB (1 << 2) ++/* Encoding of cpuinfo.spec_ctrl_flags */ ++#define SCF_use_shadow (1 << 0) ++#define SCF_ist_wrmsr (1 << 1) ++#define SCF_ist_rsb (1 << 2) + + #ifdef __ASSEMBLY__ + #include <asm/msr-index.h> +@@ -49,20 +50,20 @@ + * after VMEXIT. The VMEXIT-specific code reads MSR_SPEC_CTRL and updates + * current before loading Xen's MSR_SPEC_CTRL setting. + * +- * Factor 2 is harder. We maintain a shadow_spec_ctrl value, and +- * use_shadow_spec_ctrl boolean per cpu. The synchronous use is: ++ * Factor 2 is harder. We maintain a shadow_spec_ctrl value, and a use_shadow ++ * boolean in the per cpu spec_ctrl_flags. The synchronous use is: + * + * 1) Store guest value in shadow_spec_ctrl +- * 2) Set use_shadow_spec_ctrl boolean ++ * 2) Set the use_shadow boolean + * 3) Load guest value into MSR_SPEC_CTRL + * 4) Exit to guest + * 5) Entry from guest +- * 6) Clear use_shadow_spec_ctrl boolean ++ * 6) Clear the use_shadow boolean + * 7) Load Xen's value into MSR_SPEC_CTRL + * + * The asynchronous use for interrupts/exceptions is: + * - Set/clear IBRS on entry to Xen +- * - On exit to Xen, check use_shadow_spec_ctrl ++ * - On exit to Xen, check use_shadow + * - If set, load shadow_spec_ctrl + * + * Therefore, an interrupt/exception which hits the synchronous path between +@@ -133,7 +134,7 @@ + xor %edx, %edx + + /* Clear SPEC_CTRL shadowing *before* loading Xen's value. */ +- movb %dl, CPUINFO_use_shadow_spec_ctrl(%rsp) ++ andb $~SCF_use_shadow, CPUINFO_spec_ctrl_flags(%rsp) + + /* Load Xen's intended value. */ + mov $\ibrs_val, %eax +@@ -159,12 +160,14 @@ + * block so calculate the position directly. + */ + .if \maybexen ++ xor %eax, %eax + /* Branchless `if ( !xen ) clear_shadowing` */ + testb $3, UREGS_cs(%rsp) +- setz %al +- and %al, STACK_CPUINFO_FIELD(use_shadow_spec_ctrl)(%r14) ++ setnz %al ++ not %eax ++ and %al, STACK_CPUINFO_FIELD(spec_ctrl_flags)(%r14) + .else +- movb %dl, CPUINFO_use_shadow_spec_ctrl(%rsp) ++ andb $~SCF_use_shadow, CPUINFO_spec_ctrl_flags(%rsp) + .endif + + /* Load Xen's intended value. */ +@@ -183,8 +186,8 @@ + */ + xor %edx, %edx + +- cmpb %dl, STACK_CPUINFO_FIELD(use_shadow_spec_ctrl)(%rbx) +- je .L\@_skip ++ testb $SCF_use_shadow, STACK_CPUINFO_FIELD(spec_ctrl_flags)(%rbx) ++ jz .L\@_skip + + mov STACK_CPUINFO_FIELD(shadow_spec_ctrl)(%rbx), %eax + mov $MSR_SPEC_CTRL, %ecx +@@ -205,7 +208,7 @@ + mov %eax, CPUINFO_shadow_spec_ctrl(%rsp) + + /* Set SPEC_CTRL shadowing *before* loading the guest value. */ +- movb $1, CPUINFO_use_shadow_spec_ctrl(%rsp) ++ orb $SCF_use_shadow, CPUINFO_spec_ctrl_flags(%rsp) + + mov $MSR_SPEC_CTRL, %ecx + xor %edx, %edx +@@ -216,7 +219,7 @@ + #define SPEC_CTRL_ENTRY_FROM_VMEXIT \ + ALTERNATIVE __stringify(ASM_NOP40), \ + DO_OVERWRITE_RSB, X86_FEATURE_RSB_VMEXIT; \ +- ALTERNATIVE_2 __stringify(ASM_NOP32), \ ++ ALTERNATIVE_2 __stringify(ASM_NOP33), \ + __stringify(DO_SPEC_CTRL_ENTRY_FROM_VMEXIT \ + ibrs_val=SPEC_CTRL_IBRS), \ + X86_FEATURE_XEN_IBRS_SET, \ +@@ -228,7 +231,7 @@ + #define SPEC_CTRL_ENTRY_FROM_PV \ + ALTERNATIVE __stringify(ASM_NOP40), \ + DO_OVERWRITE_RSB, X86_FEATURE_RSB_NATIVE; \ +- ALTERNATIVE_2 __stringify(ASM_NOP21), \ ++ ALTERNATIVE_2 __stringify(ASM_NOP22), \ + __stringify(DO_SPEC_CTRL_ENTRY maybexen=0 \ + ibrs_val=SPEC_CTRL_IBRS), \ + X86_FEATURE_XEN_IBRS_SET, \ +@@ -239,7 +242,7 @@ + #define SPEC_CTRL_ENTRY_FROM_INTR \ + ALTERNATIVE __stringify(ASM_NOP40), \ + DO_OVERWRITE_RSB, X86_FEATURE_RSB_NATIVE; \ +- ALTERNATIVE_2 __stringify(ASM_NOP29), \ ++ ALTERNATIVE_2 __stringify(ASM_NOP33), \ + __stringify(DO_SPEC_CTRL_ENTRY maybexen=1 \ + ibrs_val=SPEC_CTRL_IBRS), \ + X86_FEATURE_XEN_IBRS_SET, \ +@@ -267,22 +270,23 @@ + * This is logical merge of DO_OVERWRITE_RSB and DO_SPEC_CTRL_ENTRY + * maybexen=1, but with conditionals rather than alternatives. + */ +- movzbl STACK_CPUINFO_FIELD(bti_ist_info)(%r14), %eax ++ movzbl STACK_CPUINFO_FIELD(spec_ctrl_flags)(%r14), %eax + +- testb $BTI_IST_RSB, %al ++ test $SCF_ist_rsb, %al + jz .L\@_skip_rsb + + DO_OVERWRITE_RSB tmp=rdx /* Clobbers %rcx/%rdx */ + + .L\@_skip_rsb: + +- testb $BTI_IST_WRMSR, %al ++ test $SCF_ist_wrmsr, %al + jz .L\@_skip_wrmsr + + xor %edx, %edx + testb $3, UREGS_cs(%rsp) +- setz %dl +- and %dl, STACK_CPUINFO_FIELD(use_shadow_spec_ctrl)(%r14) ++ setnz %dl ++ not %edx ++ and %dl, STACK_CPUINFO_FIELD(spec_ctrl_flags)(%r14) + + /* Load Xen's intended value. */ + mov $MSR_SPEC_CTRL, %ecx +@@ -309,7 +313,7 @@ UNLIKELY_DISPATCH_LABEL(\@_serialise): + * Requires %rbx=stack_end + * Clobbers %rax, %rcx, %rdx + */ +- testb $BTI_IST_WRMSR, STACK_CPUINFO_FIELD(bti_ist_info)(%rbx) ++ testb $SCF_ist_wrmsr, STACK_CPUINFO_FIELD(spec_ctrl_flags)(%rbx) + jz .L\@_skip + + DO_SPEC_CTRL_EXIT_TO_XEN +-- +2.1.4 + diff --git a/main/xen/0004-x86-spec_ctrl-Fold-the-XEN_IBRS_-SET-CLEAR-ALTERNATI.patch b/main/xen/0004-x86-spec_ctrl-Fold-the-XEN_IBRS_-SET-CLEAR-ALTERNATI.patch new file mode 100644 index 0000000000..0741752f15 --- /dev/null +++ b/main/xen/0004-x86-spec_ctrl-Fold-the-XEN_IBRS_-SET-CLEAR-ALTERNATI.patch @@ -0,0 +1,221 @@ +From df0421d0368ba545f37b07c08b13591540227dcc Mon Sep 17 00:00:00 2001 +From: Andrew Cooper <andrew.cooper3@citrix.com> +Date: Tue, 17 Apr 2018 14:15:04 +0100 +Subject: [PATCH] x86/spec_ctrl: Fold the XEN_IBRS_{SET,CLEAR} ALTERNATIVES + together + +Currently, the SPEC_CTRL_{ENTRY,EXIT}_* macros encode Xen's choice of +MSR_SPEC_CTRL as an immediate constant, and chooses between IBRS or not by +doubling up the entire alternative block. + +There is now a variable holding Xen's choice of value, so use that and +simplify the alternatives. + +Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> +Reviewed-by: Wei Liu <wei.liu2@citrix.com> +Reviewed-by: Jan Beulich <jbeulich@suse.com> +Release-acked-by: Juergen Gross <jgross@suse.com> +(cherry picked from commit af949407eaba7af71067f23d5866cd0bf1f1144d) +--- + xen/arch/x86/spec_ctrl.c | 12 +++++----- + xen/include/asm-x86/cpufeatures.h | 3 +-- + xen/include/asm-x86/nops.h | 3 ++- + xen/include/asm-x86/spec_ctrl.h | 6 ++--- + xen/include/asm-x86/spec_ctrl_asm.h | 45 +++++++++++++------------------------ + 5 files changed, 26 insertions(+), 43 deletions(-) + +diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c +index 2d69910..b62cfcc 100644 +--- a/xen/arch/x86/spec_ctrl.c ++++ b/xen/arch/x86/spec_ctrl.c +@@ -112,8 +112,9 @@ static void __init print_details(enum ind_thunk thunk, uint64_t caps) + thunk == THUNK_RETPOLINE ? "RETPOLINE" : + thunk == THUNK_LFENCE ? "LFENCE" : + thunk == THUNK_JMP ? "JMP" : "?", +- boot_cpu_has(X86_FEATURE_XEN_IBRS_SET) ? " IBRS+" : +- boot_cpu_has(X86_FEATURE_XEN_IBRS_CLEAR) ? " IBRS-" : "", ++ boot_cpu_has(X86_FEATURE_SC_MSR) ? ++ default_xen_spec_ctrl & SPEC_CTRL_IBRS ? " IBRS+" : ++ " IBRS-" : "", + opt_ibpb ? " IBPB" : "", + boot_cpu_has(X86_FEATURE_RSB_NATIVE) ? " RSB_NATIVE" : "", + boot_cpu_has(X86_FEATURE_RSB_VMEXIT) ? " RSB_VMEXIT" : ""); +@@ -285,13 +286,10 @@ void __init init_speculation_mitigations(void) + * need the IBRS entry/exit logic to virtualise IBRS support for + * guests. + */ ++ setup_force_cpu_cap(X86_FEATURE_SC_MSR); ++ + if ( ibrs ) +- { + default_xen_spec_ctrl |= SPEC_CTRL_IBRS; +- setup_force_cpu_cap(X86_FEATURE_XEN_IBRS_SET); +- } +- else +- setup_force_cpu_cap(X86_FEATURE_XEN_IBRS_CLEAR); + + default_spec_ctrl_flags |= SCF_ist_wrmsr; + } +diff --git a/xen/include/asm-x86/cpufeatures.h b/xen/include/asm-x86/cpufeatures.h +index 84d5c5b..6119bab 100644 +--- a/xen/include/asm-x86/cpufeatures.h ++++ b/xen/include/asm-x86/cpufeatures.h +@@ -28,8 +28,7 @@ XEN_CPUFEATURE(LFENCE_DISPATCH, (FSCAPINTS+0)*32+14) /* lfence set as Dispatch S + XEN_CPUFEATURE(IND_THUNK_LFENCE,(FSCAPINTS+0)*32+15) /* Use IND_THUNK_LFENCE */ + XEN_CPUFEATURE(IND_THUNK_JMP, (FSCAPINTS+0)*32+16) /* Use IND_THUNK_JMP */ + XEN_CPUFEATURE(XEN_IBPB, (FSCAPINTS+0)*32+17) /* IBRSB || IBPB */ +-XEN_CPUFEATURE(XEN_IBRS_SET, (FSCAPINTS+0)*32+18) /* IBRSB && IRBS set in Xen */ +-XEN_CPUFEATURE(XEN_IBRS_CLEAR, (FSCAPINTS+0)*32+19) /* IBRSB && IBRS clear in Xen */ ++XEN_CPUFEATURE(SC_MSR, (FSCAPINTS+0)*32+18) /* MSR_SPEC_CTRL used by Xen */ + XEN_CPUFEATURE(RSB_NATIVE, (FSCAPINTS+0)*32+20) /* RSB overwrite needed for native */ + XEN_CPUFEATURE(RSB_VMEXIT, (FSCAPINTS+0)*32+21) /* RSB overwrite needed for vmexit */ + XEN_CPUFEATURE(NO_XPTI, (FSCAPINTS+0)*32+22) /* XPTI mitigation not in use */ +diff --git a/xen/include/asm-x86/nops.h b/xen/include/asm-x86/nops.h +index b744895..913e9f0 100644 +--- a/xen/include/asm-x86/nops.h ++++ b/xen/include/asm-x86/nops.h +@@ -62,9 +62,10 @@ + #define ASM_NOP8 _ASM_MK_NOP(K8_NOP8) + + #define ASM_NOP17 ASM_NOP8; ASM_NOP7; ASM_NOP2 +-#define ASM_NOP22 ASM_NOP8; ASM_NOP8; ASM_NOP6 + #define ASM_NOP24 ASM_NOP8; ASM_NOP8; ASM_NOP8 ++#define ASM_NOP25 ASM_NOP8; ASM_NOP8; ASM_NOP7; ASM_NOP2 + #define ASM_NOP33 ASM_NOP8; ASM_NOP8; ASM_NOP8; ASM_NOP7; ASM_NOP2 ++#define ASM_NOP36 ASM_NOP8; ASM_NOP8; ASM_NOP8; ASM_NOP8; ASM_NOP4 + #define ASM_NOP40 ASM_NOP8; ASM_NOP8; ASM_NOP8; ASM_NOP8; ASM_NOP8 + + #define ASM_NOP_MAX 8 +diff --git a/xen/include/asm-x86/spec_ctrl.h b/xen/include/asm-x86/spec_ctrl.h +index 059e291..7d7c42e 100644 +--- a/xen/include/asm-x86/spec_ctrl.h ++++ b/xen/include/asm-x86/spec_ctrl.h +@@ -52,14 +52,14 @@ static always_inline void spec_ctrl_enter_idle(struct cpu_info *info) + barrier(); + info->spec_ctrl_flags |= SCF_use_shadow; + barrier(); +- asm volatile ( ALTERNATIVE(ASM_NOP3, "wrmsr", X86_FEATURE_XEN_IBRS_SET) ++ asm volatile ( ALTERNATIVE(ASM_NOP3, "wrmsr", X86_FEATURE_SC_MSR) + :: "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; ++ uint32_t val = info->xen_spec_ctrl; + + /* + * Disable shadowing before updating the MSR. There are no SMP issues +@@ -67,7 +67,7 @@ static always_inline void spec_ctrl_exit_idle(struct cpu_info *info) + */ + info->spec_ctrl_flags &= ~SCF_use_shadow; + barrier(); +- asm volatile ( ALTERNATIVE(ASM_NOP3, "wrmsr", X86_FEATURE_XEN_IBRS_SET) ++ asm volatile ( ALTERNATIVE(ASM_NOP3, "wrmsr", X86_FEATURE_SC_MSR) + :: "a" (val), "c" (MSR_SPEC_CTRL), "d" (0) : "memory" ); + } + +diff --git a/xen/include/asm-x86/spec_ctrl_asm.h b/xen/include/asm-x86/spec_ctrl_asm.h +index 582403a..941aeb7 100644 +--- a/xen/include/asm-x86/spec_ctrl_asm.h ++++ b/xen/include/asm-x86/spec_ctrl_asm.h +@@ -117,7 +117,7 @@ + mov %\tmp, %rsp /* Restore old %rsp */ + .endm + +-.macro DO_SPEC_CTRL_ENTRY_FROM_VMEXIT ibrs_val:req ++.macro DO_SPEC_CTRL_ENTRY_FROM_VMEXIT + /* + * Requires %rbx=current, %rsp=regs/cpuinfo + * Clobbers %rax, %rcx, %rdx +@@ -137,11 +137,11 @@ + andb $~SCF_use_shadow, CPUINFO_spec_ctrl_flags(%rsp) + + /* Load Xen's intended value. */ +- mov $\ibrs_val, %eax ++ movzbl CPUINFO_xen_spec_ctrl(%rsp), %eax + wrmsr + .endm + +-.macro DO_SPEC_CTRL_ENTRY maybexen:req ibrs_val:req ++.macro DO_SPEC_CTRL_ENTRY maybexen:req + /* + * Requires %rsp=regs (also cpuinfo if !maybexen) + * Requires %r14=stack_end (if maybexen) +@@ -166,12 +166,12 @@ + setnz %al + not %eax + and %al, STACK_CPUINFO_FIELD(spec_ctrl_flags)(%r14) ++ movzbl STACK_CPUINFO_FIELD(xen_spec_ctrl)(%r14), %eax + .else + andb $~SCF_use_shadow, CPUINFO_spec_ctrl_flags(%rsp) ++ movzbl CPUINFO_xen_spec_ctrl(%rsp), %eax + .endif + +- /* Load Xen's intended value. */ +- mov $\ibrs_val, %eax + wrmsr + .endm + +@@ -219,47 +219,32 @@ + #define SPEC_CTRL_ENTRY_FROM_VMEXIT \ + ALTERNATIVE __stringify(ASM_NOP40), \ + DO_OVERWRITE_RSB, X86_FEATURE_RSB_VMEXIT; \ +- ALTERNATIVE_2 __stringify(ASM_NOP33), \ +- __stringify(DO_SPEC_CTRL_ENTRY_FROM_VMEXIT \ +- ibrs_val=SPEC_CTRL_IBRS), \ +- X86_FEATURE_XEN_IBRS_SET, \ +- __stringify(DO_SPEC_CTRL_ENTRY_FROM_VMEXIT \ +- ibrs_val=0), \ +- X86_FEATURE_XEN_IBRS_CLEAR ++ ALTERNATIVE __stringify(ASM_NOP36), \ ++ DO_SPEC_CTRL_ENTRY_FROM_VMEXIT, X86_FEATURE_SC_MSR + + /* Use after an entry from PV context (syscall/sysenter/int80/int82/etc). */ + #define SPEC_CTRL_ENTRY_FROM_PV \ + ALTERNATIVE __stringify(ASM_NOP40), \ + DO_OVERWRITE_RSB, X86_FEATURE_RSB_NATIVE; \ +- ALTERNATIVE_2 __stringify(ASM_NOP22), \ +- __stringify(DO_SPEC_CTRL_ENTRY maybexen=0 \ +- ibrs_val=SPEC_CTRL_IBRS), \ +- X86_FEATURE_XEN_IBRS_SET, \ +- __stringify(DO_SPEC_CTRL_ENTRY maybexen=0 ibrs_val=0), \ +- X86_FEATURE_XEN_IBRS_CLEAR ++ ALTERNATIVE __stringify(ASM_NOP25), \ ++ __stringify(DO_SPEC_CTRL_ENTRY maybexen=0), X86_FEATURE_SC_MSR + + /* Use in interrupt/exception context. May interrupt Xen or PV context. */ + #define SPEC_CTRL_ENTRY_FROM_INTR \ + ALTERNATIVE __stringify(ASM_NOP40), \ + DO_OVERWRITE_RSB, X86_FEATURE_RSB_NATIVE; \ +- ALTERNATIVE_2 __stringify(ASM_NOP33), \ +- __stringify(DO_SPEC_CTRL_ENTRY maybexen=1 \ +- ibrs_val=SPEC_CTRL_IBRS), \ +- X86_FEATURE_XEN_IBRS_SET, \ +- __stringify(DO_SPEC_CTRL_ENTRY maybexen=1 ibrs_val=0), \ +- X86_FEATURE_XEN_IBRS_CLEAR ++ ALTERNATIVE __stringify(ASM_NOP33), \ ++ __stringify(DO_SPEC_CTRL_ENTRY maybexen=1), X86_FEATURE_SC_MSR + + /* Use when exiting to Xen context. */ + #define SPEC_CTRL_EXIT_TO_XEN \ +- ALTERNATIVE_2 __stringify(ASM_NOP17), \ +- DO_SPEC_CTRL_EXIT_TO_XEN, X86_FEATURE_XEN_IBRS_SET, \ +- DO_SPEC_CTRL_EXIT_TO_XEN, X86_FEATURE_XEN_IBRS_CLEAR ++ ALTERNATIVE __stringify(ASM_NOP17), \ ++ DO_SPEC_CTRL_EXIT_TO_XEN, X86_FEATURE_SC_MSR + + /* Use when exiting to guest context. */ + #define SPEC_CTRL_EXIT_TO_GUEST \ +- ALTERNATIVE_2 __stringify(ASM_NOP24), \ +- DO_SPEC_CTRL_EXIT_TO_GUEST, X86_FEATURE_XEN_IBRS_SET, \ +- DO_SPEC_CTRL_EXIT_TO_GUEST, X86_FEATURE_XEN_IBRS_CLEAR ++ ALTERNATIVE __stringify(ASM_NOP24), \ ++ DO_SPEC_CTRL_EXIT_TO_GUEST, X86_FEATURE_SC_MSR + + /* TODO: Drop these when the alternatives infrastructure is NMI/#MC safe. */ + .macro SPEC_CTRL_ENTRY_FROM_INTR_IST +-- +2.1.4 + diff --git a/main/xen/0005-x86-spec_ctrl-Rename-bits-of-infrastructure-to-avoid.patch b/main/xen/0005-x86-spec_ctrl-Rename-bits-of-infrastructure-to-avoid.patch new file mode 100644 index 0000000000..d271bb29fd --- /dev/null +++ b/main/xen/0005-x86-spec_ctrl-Rename-bits-of-infrastructure-to-avoid.patch @@ -0,0 +1,273 @@ +From e00632c06f088bfe4bd110686faa4a7e01a5667b Mon Sep 17 00:00:00 2001 +From: Andrew Cooper <andrew.cooper3@citrix.com> +Date: Mon, 30 Apr 2018 14:20:23 +0100 +Subject: [PATCH] x86/spec_ctrl: Rename bits of infrastructure to avoid NATIVE + and VMEXIT + +In hindsight, using NATIVE and VMEXIT as naming terminology was not clever. +A future change wants to split SPEC_CTRL_EXIT_TO_GUEST into PV and HVM +specific implementations, and using VMEXIT as a term is completely wrong. + +Take the opportunity to fix some stale documentation in spec_ctrl_asm.h. The +IST helpers were missing from the large comment block, and since +SPEC_CTRL_ENTRY_FROM_INTR_IST was introduced, we've gained a new piece of +functionality which currently depends on the fine grain control, which exists +in lieu of livepatching. Note this in the comment. + +No functional change. + +Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> +Reviewed-by: Wei Liu <wei.liu2@citrix.com> +Reviewed-by: Jan Beulich <jbeulich@suse.com> +Release-acked-by: Juergen Gross <jgross@suse.com> +(cherry picked from commit d9822b8a38114e96e4516dc998f4055249364d5d) +--- + xen/arch/x86/hvm/svm/entry.S | 4 ++-- + xen/arch/x86/hvm/vmx/entry.S | 4 ++-- + xen/arch/x86/spec_ctrl.c | 20 ++++++++++---------- + xen/arch/x86/x86_64/compat/entry.S | 2 +- + xen/arch/x86/x86_64/entry.S | 2 +- + xen/include/asm-x86/cpufeatures.h | 4 ++-- + xen/include/asm-x86/spec_ctrl_asm.h | 36 +++++++++++++++++++++++++----------- + 7 files changed, 43 insertions(+), 29 deletions(-) + +diff --git a/xen/arch/x86/hvm/svm/entry.S b/xen/arch/x86/hvm/svm/entry.S +index 7c91595..d0e9171 100644 +--- a/xen/arch/x86/hvm/svm/entry.S ++++ b/xen/arch/x86/hvm/svm/entry.S +@@ -80,7 +80,7 @@ UNLIKELY_END(svm_trace) + mov VCPU_arch_spec_ctrl(%rbx), %eax + + /* WARNING! `ret`, `call *`, `jmp *` not safe beyond this point. */ +- SPEC_CTRL_EXIT_TO_GUEST /* Req: a=spec_ctrl %rsp=regs/cpuinfo, Clob: cd */ ++ SPEC_CTRL_EXIT_TO_HVM /* Req: a=spec_ctrl %rsp=regs/cpuinfo, Clob: cd */ + + pop %r15 + pop %r14 +@@ -105,7 +105,7 @@ UNLIKELY_END(svm_trace) + + GET_CURRENT(bx) + +- SPEC_CTRL_ENTRY_FROM_VMEXIT /* Req: b=curr %rsp=regs/cpuinfo, Clob: acd */ ++ SPEC_CTRL_ENTRY_FROM_HVM /* Req: b=curr %rsp=regs/cpuinfo, Clob: acd */ + /* WARNING! `ret`, `call *`, `jmp *` not safe before this point. */ + + mov VCPU_svm_vmcb(%rbx),%rcx +diff --git a/xen/arch/x86/hvm/vmx/entry.S b/xen/arch/x86/hvm/vmx/entry.S +index f823850..bdcd3ca 100644 +--- a/xen/arch/x86/hvm/vmx/entry.S ++++ b/xen/arch/x86/hvm/vmx/entry.S +@@ -36,7 +36,7 @@ ENTRY(vmx_asm_vmexit_handler) + movb $1,VCPU_vmx_launched(%rbx) + mov %rax,VCPU_hvm_guest_cr2(%rbx) + +- SPEC_CTRL_ENTRY_FROM_VMEXIT /* Req: b=curr %rsp=regs/cpuinfo, Clob: acd */ ++ SPEC_CTRL_ENTRY_FROM_HVM /* Req: b=curr %rsp=regs/cpuinfo, Clob: acd */ + /* WARNING! `ret`, `call *`, `jmp *` not safe before this point. */ + + mov %rsp,%rdi +@@ -71,7 +71,7 @@ UNLIKELY_END(realmode) + mov VCPU_arch_spec_ctrl(%rbx), %eax + + /* WARNING! `ret`, `call *`, `jmp *` not safe beyond this point. */ +- SPEC_CTRL_EXIT_TO_GUEST /* Req: a=spec_ctrl %rsp=regs/cpuinfo, Clob: cd */ ++ SPEC_CTRL_EXIT_TO_HVM /* Req: a=spec_ctrl %rsp=regs/cpuinfo, Clob: cd */ + + mov VCPU_hvm_guest_cr2(%rbx),%rax + +diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c +index b62cfcc..015a9e2 100644 +--- a/xen/arch/x86/spec_ctrl.c ++++ b/xen/arch/x86/spec_ctrl.c +@@ -35,8 +35,8 @@ static enum ind_thunk { + THUNK_JMP, + } opt_thunk __initdata = THUNK_DEFAULT; + static int8_t __initdata opt_ibrs = -1; +-static bool __initdata opt_rsb_native = true; +-static bool __initdata opt_rsb_vmexit = true; ++static bool __initdata opt_rsb_pv = true; ++static bool __initdata opt_rsb_hvm = true; + bool __read_mostly opt_ibpb = true; + uint8_t __read_mostly default_xen_spec_ctrl; + uint8_t __read_mostly default_spec_ctrl_flags; +@@ -69,9 +69,9 @@ static int __init parse_bti(const char *s) + else if ( (val = parse_boolean("ibpb", s, ss)) >= 0 ) + opt_ibpb = val; + else if ( (val = parse_boolean("rsb_native", s, ss)) >= 0 ) +- opt_rsb_native = val; ++ opt_rsb_pv = val; + else if ( (val = parse_boolean("rsb_vmexit", s, ss)) >= 0 ) +- opt_rsb_vmexit = val; ++ opt_rsb_hvm = val; + else + rc = -EINVAL; + +@@ -116,8 +116,8 @@ static void __init print_details(enum ind_thunk thunk, uint64_t caps) + default_xen_spec_ctrl & SPEC_CTRL_IBRS ? " IBRS+" : + " IBRS-" : "", + opt_ibpb ? " IBPB" : "", +- boot_cpu_has(X86_FEATURE_RSB_NATIVE) ? " RSB_NATIVE" : "", +- boot_cpu_has(X86_FEATURE_RSB_VMEXIT) ? " RSB_VMEXIT" : ""); ++ boot_cpu_has(X86_FEATURE_SC_RSB_PV) ? " RSB_NATIVE" : "", ++ boot_cpu_has(X86_FEATURE_SC_RSB_HVM) ? " RSB_VMEXIT" : ""); + + printk("XPTI: %s\n", + boot_cpu_has(X86_FEATURE_NO_XPTI) ? "disabled" : "enabled"); +@@ -307,9 +307,9 @@ void __init init_speculation_mitigations(void) + * If a processors speculates to 32bit PV guest kernel mappings, it is + * speculating in 64bit supervisor mode, and can leak data. + */ +- if ( opt_rsb_native ) ++ if ( opt_rsb_pv ) + { +- setup_force_cpu_cap(X86_FEATURE_RSB_NATIVE); ++ setup_force_cpu_cap(X86_FEATURE_SC_RSB_PV); + default_spec_ctrl_flags |= SCF_ist_rsb; + } + +@@ -317,8 +317,8 @@ void __init init_speculation_mitigations(void) + * HVM guests can always poison the RSB to point at Xen supervisor + * mappings. + */ +- if ( opt_rsb_vmexit ) +- setup_force_cpu_cap(X86_FEATURE_RSB_VMEXIT); ++ if ( opt_rsb_hvm ) ++ setup_force_cpu_cap(X86_FEATURE_SC_RSB_HVM); + + /* Check we have hardware IBPB support before using it... */ + if ( !boot_cpu_has(X86_FEATURE_IBRSB) && !boot_cpu_has(X86_FEATURE_IBPB) ) +diff --git a/xen/arch/x86/x86_64/compat/entry.S b/xen/arch/x86/x86_64/compat/entry.S +index c538643..63cd51f 100644 +--- a/xen/arch/x86/x86_64/compat/entry.S ++++ b/xen/arch/x86/x86_64/compat/entry.S +@@ -163,7 +163,7 @@ ENTRY(compat_restore_all_guest) + mov VCPU_arch_spec_ctrl(%rbx), %eax + + /* WARNING! `ret`, `call *`, `jmp *` not safe beyond this point. */ +- SPEC_CTRL_EXIT_TO_GUEST /* Req: a=spec_ctrl %rsp=regs/cpuinfo, Clob: cd */ ++ SPEC_CTRL_EXIT_TO_PV /* Req: a=spec_ctrl %rsp=regs/cpuinfo, Clob: cd */ + + RESTORE_ALL adj=8 compat=1 + .Lft0: iretq +diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S +index 7004f52..cdf5090 100644 +--- a/xen/arch/x86/x86_64/entry.S ++++ b/xen/arch/x86/x86_64/entry.S +@@ -193,7 +193,7 @@ restore_all_guest: + mov %r15d, %eax + + /* WARNING! `ret`, `call *`, `jmp *` not safe beyond this point. */ +- SPEC_CTRL_EXIT_TO_GUEST /* Req: a=spec_ctrl %rsp=regs/cpuinfo, Clob: cd */ ++ SPEC_CTRL_EXIT_TO_PV /* Req: a=spec_ctrl %rsp=regs/cpuinfo, Clob: cd */ + + RESTORE_ALL + testw $TRAP_syscall,4(%rsp) +diff --git a/xen/include/asm-x86/cpufeatures.h b/xen/include/asm-x86/cpufeatures.h +index 6119bab..1353fe5 100644 +--- a/xen/include/asm-x86/cpufeatures.h ++++ b/xen/include/asm-x86/cpufeatures.h +@@ -29,6 +29,6 @@ XEN_CPUFEATURE(IND_THUNK_LFENCE,(FSCAPINTS+0)*32+15) /* Use IND_THUNK_LFENCE */ + XEN_CPUFEATURE(IND_THUNK_JMP, (FSCAPINTS+0)*32+16) /* Use IND_THUNK_JMP */ + XEN_CPUFEATURE(XEN_IBPB, (FSCAPINTS+0)*32+17) /* IBRSB || IBPB */ + XEN_CPUFEATURE(SC_MSR, (FSCAPINTS+0)*32+18) /* MSR_SPEC_CTRL used by Xen */ +-XEN_CPUFEATURE(RSB_NATIVE, (FSCAPINTS+0)*32+20) /* RSB overwrite needed for native */ +-XEN_CPUFEATURE(RSB_VMEXIT, (FSCAPINTS+0)*32+21) /* RSB overwrite needed for vmexit */ ++XEN_CPUFEATURE(SC_RSB_PV, (FSCAPINTS+0)*32+20) /* RSB overwrite needed for PV */ ++XEN_CPUFEATURE(SC_RSB_HVM, (FSCAPINTS+0)*32+21) /* RSB overwrite needed for HVM */ + XEN_CPUFEATURE(NO_XPTI, (FSCAPINTS+0)*32+22) /* XPTI mitigation not in use */ +diff --git a/xen/include/asm-x86/spec_ctrl_asm.h b/xen/include/asm-x86/spec_ctrl_asm.h +index 941aeb7..b330e20 100644 +--- a/xen/include/asm-x86/spec_ctrl_asm.h ++++ b/xen/include/asm-x86/spec_ctrl_asm.h +@@ -72,11 +72,14 @@ + * + * The following ASM fragments implement this algorithm. See their local + * comments for further details. +- * - SPEC_CTRL_ENTRY_FROM_VMEXIT ++ * - SPEC_CTRL_ENTRY_FROM_HVM + * - SPEC_CTRL_ENTRY_FROM_PV + * - SPEC_CTRL_ENTRY_FROM_INTR ++ * - SPEC_CTRL_ENTRY_FROM_INTR_IST ++ * - SPEC_CTRL_EXIT_TO_XEN_IST + * - SPEC_CTRL_EXIT_TO_XEN +- * - SPEC_CTRL_EXIT_TO_GUEST ++ * - SPEC_CTRL_EXIT_TO_PV ++ * - SPEC_CTRL_EXIT_TO_HVM + */ + + .macro DO_OVERWRITE_RSB tmp=rax +@@ -117,7 +120,7 @@ + mov %\tmp, %rsp /* Restore old %rsp */ + .endm + +-.macro DO_SPEC_CTRL_ENTRY_FROM_VMEXIT ++.macro DO_SPEC_CTRL_ENTRY_FROM_HVM + /* + * Requires %rbx=current, %rsp=regs/cpuinfo + * Clobbers %rax, %rcx, %rdx +@@ -216,23 +219,23 @@ + .endm + + /* Use after a VMEXIT from an HVM guest. */ +-#define SPEC_CTRL_ENTRY_FROM_VMEXIT \ ++#define SPEC_CTRL_ENTRY_FROM_HVM \ + ALTERNATIVE __stringify(ASM_NOP40), \ +- DO_OVERWRITE_RSB, X86_FEATURE_RSB_VMEXIT; \ ++ DO_OVERWRITE_RSB, X86_FEATURE_SC_RSB_HVM; \ + ALTERNATIVE __stringify(ASM_NOP36), \ +- DO_SPEC_CTRL_ENTRY_FROM_VMEXIT, X86_FEATURE_SC_MSR ++ DO_SPEC_CTRL_ENTRY_FROM_HVM, X86_FEATURE_SC_MSR + + /* Use after an entry from PV context (syscall/sysenter/int80/int82/etc). */ + #define SPEC_CTRL_ENTRY_FROM_PV \ + ALTERNATIVE __stringify(ASM_NOP40), \ +- DO_OVERWRITE_RSB, X86_FEATURE_RSB_NATIVE; \ ++ DO_OVERWRITE_RSB, X86_FEATURE_SC_RSB_PV; \ + ALTERNATIVE __stringify(ASM_NOP25), \ + __stringify(DO_SPEC_CTRL_ENTRY maybexen=0), X86_FEATURE_SC_MSR + + /* Use in interrupt/exception context. May interrupt Xen or PV context. */ + #define SPEC_CTRL_ENTRY_FROM_INTR \ + ALTERNATIVE __stringify(ASM_NOP40), \ +- DO_OVERWRITE_RSB, X86_FEATURE_RSB_NATIVE; \ ++ DO_OVERWRITE_RSB, X86_FEATURE_SC_RSB_PV; \ + ALTERNATIVE __stringify(ASM_NOP33), \ + __stringify(DO_SPEC_CTRL_ENTRY maybexen=1), X86_FEATURE_SC_MSR + +@@ -241,12 +244,22 @@ + ALTERNATIVE __stringify(ASM_NOP17), \ + DO_SPEC_CTRL_EXIT_TO_XEN, X86_FEATURE_SC_MSR + +-/* Use when exiting to guest context. */ +-#define SPEC_CTRL_EXIT_TO_GUEST \ ++/* Use when exiting to PV guest context. */ ++#define SPEC_CTRL_EXIT_TO_PV \ + ALTERNATIVE __stringify(ASM_NOP24), \ + DO_SPEC_CTRL_EXIT_TO_GUEST, X86_FEATURE_SC_MSR + +-/* TODO: Drop these when the alternatives infrastructure is NMI/#MC safe. */ ++/* Use when exiting to HVM guest context. */ ++#define SPEC_CTRL_EXIT_TO_HVM \ ++ ALTERNATIVE __stringify(ASM_NOP24), \ ++ DO_SPEC_CTRL_EXIT_TO_GUEST, X86_FEATURE_SC_MSR ++ ++/* ++ * Use in IST interrupt/exception context. May interrupt Xen or PV context. ++ * Fine grain control of SCF_ist_wrmsr is needed for safety in the S3 resume ++ * path to avoid using MSR_SPEC_CTRL before the microcode introducing it has ++ * been reloaded. ++ */ + .macro SPEC_CTRL_ENTRY_FROM_INTR_IST + /* + * Requires %rsp=regs, %r14=stack_end +@@ -293,6 +306,7 @@ UNLIKELY_DISPATCH_LABEL(\@_serialise): + UNLIKELY_END(\@_serialise) + .endm + ++/* Use when exiting to Xen in IST context. */ + .macro SPEC_CTRL_EXIT_TO_XEN_IST + /* + * Requires %rbx=stack_end +-- +2.1.4 + diff --git a/main/xen/0006-x86-spec_ctrl-Elide-MSR_SPEC_CTRL-handling-in-idle-c.patch b/main/xen/0006-x86-spec_ctrl-Elide-MSR_SPEC_CTRL-handling-in-idle-c.patch new file mode 100644 index 0000000000..f771e545d5 --- /dev/null +++ b/main/xen/0006-x86-spec_ctrl-Elide-MSR_SPEC_CTRL-handling-in-idle-c.patch @@ -0,0 +1,71 @@ +From 12dec36f81cdd8aecc5388f983884cbb4e437ce8 Mon Sep 17 00:00:00 2001 +From: Andrew Cooper <andrew.cooper3@citrix.com> +Date: Mon, 7 May 2018 14:06:16 +0100 +Subject: [PATCH] x86/spec_ctrl: Elide MSR_SPEC_CTRL handling in idle context + when possible + +If Xen is virtualising MSR_SPEC_CTRL handling for guests, but using 0 as its +own MSR_SPEC_CTRL value, spec_ctrl_{enter,exit}_idle() need not write to the +MSR. + +Requested-by: Jan Beulich <JBeulich@suse.com> +Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> +Reviewed-by: Wei Liu <wei.liu2@citrix.com> +Reviewed-by: Jan Beulich <jbeulich@suse.com> +Release-acked-by: Juergen Gross <jgross@suse.com> +(cherry picked from commit 94df6e8588e35cc2028ccb3fd2921c6e6360605e) +--- + xen/arch/x86/spec_ctrl.c | 4 ++++ + xen/include/asm-x86/cpufeatures.h | 1 + + xen/include/asm-x86/spec_ctrl.h | 4 ++-- + 3 files changed, 7 insertions(+), 2 deletions(-) + +diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c +index 015a9e2..55ef79f 100644 +--- a/xen/arch/x86/spec_ctrl.c ++++ b/xen/arch/x86/spec_ctrl.c +@@ -327,6 +327,10 @@ void __init init_speculation_mitigations(void) + /* (Re)init BSP state now that default_spec_ctrl_flags has been calculated. */ + init_shadow_spec_ctrl_state(); + ++ /* If Xen is using any MSR_SPEC_CTRL settings, adjust the idle path. */ ++ if ( default_xen_spec_ctrl ) ++ setup_force_cpu_cap(X86_FEATURE_SC_MSR_IDLE); ++ + print_details(thunk, caps); + } + +diff --git a/xen/include/asm-x86/cpufeatures.h b/xen/include/asm-x86/cpufeatures.h +index 1353fe5..f419c36 100644 +--- a/xen/include/asm-x86/cpufeatures.h ++++ b/xen/include/asm-x86/cpufeatures.h +@@ -32,3 +32,4 @@ XEN_CPUFEATURE(SC_MSR, (FSCAPINTS+0)*32+18) /* MSR_SPEC_CTRL used by Xe + XEN_CPUFEATURE(SC_RSB_PV, (FSCAPINTS+0)*32+20) /* RSB overwrite needed for PV */ + XEN_CPUFEATURE(SC_RSB_HVM, (FSCAPINTS+0)*32+21) /* RSB overwrite needed for HVM */ + XEN_CPUFEATURE(NO_XPTI, (FSCAPINTS+0)*32+22) /* XPTI mitigation not in use */ ++XEN_CPUFEATURE(SC_MSR_IDLE, (FSCAPINTS+0)*32+23) /* SC_MSR && default_xen_spec_ctrl */ +diff --git a/xen/include/asm-x86/spec_ctrl.h b/xen/include/asm-x86/spec_ctrl.h +index 7d7c42e..77f92ba 100644 +--- a/xen/include/asm-x86/spec_ctrl.h ++++ b/xen/include/asm-x86/spec_ctrl.h +@@ -52,7 +52,7 @@ static always_inline void spec_ctrl_enter_idle(struct cpu_info *info) + barrier(); + info->spec_ctrl_flags |= SCF_use_shadow; + barrier(); +- asm volatile ( ALTERNATIVE(ASM_NOP3, "wrmsr", X86_FEATURE_SC_MSR) ++ asm volatile ( ALTERNATIVE(ASM_NOP3, "wrmsr", X86_FEATURE_SC_MSR_IDLE) + :: "a" (val), "c" (MSR_SPEC_CTRL), "d" (0) : "memory" ); + } + +@@ -67,7 +67,7 @@ static always_inline void spec_ctrl_exit_idle(struct cpu_info *info) + */ + info->spec_ctrl_flags &= ~SCF_use_shadow; + barrier(); +- asm volatile ( ALTERNATIVE(ASM_NOP3, "wrmsr", X86_FEATURE_SC_MSR) ++ asm volatile ( ALTERNATIVE(ASM_NOP3, "wrmsr", X86_FEATURE_SC_MSR_IDLE) + :: "a" (val), "c" (MSR_SPEC_CTRL), "d" (0) : "memory" ); + } + +-- +2.1.4 + diff --git a/main/xen/0007-x86-spec_ctrl-Split-X86_FEATURE_SC_MSR-into-PV-and-H.patch b/main/xen/0007-x86-spec_ctrl-Split-X86_FEATURE_SC_MSR-into-PV-and-H.patch new file mode 100644 index 0000000000..bd7f9d30ac --- /dev/null +++ b/main/xen/0007-x86-spec_ctrl-Split-X86_FEATURE_SC_MSR-into-PV-and-H.patch @@ -0,0 +1,111 @@ +From 161f6c16d82ed912f6b656c90572ca265a4f0f78 Mon Sep 17 00:00:00 2001 +From: Andrew Cooper <andrew.cooper3@citrix.com> +Date: Tue, 17 Apr 2018 14:15:04 +0100 +Subject: [PATCH] x86/spec_ctrl: Split X86_FEATURE_SC_MSR into PV and HVM + variants + +In order to separately control whether MSR_SPEC_CTRL is virtualised for PV and +HVM guests, split the feature used to control runtime alternatives into two. +Xen will use MSR_SPEC_CTRL itself if either of these features are active. + +Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> +Reviewed-by: Wei Liu <wei.liu2@citrix.com> +Reviewed-by: Jan Beulich <jbeulich@suse.com> +Release-acked-by: Juergen Gross <jgross@suse.com> +(cherry picked from commit fa9eb09d446a1279f5e861e6b84fa8675dabf148) +--- + xen/arch/x86/spec_ctrl.c | 6 ++++-- + xen/include/asm-x86/cpufeatures.h | 5 +++-- + xen/include/asm-x86/spec_ctrl_asm.h | 12 ++++++------ + 3 files changed, 13 insertions(+), 10 deletions(-) + +diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c +index 55ef79f..a940308 100644 +--- a/xen/arch/x86/spec_ctrl.c ++++ b/xen/arch/x86/spec_ctrl.c +@@ -112,7 +112,8 @@ static void __init print_details(enum ind_thunk thunk, uint64_t caps) + thunk == THUNK_RETPOLINE ? "RETPOLINE" : + thunk == THUNK_LFENCE ? "LFENCE" : + thunk == THUNK_JMP ? "JMP" : "?", +- boot_cpu_has(X86_FEATURE_SC_MSR) ? ++ (boot_cpu_has(X86_FEATURE_SC_MSR_PV) || ++ boot_cpu_has(X86_FEATURE_SC_MSR_HVM)) ? + default_xen_spec_ctrl & SPEC_CTRL_IBRS ? " IBRS+" : + " IBRS-" : "", + opt_ibpb ? " IBPB" : "", +@@ -286,7 +287,8 @@ void __init init_speculation_mitigations(void) + * need the IBRS entry/exit logic to virtualise IBRS support for + * guests. + */ +- setup_force_cpu_cap(X86_FEATURE_SC_MSR); ++ setup_force_cpu_cap(X86_FEATURE_SC_MSR_PV); ++ setup_force_cpu_cap(X86_FEATURE_SC_MSR_HVM); + + if ( ibrs ) + default_xen_spec_ctrl |= SPEC_CTRL_IBRS; +diff --git a/xen/include/asm-x86/cpufeatures.h b/xen/include/asm-x86/cpufeatures.h +index f419c36..f568265 100644 +--- a/xen/include/asm-x86/cpufeatures.h ++++ b/xen/include/asm-x86/cpufeatures.h +@@ -28,8 +28,9 @@ XEN_CPUFEATURE(LFENCE_DISPATCH, (FSCAPINTS+0)*32+14) /* lfence set as Dispatch S + XEN_CPUFEATURE(IND_THUNK_LFENCE,(FSCAPINTS+0)*32+15) /* Use IND_THUNK_LFENCE */ + XEN_CPUFEATURE(IND_THUNK_JMP, (FSCAPINTS+0)*32+16) /* Use IND_THUNK_JMP */ + XEN_CPUFEATURE(XEN_IBPB, (FSCAPINTS+0)*32+17) /* IBRSB || IBPB */ +-XEN_CPUFEATURE(SC_MSR, (FSCAPINTS+0)*32+18) /* MSR_SPEC_CTRL used by Xen */ ++XEN_CPUFEATURE(SC_MSR_PV, (FSCAPINTS+0)*32+18) /* MSR_SPEC_CTRL used by Xen for PV */ ++XEN_CPUFEATURE(SC_MSR_HVM, (FSCAPINTS+0)*32+19) /* MSR_SPEC_CTRL used by Xen for HVM */ + XEN_CPUFEATURE(SC_RSB_PV, (FSCAPINTS+0)*32+20) /* RSB overwrite needed for PV */ + XEN_CPUFEATURE(SC_RSB_HVM, (FSCAPINTS+0)*32+21) /* RSB overwrite needed for HVM */ + XEN_CPUFEATURE(NO_XPTI, (FSCAPINTS+0)*32+22) /* XPTI mitigation not in use */ +-XEN_CPUFEATURE(SC_MSR_IDLE, (FSCAPINTS+0)*32+23) /* SC_MSR && default_xen_spec_ctrl */ ++XEN_CPUFEATURE(SC_MSR_IDLE, (FSCAPINTS+0)*32+23) /* (SC_MSR_PV || SC_MSR_HVM) && default_xen_spec_ctrl */ +diff --git a/xen/include/asm-x86/spec_ctrl_asm.h b/xen/include/asm-x86/spec_ctrl_asm.h +index b330e20..4d864eb 100644 +--- a/xen/include/asm-x86/spec_ctrl_asm.h ++++ b/xen/include/asm-x86/spec_ctrl_asm.h +@@ -223,36 +223,36 @@ + ALTERNATIVE __stringify(ASM_NOP40), \ + DO_OVERWRITE_RSB, X86_FEATURE_SC_RSB_HVM; \ + ALTERNATIVE __stringify(ASM_NOP36), \ +- DO_SPEC_CTRL_ENTRY_FROM_HVM, X86_FEATURE_SC_MSR ++ DO_SPEC_CTRL_ENTRY_FROM_HVM, X86_FEATURE_SC_MSR_HVM + + /* Use after an entry from PV context (syscall/sysenter/int80/int82/etc). */ + #define SPEC_CTRL_ENTRY_FROM_PV \ + ALTERNATIVE __stringify(ASM_NOP40), \ + DO_OVERWRITE_RSB, X86_FEATURE_SC_RSB_PV; \ + ALTERNATIVE __stringify(ASM_NOP25), \ +- __stringify(DO_SPEC_CTRL_ENTRY maybexen=0), X86_FEATURE_SC_MSR ++ __stringify(DO_SPEC_CTRL_ENTRY maybexen=0), X86_FEATURE_SC_MSR_PV + + /* Use in interrupt/exception context. May interrupt Xen or PV context. */ + #define SPEC_CTRL_ENTRY_FROM_INTR \ + ALTERNATIVE __stringify(ASM_NOP40), \ + DO_OVERWRITE_RSB, X86_FEATURE_SC_RSB_PV; \ + ALTERNATIVE __stringify(ASM_NOP33), \ +- __stringify(DO_SPEC_CTRL_ENTRY maybexen=1), X86_FEATURE_SC_MSR ++ __stringify(DO_SPEC_CTRL_ENTRY maybexen=1), X86_FEATURE_SC_MSR_PV + + /* Use when exiting to Xen context. */ + #define SPEC_CTRL_EXIT_TO_XEN \ + ALTERNATIVE __stringify(ASM_NOP17), \ +- DO_SPEC_CTRL_EXIT_TO_XEN, X86_FEATURE_SC_MSR ++ DO_SPEC_CTRL_EXIT_TO_XEN, X86_FEATURE_SC_MSR_PV + + /* Use when exiting to PV guest context. */ + #define SPEC_CTRL_EXIT_TO_PV \ + ALTERNATIVE __stringify(ASM_NOP24), \ +- DO_SPEC_CTRL_EXIT_TO_GUEST, X86_FEATURE_SC_MSR ++ DO_SPEC_CTRL_EXIT_TO_GUEST, X86_FEATURE_SC_MSR_PV + + /* Use when exiting to HVM guest context. */ + #define SPEC_CTRL_EXIT_TO_HVM \ + ALTERNATIVE __stringify(ASM_NOP24), \ +- DO_SPEC_CTRL_EXIT_TO_GUEST, X86_FEATURE_SC_MSR ++ DO_SPEC_CTRL_EXIT_TO_GUEST, X86_FEATURE_SC_MSR_HVM + + /* + * Use in IST interrupt/exception context. May interrupt Xen or PV context. +-- +2.1.4 + diff --git a/main/xen/0008-x86-spec_ctrl-Explicitly-set-Xen-s-default-MSR_SPEC_.patch b/main/xen/0008-x86-spec_ctrl-Explicitly-set-Xen-s-default-MSR_SPEC_.patch new file mode 100644 index 0000000000..b6b1d6cd11 --- /dev/null +++ b/main/xen/0008-x86-spec_ctrl-Explicitly-set-Xen-s-default-MSR_SPEC_.patch @@ -0,0 +1,134 @@ +From be34661999a9090bd0dfbf2e47af3c12889a5ccf Mon Sep 17 00:00:00 2001 +From: Andrew Cooper <andrew.cooper3@citrix.com> +Date: Wed, 9 May 2018 13:59:56 +0100 +Subject: [PATCH] x86/spec_ctrl: Explicitly set Xen's default MSR_SPEC_CTRL + value + +With the impending ability to disable MSR_SPEC_CTRL handling on a +per-guest-type basis, the first exit-from-guest may not have the side effect +of loading Xen's choice of value. Explicitly set Xen's default during the BSP +and AP boot paths. + +For the BSP however, delay setting a non-zero MSR_SPEC_CTRL default until +after dom0 has been constructed when safe to do so. Oracle report that this +speeds up boots of some hardware by 50s. + +"when safe to do so" is based on whether we are virtualised. A native boot +won't have any other code running in a position to mount an attack. + +Reported-by: Zhenzhong Duan <zhenzhong.duan@oracle.com> +Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> +Reviewed-by: Wei Liu <wei.liu2@citrix.com> +Reviewed-by: Jan Beulich <jbeulich@suse.com> +Release-acked-by: Juergen Gross <jgross@suse.com> +(cherry picked from commit cb8c12020307b39a89273d7699e89000451987ab) +--- + xen/arch/x86/setup.c | 7 +++++++ + xen/arch/x86/smpboot.c | 8 ++++++++ + xen/arch/x86/spec_ctrl.c | 32 ++++++++++++++++++++++++++++++++ + xen/include/asm-x86/spec_ctrl.h | 2 ++ + 4 files changed, 49 insertions(+) + +diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c +index 29cbe42..bae9ca0 100644 +--- a/xen/arch/x86/setup.c ++++ b/xen/arch/x86/setup.c +@@ -1687,6 +1687,13 @@ void __init noreturn __start_xen(unsigned long mbi_p) + + setup_io_bitmap(dom0); + ++ if ( bsp_delay_spec_ctrl ) ++ { ++ get_cpu_info()->spec_ctrl_flags &= ~SCF_use_shadow; ++ barrier(); ++ wrmsrl(MSR_SPEC_CTRL, default_xen_spec_ctrl); ++ } ++ + /* Jump to the 1:1 virtual mappings of cpu0_stack. */ + asm volatile ("mov %[stk], %%rsp; jmp %c[fn]" :: + [stk] "g" (__va(__pa(get_stack_bottom()))), +diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c +index 3d5faa2..f4a1588 100644 +--- a/xen/arch/x86/smpboot.c ++++ b/xen/arch/x86/smpboot.c +@@ -344,6 +344,14 @@ void start_secondary(void *unused) + else + microcode_resume_cpu(cpu); + ++ /* ++ * If MSR_SPEC_CTRL is available, apply Xen's default setting and discard ++ * any firmware settings. Note: MSR_SPEC_CTRL may only become available ++ * after loading microcode. ++ */ ++ if ( boot_cpu_has(X86_FEATURE_IBRSB) ) ++ wrmsrl(MSR_SPEC_CTRL, default_xen_spec_ctrl); ++ + smp_callin(); + + init_percpu_time(); +diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c +index a940308..3adec1a 100644 +--- a/xen/arch/x86/spec_ctrl.c ++++ b/xen/arch/x86/spec_ctrl.c +@@ -38,6 +38,8 @@ static int8_t __initdata opt_ibrs = -1; + static bool __initdata opt_rsb_pv = true; + static bool __initdata opt_rsb_hvm = true; + bool __read_mostly opt_ibpb = true; ++ ++bool __initdata bsp_delay_spec_ctrl; + uint8_t __read_mostly default_xen_spec_ctrl; + uint8_t __read_mostly default_spec_ctrl_flags; + +@@ -334,6 +336,36 @@ void __init init_speculation_mitigations(void) + setup_force_cpu_cap(X86_FEATURE_SC_MSR_IDLE); + + print_details(thunk, caps); ++ ++ /* ++ * If MSR_SPEC_CTRL is available, apply Xen's default setting and discard ++ * any firmware settings. For performance reasons, when safe to do so, we ++ * delay applying non-zero settings until after dom0 has been constructed. ++ * ++ * "when safe to do so" is based on whether we are virtualised. A native ++ * boot won't have any other code running in a position to mount an ++ * attack. ++ */ ++ if ( boot_cpu_has(X86_FEATURE_IBRSB) ) ++ { ++ bsp_delay_spec_ctrl = !cpu_has_hypervisor && default_xen_spec_ctrl; ++ ++ /* ++ * If delaying MSR_SPEC_CTRL setup, use the same mechanism as ++ * spec_ctrl_enter_idle(), by using a shadow value of zero. ++ */ ++ if ( bsp_delay_spec_ctrl ) ++ { ++ struct cpu_info *info = get_cpu_info(); ++ ++ info->shadow_spec_ctrl = 0; ++ barrier(); ++ info->spec_ctrl_flags |= SCF_use_shadow; ++ barrier(); ++ } ++ ++ wrmsrl(MSR_SPEC_CTRL, bsp_delay_spec_ctrl ? 0 : default_xen_spec_ctrl); ++ } + } + + static void __init __maybe_unused build_assertions(void) +diff --git a/xen/include/asm-x86/spec_ctrl.h b/xen/include/asm-x86/spec_ctrl.h +index 77f92ba..c6a38f4 100644 +--- a/xen/include/asm-x86/spec_ctrl.h ++++ b/xen/include/asm-x86/spec_ctrl.h +@@ -27,6 +27,8 @@ + void init_speculation_mitigations(void); + + extern bool opt_ibpb; ++ ++extern bool bsp_delay_spec_ctrl; + extern uint8_t default_xen_spec_ctrl; + extern uint8_t default_spec_ctrl_flags; + +-- +2.1.4 + diff --git a/main/xen/0009-x86-cpuid-Improvements-to-guest-policies-for-specula.patch b/main/xen/0009-x86-cpuid-Improvements-to-guest-policies-for-specula.patch new file mode 100644 index 0000000000..a07253da98 --- /dev/null +++ b/main/xen/0009-x86-cpuid-Improvements-to-guest-policies-for-specula.patch @@ -0,0 +1,132 @@ +From eea942504afa2b91a3934b8f712758277a0adf00 Mon Sep 17 00:00:00 2001 +From: Andrew Cooper <andrew.cooper3@citrix.com> +Date: Tue, 1 May 2018 11:59:03 +0100 +Subject: [PATCH] x86/cpuid: Improvements to guest policies for speculative + sidechannel features + +If Xen isn't virtualising MSR_SPEC_CTRL for guests, IBRSB shouldn't be +advertised. It is not currently possible to express this via the existing +command line options, but such an ability will be introduced. + +Another useful option in some usecases is to offer IBPB without IBRS. When a +guest kernel is known to be compatible (uses retpoline and knows about the AMD +IBPB feature bit), an administrator with pre-Skylake hardware may wish to hide +IBRS. This allows the VM to have full protection, without Xen or the VM +needing to touch MSR_SPEC_CTRL, which can reduce the overhead of Spectre +mitigations. + +Break the logic common to both PV and HVM CPUID calculations into a common +helper, to avoid duplication. + +Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> +Reviewed-by: Wei Liu <wei.liu2@citrix.com> +Reviewed-by: Jan Beulich <jbeulich@suse.com> +Release-acked-by: Juergen Gross <jgross@suse.com> +(cherry picked from commit cb06b308ec71b23f37a44f5e2351fe2cae0306e9) +--- + xen/arch/x86/cpuid.c | 60 ++++++++++++++++++++++++++++++++-------------------- + 1 file changed, 37 insertions(+), 23 deletions(-) + +diff --git a/xen/arch/x86/cpuid.c b/xen/arch/x86/cpuid.c +index 7f7f6be..ebc1638 100644 +--- a/xen/arch/x86/cpuid.c ++++ b/xen/arch/x86/cpuid.c +@@ -374,6 +374,28 @@ static void __init calculate_host_policy(void) + } + } + ++static void __init guest_common_feature_adjustments(uint32_t *fs) ++{ ++ /* Unconditionally claim to be able to set the hypervisor bit. */ ++ __set_bit(X86_FEATURE_HYPERVISOR, fs); ++ ++ /* ++ * If IBRS is offered to the guest, unconditionally offer STIBP. It is a ++ * nop on non-HT hardware, and has this behaviour to make heterogeneous ++ * setups easier to manage. ++ */ ++ if ( test_bit(X86_FEATURE_IBRSB, fs) ) ++ __set_bit(X86_FEATURE_STIBP, fs); ++ ++ /* ++ * On hardware which supports IBRS/IBPB, we can offer IBPB independently ++ * of IBRS by using the AMD feature bit. An administrator may wish for ++ * performance reasons to offer IBPB without IBRS. ++ */ ++ if ( boot_cpu_has(X86_FEATURE_IBRSB) ) ++ __set_bit(X86_FEATURE_IBPB, fs); ++} ++ + static void __init calculate_pv_max_policy(void) + { + struct cpuid_policy *p = &pv_max_policy; +@@ -386,18 +408,14 @@ static void __init calculate_pv_max_policy(void) + for ( i = 0; i < ARRAY_SIZE(pv_featureset); ++i ) + pv_featureset[i] &= pv_featuremask[i]; + +- /* Unconditionally claim to be able to set the hypervisor bit. */ +- __set_bit(X86_FEATURE_HYPERVISOR, pv_featureset); +- +- /* On hardware with IBRS/IBPB support, there are further adjustments. */ +- if ( test_bit(X86_FEATURE_IBRSB, pv_featureset) ) +- { +- /* Offer STIBP unconditionally. It is a nop on non-HT hardware. */ +- __set_bit(X86_FEATURE_STIBP, pv_featureset); ++ /* ++ * If Xen isn't virtualising MSR_SPEC_CTRL for PV guests because of ++ * administrator choice, hide the feature. ++ */ ++ if ( !boot_cpu_has(X86_FEATURE_SC_MSR_PV) ) ++ __clear_bit(X86_FEATURE_IBRSB, pv_featureset); + +- /* AMD's IBPB is a subset of IBRS/IBPB. */ +- __set_bit(X86_FEATURE_IBPB, pv_featureset); +- } ++ guest_common_feature_adjustments(pv_featureset); + + sanitise_featureset(pv_featureset); + cpuid_featureset_to_policy(pv_featureset, p); +@@ -425,9 +443,6 @@ static void __init calculate_hvm_max_policy(void) + for ( i = 0; i < ARRAY_SIZE(hvm_featureset); ++i ) + hvm_featureset[i] &= hvm_featuremask[i]; + +- /* Unconditionally claim to be able to set the hypervisor bit. */ +- __set_bit(X86_FEATURE_HYPERVISOR, hvm_featureset); +- + /* + * Xen can provide an APIC emulation to HVM guests even if the host's APIC + * isn't enabled. +@@ -443,6 +458,13 @@ static void __init calculate_hvm_max_policy(void) + __set_bit(X86_FEATURE_SEP, hvm_featureset); + + /* ++ * If Xen isn't virtualising MSR_SPEC_CTRL for HVM guests because of ++ * administrator choice, hide the feature. ++ */ ++ if ( !boot_cpu_has(X86_FEATURE_SC_MSR_HVM) ) ++ __clear_bit(X86_FEATURE_IBRSB, hvm_featureset); ++ ++ /* + * With VT-x, some features are only supported by Xen if dedicated + * hardware support is also available. + */ +@@ -455,15 +477,7 @@ static void __init calculate_hvm_max_policy(void) + __clear_bit(X86_FEATURE_XSAVES, hvm_featureset); + } + +- /* On hardware with IBRS/IBPB support, there are further adjustments. */ +- if ( test_bit(X86_FEATURE_IBRSB, hvm_featureset) ) +- { +- /* Offer STIBP unconditionally. It is a nop on non-HT hardware. */ +- __set_bit(X86_FEATURE_STIBP, hvm_featureset); +- +- /* AMD's IBPB is a subset of IBRS/IBPB. */ +- __set_bit(X86_FEATURE_IBPB, hvm_featureset); +- } ++ guest_common_feature_adjustments(hvm_featureset); + + sanitise_featureset(hvm_featureset); + cpuid_featureset_to_policy(hvm_featureset, p); +-- +2.1.4 + diff --git a/main/xen/0010-x86-spec_ctrl-Introduce-a-new-spec-ctrl-command-line.patch b/main/xen/0010-x86-spec_ctrl-Introduce-a-new-spec-ctrl-command-line.patch new file mode 100644 index 0000000000..32e577a443 --- /dev/null +++ b/main/xen/0010-x86-spec_ctrl-Introduce-a-new-spec-ctrl-command-line.patch @@ -0,0 +1,344 @@ +From 128146fcee77e9f27262dda89620f20f7386cd04 Mon Sep 17 00:00:00 2001 +From: Andrew Cooper <andrew.cooper3@citrix.com> +Date: Thu, 26 Apr 2018 10:52:55 +0100 +Subject: [PATCH] x86/spec_ctrl: Introduce a new `spec-ctrl=` command line + argument to replace `bti=` + +In hindsight, the options for `bti=` aren't as flexible or useful as expected +(including several options which don't appear to behave as intended). +Changing the behaviour of an existing option is problematic for compatibility, +so introduce a new `spec-ctrl=` in the hopes that we can do better. + +One common way of deploying Xen is with a single PV dom0 and all domUs being +HVM domains. In such a setup, an administrator who has weighed up the risks +may wish to forgo protection against malicious PV domains, to reduce the +overall performance hit. To cater for this usecase, `spec-ctrl=no-pv` will +disable all speculative protection for PV domains, while leaving all +speculative protection for HVM domains intact. + +For coding clarity as much as anything else, the suboptions are grouped by +logical area; those which affect the alternatives blocks, and those which +affect Xen's in-hypervisor settings. See the xen-command-line.markdown for +full details of the new options. + +While changing the command line options, take the time to change how the data +is reported to the user. The three DEBUG printks are upgraded to unilateral, +as they are all relevant pieces of information, and the old "mitigations:" +line is split in the two logical areas described above. + +Sample output from booting with `spec-ctrl=no-pv` looks like: + + (XEN) Speculative mitigation facilities: + (XEN) Hardware features: IBRS/IBPB STIBP IBPB + (XEN) Compiled-in support: INDIRECT_THUNK + (XEN) Xen settings: BTI-Thunk RETPOLINE, SPEC_CTRL: IBRS-, Other: IBPB + (XEN) Support for VMs: PV: None, HVM: MSR_SPEC_CTRL RSB + (XEN) XPTI (64-bit PV only): Dom0 enabled, DomU enabled + +Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> +Reviewed-by: Wei Liu <wei.liu2@citrix.com> +Reviewed-by: Jan Beulich <jbeulich@suse.com> +Release-acked-by: Juergen Gross <jgross@suse.com> +(cherry picked from commit 3352afc26c497d26ecb70527db3cb29daf7b1422) +--- + docs/misc/xen-command-line.markdown | 49 +++++++++++ + xen/arch/x86/spec_ctrl.c | 160 ++++++++++++++++++++++++++++++------ + 2 files changed, 186 insertions(+), 23 deletions(-) + +diff --git a/docs/misc/xen-command-line.markdown b/docs/misc/xen-command-line.markdown +index dbea91d..cf88419 100644 +--- a/docs/misc/xen-command-line.markdown ++++ b/docs/misc/xen-command-line.markdown +@@ -255,6 +255,9 @@ the NMI watchdog is also enabled. + ### bti (x86) + > `= List of [ thunk=retpoline|lfence|jmp, ibrs=<bool>, ibpb=<bool>, rsb_{vmexit,native}=<bool> ]` + ++**WARNING: This command line option is deprecated, and superseded by ++_spec-ctrl=_ - using both options in combination is undefined.** ++ + Branch Target Injection controls. By default, Xen will pick the most + appropriate BTI mitigations based on compiled in support, loaded microcode, + and hardware details. +@@ -1606,6 +1609,52 @@ enforces the maximum theoretically necessary timeout of 670ms. Any number + is being interpreted as a custom timeout in milliseconds. Zero or boolean + false disable the quirk workaround, which is also the default. + ++### spec-ctrl (x86) ++> `= List of [ <bool>, xen=<bool>, {pv,hvm,msr-sc,rsb}=<bool>, ++> bti-thunk=retpoline|lfence|jmp, {ibrs,ibpb}=<bool> ]` ++ ++Controls for speculative execution sidechannel mitigations. By default, Xen ++will pick the most appropriate mitigations based on compiled in support, ++loaded microcode, and hardware details, and will virtualise appropriate ++mitigations for guests to use. ++ ++**WARNING: Any use of this option may interfere with heuristics. Use with ++extreme care.** ++ ++An overall boolean value, `spec-ctrl=no`, can be specified to turn off all ++mitigations, including pieces of infrastructure used to virtualise certain ++mitigation features for guests. Alternatively, a slightly more restricted ++`spec-ctrl=no-xen` can be used to turn off all of Xen's mitigations, while ++leaving the virtualisation support in place for guests to use. Use of a ++positive boolean value for either of these options is invalid. ++ ++The booleans `pv=`, `hvm=`, `msr-sc=` and `rsb=` offer fine grained control ++over the alternative blocks used by Xen. These impact Xen's ability to ++protect itself, and Xen's ability to virtualise support for guests to use. ++ ++* `pv=` and `hvm=` offer control over all suboptions for PV and HVM guests ++ respectively. ++* `msr-sc=` offers control over Xen's support for manipulating MSR\_SPEC\_CTRL ++ on entry and exit. These blocks are necessary to virtualise support for ++ guests and if disabled, guests will be unable to use IBRS/STIBP/etc. ++* `rsb=` offers control over whether to overwrite the Return Stack Buffer / ++ Return Address Stack on entry to Xen. ++ ++If Xen was compiled with INDIRECT\_THUNK support, `bti-thunk=` can be used to ++select which of the thunks gets patched into the `__x86_indirect_thunk_%reg` ++locations. The default thunk is `retpoline` (generally preferred for Intel ++hardware), with the alternatives being `jmp` (a `jmp *%reg` gadget, minimal ++overhead), and `lfence` (an `lfence; jmp *%reg` gadget, preferred for AMD). ++ ++On hardware supporting IBRS (Indirect Branch Restricted Speculation), the ++`ibrs=` option can be used to force or prevent Xen using the feature itself. ++If Xen is not using IBRS itself, functionality is still set up so IBRS can be ++virtualised for guests. ++ ++On hardware supporting IBPB (Indirect Branch Prediction Barrier), the `ibpb=` ++option can be used to force (the default) or prevent Xen from issuing branch ++prediction barriers on vcpu context switches. ++ + ### sync\_console + > `= <boolean>` + +diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c +index 3adec1a..1a59b54 100644 +--- a/xen/arch/x86/spec_ctrl.c ++++ b/xen/arch/x86/spec_ctrl.c +@@ -26,6 +26,13 @@ + #include <asm/spec_ctrl.h> + #include <asm/spec_ctrl_asm.h> + ++/* Cmdline controls for Xen's alternative blocks. */ ++static bool __initdata opt_msr_sc_pv = true; ++static bool __initdata opt_msr_sc_hvm = true; ++static bool __initdata opt_rsb_pv = true; ++static bool __initdata opt_rsb_hvm = true; ++ ++/* Cmdline controls for Xen's speculative settings. */ + static enum ind_thunk { + THUNK_DEFAULT, /* Decide which thunk to use at boot time. */ + THUNK_NONE, /* Missing compiler support for thunks. */ +@@ -35,8 +42,6 @@ static enum ind_thunk { + THUNK_JMP, + } opt_thunk __initdata = THUNK_DEFAULT; + static int8_t __initdata opt_ibrs = -1; +-static bool __initdata opt_rsb_pv = true; +-static bool __initdata opt_rsb_hvm = true; + bool __read_mostly opt_ibpb = true; + + bool __initdata bsp_delay_spec_ctrl; +@@ -84,8 +89,95 @@ static int __init parse_bti(const char *s) + } + custom_param("bti", parse_bti); + ++static int __init parse_spec_ctrl(const char *s) ++{ ++ const char *ss; ++ int val, rc = 0; ++ ++ do { ++ ss = strchr(s, ','); ++ if ( !ss ) ++ ss = strchr(s, '\0'); ++ ++ /* Global and Xen-wide disable. */ ++ val = parse_bool(s); ++ if ( !val ) ++ { ++ opt_msr_sc_pv = false; ++ opt_msr_sc_hvm = false; ++ ++ disable_common: ++ opt_rsb_pv = false; ++ opt_rsb_hvm = false; ++ ++ opt_thunk = THUNK_JMP; ++ opt_ibrs = 0; ++ opt_ibpb = false; ++ } ++ else if ( val > 0 ) ++ rc = -EINVAL; ++ else if ( (val = parse_boolean("xen", s, ss)) >= 0 ) ++ { ++ if ( !val ) ++ goto disable_common; ++ ++ rc = -EINVAL; ++ } ++ ++ /* Xen's alternative blocks. */ ++ else if ( (val = parse_boolean("pv", s, ss)) >= 0 ) ++ { ++ opt_msr_sc_pv = val; ++ opt_rsb_pv = val; ++ } ++ else if ( (val = parse_boolean("hvm", s, ss)) >= 0 ) ++ { ++ opt_msr_sc_hvm = val; ++ opt_rsb_hvm = val; ++ } ++ else if ( (val = parse_boolean("msr-sc", s, ss)) >= 0 ) ++ { ++ opt_msr_sc_pv = val; ++ opt_msr_sc_hvm = val; ++ } ++ else if ( (val = parse_boolean("rsb", s, ss)) >= 0 ) ++ { ++ opt_rsb_pv = val; ++ opt_rsb_hvm = val; ++ } ++ ++ /* Xen's speculative sidechannel mitigation settings. */ ++ else if ( !strncmp(s, "bti-thunk=", 10) ) ++ { ++ s += 10; ++ ++ if ( !strncmp(s, "retpoline", ss - s) ) ++ opt_thunk = THUNK_RETPOLINE; ++ else if ( !strncmp(s, "lfence", ss - s) ) ++ opt_thunk = THUNK_LFENCE; ++ else if ( !strncmp(s, "jmp", ss - s) ) ++ opt_thunk = THUNK_JMP; ++ else ++ rc = -EINVAL; ++ } ++ else if ( (val = parse_boolean("ibrs", s, ss)) >= 0 ) ++ opt_ibrs = val; ++ else if ( (val = parse_boolean("ibpb", s, ss)) >= 0 ) ++ opt_ibpb = val; ++ else ++ rc = -EINVAL; ++ ++ s = ss + 1; ++ } while ( *ss ); ++ ++ return rc; ++} ++custom_param("spec-ctrl", parse_spec_ctrl); ++ + static void __init print_details(enum ind_thunk thunk, uint64_t caps) + { ++ bool use_spec_ctrl = (boot_cpu_has(X86_FEATURE_SC_MSR_PV) || ++ boot_cpu_has(X86_FEATURE_SC_MSR_HVM)); + unsigned int _7d0 = 0, e8b = 0, tmp; + + /* Collect diagnostics about available mitigations. */ +@@ -94,10 +186,10 @@ static void __init print_details(enum ind_thunk thunk, uint64_t caps) + if ( boot_cpu_data.extended_cpuid_level >= 0x80000008 ) + cpuid(0x80000008, &tmp, &e8b, &tmp, &tmp); + +- printk(XENLOG_DEBUG "Speculative mitigation facilities:\n"); ++ printk("Speculative mitigation facilities:\n"); + + /* Hardware features which pertain to speculative mitigations. */ +- printk(XENLOG_DEBUG " Hardware features:%s%s%s%s%s%s\n", ++ printk(" Hardware features:%s%s%s%s%s%s\n", + (_7d0 & cpufeat_mask(X86_FEATURE_IBRSB)) ? " IBRS/IBPB" : "", + (_7d0 & cpufeat_mask(X86_FEATURE_STIBP)) ? " STIBP" : "", + (e8b & cpufeat_mask(X86_FEATURE_IBPB)) ? " IBPB" : "", +@@ -107,20 +199,31 @@ static void __init print_details(enum ind_thunk thunk, uint64_t caps) + + /* Compiled-in support which pertains to BTI mitigations. */ + if ( IS_ENABLED(CONFIG_INDIRECT_THUNK) ) +- printk(XENLOG_DEBUG " Compiled-in support: INDIRECT_THUNK\n"); ++ printk(" Compiled-in support: INDIRECT_THUNK\n"); + +- printk("BTI mitigations: Thunk %s, Others:%s%s%s%s\n", ++ /* Settings for Xen's protection, irrespective of guests. */ ++ printk(" Xen settings: BTI-Thunk %s, SPEC_CTRL: %s, Other:%s\n", + thunk == THUNK_NONE ? "N/A" : + thunk == THUNK_RETPOLINE ? "RETPOLINE" : + thunk == THUNK_LFENCE ? "LFENCE" : + thunk == THUNK_JMP ? "JMP" : "?", ++ !use_spec_ctrl ? "No" : ++ (default_xen_spec_ctrl & SPEC_CTRL_IBRS) ? "IBRS+" : "IBRS-", ++ opt_ibpb ? " IBPB" : ""); ++ ++ /* ++ * Alternatives blocks for protecting against and/or virtualising ++ * mitigation support for guests. ++ */ ++ printk(" Support for VMs: PV:%s%s%s, HVM:%s%s%s\n", + (boot_cpu_has(X86_FEATURE_SC_MSR_PV) || +- boot_cpu_has(X86_FEATURE_SC_MSR_HVM)) ? +- default_xen_spec_ctrl & SPEC_CTRL_IBRS ? " IBRS+" : +- " IBRS-" : "", +- opt_ibpb ? " IBPB" : "", +- boot_cpu_has(X86_FEATURE_SC_RSB_PV) ? " RSB_NATIVE" : "", +- boot_cpu_has(X86_FEATURE_SC_RSB_HVM) ? " RSB_VMEXIT" : ""); ++ boot_cpu_has(X86_FEATURE_SC_RSB_PV)) ? "" : " None", ++ boot_cpu_has(X86_FEATURE_SC_MSR_PV) ? " MSR_SPEC_CTRL" : "", ++ boot_cpu_has(X86_FEATURE_SC_RSB_PV) ? " RSB" : "", ++ (boot_cpu_has(X86_FEATURE_SC_MSR_HVM) || ++ boot_cpu_has(X86_FEATURE_SC_RSB_HVM)) ? "" : " None", ++ boot_cpu_has(X86_FEATURE_SC_MSR_HVM) ? " MSR_SPEC_CTRL" : "", ++ boot_cpu_has(X86_FEATURE_SC_RSB_HVM) ? " RSB" : ""); + + printk("XPTI: %s\n", + boot_cpu_has(X86_FEATURE_NO_XPTI) ? "disabled" : "enabled"); +@@ -212,7 +315,7 @@ static bool __init retpoline_safe(uint64_t caps) + void __init init_speculation_mitigations(void) + { + enum ind_thunk thunk = THUNK_DEFAULT; +- bool ibrs = false; ++ bool use_spec_ctrl = false, ibrs = false; + uint64_t caps = 0; + + if ( boot_cpu_has(X86_FEATURE_ARCH_CAPS) ) +@@ -282,20 +385,31 @@ void __init init_speculation_mitigations(void) + else if ( thunk == THUNK_JMP ) + setup_force_cpu_cap(X86_FEATURE_IND_THUNK_JMP); + ++ /* ++ * If we are on hardware supporting MSR_SPEC_CTRL, see about setting up ++ * the alternatives blocks so we can virtualise support for guests. ++ */ + if ( boot_cpu_has(X86_FEATURE_IBRSB) ) + { +- /* +- * Even if we've chosen to not have IBRS set in Xen context, we still +- * need the IBRS entry/exit logic to virtualise IBRS support for +- * guests. +- */ +- setup_force_cpu_cap(X86_FEATURE_SC_MSR_PV); +- setup_force_cpu_cap(X86_FEATURE_SC_MSR_HVM); ++ if ( opt_msr_sc_pv ) ++ { ++ use_spec_ctrl = true; ++ setup_force_cpu_cap(X86_FEATURE_SC_MSR_PV); ++ } + +- if ( ibrs ) +- default_xen_spec_ctrl |= SPEC_CTRL_IBRS; ++ if ( opt_msr_sc_hvm ) ++ { ++ use_spec_ctrl = true; ++ setup_force_cpu_cap(X86_FEATURE_SC_MSR_HVM); ++ } ++ ++ if ( use_spec_ctrl ) ++ { ++ if ( ibrs ) ++ default_xen_spec_ctrl |= SPEC_CTRL_IBRS; + +- default_spec_ctrl_flags |= SCF_ist_wrmsr; ++ default_spec_ctrl_flags |= SCF_ist_wrmsr; ++ } + } + + /* +-- +2.1.4 + diff --git a/main/xen/0011-x86-AMD-Mitigations-for-GPZ-SP4-Speculative-Store-By.patch b/main/xen/0011-x86-AMD-Mitigations-for-GPZ-SP4-Speculative-Store-By.patch new file mode 100644 index 0000000000..6fb9af98b5 --- /dev/null +++ b/main/xen/0011-x86-AMD-Mitigations-for-GPZ-SP4-Speculative-Store-By.patch @@ -0,0 +1,123 @@ +From 21c05fe06fb62aea7f29d4d216b8ab623754ae98 Mon Sep 17 00:00:00 2001 +From: Andrew Cooper <andrew.cooper3@citrix.com> +Date: Thu, 26 Apr 2018 10:56:28 +0100 +Subject: [PATCH] x86/AMD: Mitigations for GPZ SP4 - Speculative Store Bypass + +AMD processors will execute loads and stores with the same base register in +program order, which is typically how a compiler emits code. + +Therefore, by default no mitigating actions are taken, despite there being +corner cases which are vulnerable to the issue. + +For performance testing, or for users with particularly sensitive workloads, +the `spec-ctrl=ssbd` command line option is available to force Xen to disable +Memory Disambiguation on applicable hardware. + +Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> +Reviewed-by: Jan Beulich <jbeulich@suse.com> +--- + docs/misc/xen-command-line.markdown | 7 ++++++- + xen/arch/x86/cpu/amd.c | 20 ++++++++++++++++++++ + xen/arch/x86/spec_ctrl.c | 3 +++ + xen/include/asm-x86/spec_ctrl.h | 1 + + 4 files changed, 30 insertions(+), 1 deletion(-) + +diff --git a/docs/misc/xen-command-line.markdown b/docs/misc/xen-command-line.markdown +index cf88419..e2b363f 100644 +--- a/docs/misc/xen-command-line.markdown ++++ b/docs/misc/xen-command-line.markdown +@@ -1611,7 +1611,7 @@ false disable the quirk workaround, which is also the default. + + ### spec-ctrl (x86) + > `= List of [ <bool>, xen=<bool>, {pv,hvm,msr-sc,rsb}=<bool>, +-> bti-thunk=retpoline|lfence|jmp, {ibrs,ibpb}=<bool> ]` ++> bti-thunk=retpoline|lfence|jmp, {ibrs,ibpb,ssbd}=<bool> ]` + + Controls for speculative execution sidechannel mitigations. By default, Xen + will pick the most appropriate mitigations based on compiled in support, +@@ -1655,6 +1655,11 @@ On hardware supporting IBPB (Indirect Branch Prediction Barrier), the `ibpb=` + option can be used to force (the default) or prevent Xen from issuing branch + prediction barriers on vcpu context switches. + ++On hardware supporting SSBD (Speculative Store Bypass Disable), the `ssbd=` ++option can be used to force or prevent Xen using the feature itself. On AMD ++hardware, this is a global option applied at boot, and not virtualised for ++guest use. ++ + ### sync\_console + > `= <boolean>` + +diff --git a/xen/arch/x86/cpu/amd.c b/xen/arch/x86/cpu/amd.c +index 40c0bac..e4fea60 100644 +--- a/xen/arch/x86/cpu/amd.c ++++ b/xen/arch/x86/cpu/amd.c +@@ -9,6 +9,7 @@ + #include <asm/amd.h> + #include <asm/hvm/support.h> + #include <asm/setup.h> /* amd_init_cpu */ ++#include <asm/spec_ctrl.h> + #include <asm/acpi.h> + #include <asm/apic.h> + +@@ -590,6 +591,25 @@ static void init_amd(struct cpuinfo_x86 *c) + c->x86_capability); + } + ++ /* ++ * If the user has explicitly chosen to disable Memory Disambiguation ++ * to mitigiate Speculative Store Bypass, poke the appropriate MSR. ++ */ ++ if (opt_ssbd) { ++ int bit = -1; ++ ++ switch (c->x86) { ++ case 0x15: bit = 54; break; ++ case 0x16: bit = 33; break; ++ case 0x17: bit = 10; break; ++ } ++ ++ if (bit >= 0 && !rdmsr_safe(MSR_AMD64_LS_CFG, value)) { ++ value |= 1ull << bit; ++ wrmsr_safe(MSR_AMD64_LS_CFG, value); ++ } ++ } ++ + /* MFENCE stops RDTSC speculation */ + if (!cpu_has_lfence_dispatch) + __set_bit(X86_FEATURE_MFENCE_RDTSC, c->x86_capability); +diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c +index 1a59b54..0fb628b 100644 +--- a/xen/arch/x86/spec_ctrl.c ++++ b/xen/arch/x86/spec_ctrl.c +@@ -43,6 +43,7 @@ static enum ind_thunk { + } opt_thunk __initdata = THUNK_DEFAULT; + static int8_t __initdata opt_ibrs = -1; + bool __read_mostly opt_ibpb = true; ++bool __read_mostly opt_ssbd = false; + + bool __initdata bsp_delay_spec_ctrl; + uint8_t __read_mostly default_xen_spec_ctrl; +@@ -164,6 +165,8 @@ static int __init parse_spec_ctrl(const char *s) + opt_ibrs = val; + else if ( (val = parse_boolean("ibpb", s, ss)) >= 0 ) + opt_ibpb = val; ++ else if ( (val = parse_boolean("ssbd", s, ss)) >= 0 ) ++ opt_ssbd = val; + else + rc = -EINVAL; + +diff --git a/xen/include/asm-x86/spec_ctrl.h b/xen/include/asm-x86/spec_ctrl.h +index c6a38f4..4678a40 100644 +--- a/xen/include/asm-x86/spec_ctrl.h ++++ b/xen/include/asm-x86/spec_ctrl.h +@@ -27,6 +27,7 @@ + void init_speculation_mitigations(void); + + extern bool opt_ibpb; ++extern bool opt_ssbd; + + extern bool bsp_delay_spec_ctrl; + extern uint8_t default_xen_spec_ctrl; +-- +2.1.4 + diff --git a/main/xen/0012-x86-Intel-Mitigations-for-GPZ-SP4-Speculative-Store-.patch b/main/xen/0012-x86-Intel-Mitigations-for-GPZ-SP4-Speculative-Store-.patch new file mode 100644 index 0000000000..b332cd14bc --- /dev/null +++ b/main/xen/0012-x86-Intel-Mitigations-for-GPZ-SP4-Speculative-Store-.patch @@ -0,0 +1,224 @@ +From 55325566b3a14167501fd0cb045d6343b17b6946 Mon Sep 17 00:00:00 2001 +From: Andrew Cooper <andrew.cooper3@citrix.com> +Date: Wed, 28 Mar 2018 15:21:39 +0100 +Subject: [PATCH] x86/Intel: Mitigations for GPZ SP4 - Speculative Store Bypass + +To combat GPZ SP4 "Speculative Store Bypass", Intel have extended their +speculative sidechannel mitigations specification as follows: + + * A feature bit to indicate that Speculative Store Bypass Disable is + supported. + * A new bit in MSR_SPEC_CTRL which, when set, disables memory disambiguation + in the pipeline. + * A new bit in MSR_ARCH_CAPABILITIES, which will be set in future hardware, + indicating that the hardware is not susceptible to Speculative Store Bypass + sidechannels. + +For contemporary processors, this interface will be implemented via a +microcode update. + +Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> +Reviewed-by: Jan Beulich <jbeulich@suse.com> +--- + docs/misc/xen-command-line.markdown | 12 +++++++----- + tools/libxl/libxl_cpuid.c | 1 + + tools/misc/xen-cpuid.c | 3 +-- + xen/arch/x86/cpuid.c | 5 +++++ + xen/arch/x86/spec_ctrl.c | 15 ++++++++++++--- + xen/include/asm-x86/msr-index.h | 2 ++ + xen/include/public/arch-x86/cpufeatureset.h | 1 + + xen/tools/gen-cpuid.py | 17 +++++++++++++---- + 8 files changed, 42 insertions(+), 14 deletions(-) + +diff --git a/docs/misc/xen-command-line.markdown b/docs/misc/xen-command-line.markdown +index e2b363f..4b8e4b6 100644 +--- a/docs/misc/xen-command-line.markdown ++++ b/docs/misc/xen-command-line.markdown +@@ -456,9 +456,10 @@ accounting for hardware capabilities as enumerated via CPUID. + + Currently accepted: + +-The Speculation Control hardware features `ibrsb`, `stibp`, `ibpb` are used by +-default if avaiable. They can be ignored, e.g. `no-ibrsb`, at which point Xen +-won't use them itself, and won't offer them to guests. ++The Speculation Control hardware features `ibrsb`, `stibp`, `ibpb`, `ssbd` are ++used by default if available and applicable. They can be ignored, ++e.g. `no-ibrsb`, at which point Xen won't use them itself, and won't offer ++them to guests. + + ### cpuid\_mask\_cpu (AMD only) + > `= fam_0f_rev_c | fam_0f_rev_d | fam_0f_rev_e | fam_0f_rev_f | fam_0f_rev_g | fam_10_rev_b | fam_10_rev_c | fam_11_rev_b` +@@ -1636,7 +1637,7 @@ protect itself, and Xen's ability to virtualise support for guests to use. + respectively. + * `msr-sc=` offers control over Xen's support for manipulating MSR\_SPEC\_CTRL + on entry and exit. These blocks are necessary to virtualise support for +- guests and if disabled, guests will be unable to use IBRS/STIBP/etc. ++ guests and if disabled, guests will be unable to use IBRS/STIBP/SSBD/etc. + * `rsb=` offers control over whether to overwrite the Return Stack Buffer / + Return Address Stack on entry to Xen. + +@@ -1658,7 +1659,8 @@ prediction barriers on vcpu context switches. + On hardware supporting SSBD (Speculative Store Bypass Disable), the `ssbd=` + option can be used to force or prevent Xen using the feature itself. On AMD + hardware, this is a global option applied at boot, and not virtualised for +-guest use. ++guest use. On Intel hardware, the feature is virtualised for guests, ++independently of Xen's choice of setting. + + ### sync\_console + > `= <boolean>` +diff --git a/tools/libxl/libxl_cpuid.c b/tools/libxl/libxl_cpuid.c +index 3c00bb5..b426898 100644 +--- a/tools/libxl/libxl_cpuid.c ++++ b/tools/libxl/libxl_cpuid.c +@@ -161,6 +161,7 @@ int libxl_cpuid_parse_config(libxl_cpuid_policy_list *cpuid, const char* str) + {"ibrsb", 0x00000007, 0, CPUID_REG_EDX, 26, 1}, + {"stibp", 0x00000007, 0, CPUID_REG_EDX, 27, 1}, + {"arch-caps", 0x00000007, 0, CPUID_REG_EDX, 29, 1}, ++ {"ssbd", 0x00000007, 0, CPUID_REG_EDX, 31, 1}, + {"topoext", 0x80000001, NA, CPUID_REG_ECX, 22, 1}, + {"tbm", 0x80000001, NA, CPUID_REG_ECX, 21, 1}, + {"nodeid", 0x80000001, NA, CPUID_REG_ECX, 19, 1}, +diff --git a/tools/misc/xen-cpuid.c b/tools/misc/xen-cpuid.c +index 24800fd..9739265 100644 +--- a/tools/misc/xen-cpuid.c ++++ b/tools/misc/xen-cpuid.c +@@ -161,8 +161,7 @@ static const char *str_7d0[32] = + + [26] = "ibrsb", [27] = "stibp", + [28] = "REZ", [29] = "arch_caps", +- +- [30 ... 31] = "REZ", ++ [30] = "REZ", [31] = "ssbd", + }; + + static struct { +diff --git a/xen/arch/x86/cpuid.c b/xen/arch/x86/cpuid.c +index ebc1638..83348b5 100644 +--- a/xen/arch/x86/cpuid.c ++++ b/xen/arch/x86/cpuid.c +@@ -43,6 +43,11 @@ static int __init parse_xen_cpuid(const char *s) + if ( !val ) + setup_clear_cpu_cap(X86_FEATURE_STIBP); + } ++ else if ( (val = parse_boolean("ssbd", s, ss)) >= 0 ) ++ { ++ if ( !val ) ++ setup_clear_cpu_cap(X86_FEATURE_SSBD); ++ } + else + rc = -EINVAL; + +diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c +index 0fb628b..18515eb 100644 +--- a/xen/arch/x86/spec_ctrl.c ++++ b/xen/arch/x86/spec_ctrl.c +@@ -192,26 +192,31 @@ static void __init print_details(enum ind_thunk thunk, uint64_t caps) + printk("Speculative mitigation facilities:\n"); + + /* Hardware features which pertain to speculative mitigations. */ +- printk(" Hardware features:%s%s%s%s%s%s\n", ++ printk(" Hardware features:%s%s%s%s%s%s%s%s\n", + (_7d0 & cpufeat_mask(X86_FEATURE_IBRSB)) ? " IBRS/IBPB" : "", + (_7d0 & cpufeat_mask(X86_FEATURE_STIBP)) ? " STIBP" : "", ++ (_7d0 & cpufeat_mask(X86_FEATURE_SSBD)) ? " SSBD" : "", + (e8b & cpufeat_mask(X86_FEATURE_IBPB)) ? " IBPB" : "", + (caps & ARCH_CAPABILITIES_IBRS_ALL) ? " IBRS_ALL" : "", + (caps & ARCH_CAPABILITIES_RDCL_NO) ? " RDCL_NO" : "", +- (caps & ARCH_CAPS_RSBA) ? " RSBA" : ""); ++ (caps & ARCH_CAPS_RSBA) ? " RSBA" : "", ++ (caps & ARCH_CAPS_SSB_NO) ? " SSB_NO" : ""); + + /* Compiled-in support which pertains to BTI mitigations. */ + if ( IS_ENABLED(CONFIG_INDIRECT_THUNK) ) + printk(" Compiled-in support: INDIRECT_THUNK\n"); + + /* Settings for Xen's protection, irrespective of guests. */ +- printk(" Xen settings: BTI-Thunk %s, SPEC_CTRL: %s, Other:%s\n", ++ printk(" Xen settings: BTI-Thunk %s, SPEC_CTRL: %s%s, Other:%s\n", + thunk == THUNK_NONE ? "N/A" : + thunk == THUNK_RETPOLINE ? "RETPOLINE" : + thunk == THUNK_LFENCE ? "LFENCE" : + thunk == THUNK_JMP ? "JMP" : "?", + !use_spec_ctrl ? "No" : + (default_xen_spec_ctrl & SPEC_CTRL_IBRS) ? "IBRS+" : "IBRS-", ++ !use_spec_ctrl || !boot_cpu_has(X86_FEATURE_SSBD) ++ ? "" : ++ (default_xen_spec_ctrl & SPEC_CTRL_SSBD) ? " SSBD+" : " SSBD-", + opt_ibpb ? " IBPB" : ""); + + /* +@@ -415,6 +420,10 @@ void __init init_speculation_mitigations(void) + } + } + ++ /* If we have SSBD available, see whether we should use it. */ ++ if ( boot_cpu_has(X86_FEATURE_SSBD) && use_spec_ctrl && opt_ssbd ) ++ default_xen_spec_ctrl |= SPEC_CTRL_SSBD; ++ + /* + * PV guests can poison the RSB to any virtual address from which + * they can execute a call instruction. This is necessarily outside +diff --git a/xen/include/asm-x86/msr-index.h b/xen/include/asm-x86/msr-index.h +index 9b0679e..4024ef5 100644 +--- a/xen/include/asm-x86/msr-index.h ++++ b/xen/include/asm-x86/msr-index.h +@@ -38,6 +38,7 @@ + #define MSR_SPEC_CTRL 0x00000048 + #define SPEC_CTRL_IBRS (_AC(1, ULL) << 0) + #define SPEC_CTRL_STIBP (_AC(1, ULL) << 1) ++#define SPEC_CTRL_SSBD (_AC(1, ULL) << 2) + + #define MSR_PRED_CMD 0x00000049 + #define PRED_CMD_IBPB (_AC(1, ULL) << 0) +@@ -46,6 +47,7 @@ + #define ARCH_CAPABILITIES_RDCL_NO (_AC(1, ULL) << 0) + #define ARCH_CAPABILITIES_IBRS_ALL (_AC(1, ULL) << 1) + #define ARCH_CAPS_RSBA (_AC(1, ULL) << 2) ++#define ARCH_CAPS_SSB_NO (_AC(1, ULL) << 4) + + /* Intel MSRs. Some also available on other CPUs */ + #define MSR_IA32_PERFCTR0 0x000000c1 +diff --git a/xen/include/public/arch-x86/cpufeatureset.h b/xen/include/public/arch-x86/cpufeatureset.h +index f4b4c0f..43f42b6 100644 +--- a/xen/include/public/arch-x86/cpufeatureset.h ++++ b/xen/include/public/arch-x86/cpufeatureset.h +@@ -244,6 +244,7 @@ XEN_CPUFEATURE(AVX512_4FMAPS, 9*32+ 3) /*A AVX512 Multiply Accumulation Single + XEN_CPUFEATURE(IBRSB, 9*32+26) /*A IBRS and IBPB support (used by Intel) */ + XEN_CPUFEATURE(STIBP, 9*32+27) /*A! STIBP */ + XEN_CPUFEATURE(ARCH_CAPS, 9*32+29) /* IA32_ARCH_CAPABILITIES MSR */ ++XEN_CPUFEATURE(SSBD, 9*32+31) /* MSR_SPEC_CTRL.SSBD available */ + + #endif /* XEN_CPUFEATURE */ + +diff --git a/xen/tools/gen-cpuid.py b/xen/tools/gen-cpuid.py +index 613b909..65526ff 100755 +--- a/xen/tools/gen-cpuid.py ++++ b/xen/tools/gen-cpuid.py +@@ -257,10 +257,19 @@ def crunch_numbers(state): + AVX512BW, AVX512VL, AVX512VBMI, AVX512_4VNNIW, + AVX512_4FMAPS, AVX512_VPOPCNTDQ], + +- # Single Thread Indirect Branch Predictors enumerates a new bit in the +- # MSR enumerated by Indirect Branch Restricted Speculation/Indirect +- # Branch Prediction Barrier enumeration. +- IBRSB: [STIBP], ++ # The features: ++ # * Single Thread Indirect Branch Predictors ++ # * Speculative Store Bypass Disable ++ # ++ # enumerate new bits in MSR_SPEC_CTRL, which is enumerated by Indirect ++ # Branch Restricted Speculation/Indirect Branch Prediction Barrier. ++ # ++ # In practice, these features also enumerate the presense of ++ # MSR_SPEC_CTRL. However, no real hardware will exist with SSBD but ++ # not IBRSB, and we pass this MSR directly to guests. Treating them ++ # as dependent features simplifies Xen's logic, and prevents the guest ++ # from seeing implausible configurations. ++ IBRSB: [STIBP, SSBD], + } + + deep_features = tuple(sorted(deps.keys())) +-- +2.1.4 + diff --git a/main/xen/0013-x86-msr-Virtualise-MSR_SPEC_CTRL.SSBD-for-guests-to-.patch b/main/xen/0013-x86-msr-Virtualise-MSR_SPEC_CTRL.SSBD-for-guests-to-.patch new file mode 100644 index 0000000000..d444e6b89e --- /dev/null +++ b/main/xen/0013-x86-msr-Virtualise-MSR_SPEC_CTRL.SSBD-for-guests-to-.patch @@ -0,0 +1,75 @@ +From 76da4cf6ec259ffa43b83af75e19cdf289e5731e Mon Sep 17 00:00:00 2001 +From: Andrew Cooper <andrew.cooper3@citrix.com> +Date: Fri, 13 Apr 2018 15:42:34 +0000 +Subject: [PATCH] x86/msr: Virtualise MSR_SPEC_CTRL.SSBD for guests to use + +Almost all infrastructure is already in place. Update the reserved bits +calculation in guest_wrmsr(), and offer SSBD to guests by default. + +Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> +Reviewed-by: Jan Beulich <jbeulich@suse.com> +--- + xen/arch/x86/domctl.c | 3 ++- + xen/arch/x86/hvm/hvm.c | 3 ++- + xen/arch/x86/traps.c | 3 ++- + xen/include/public/arch-x86/cpufeatureset.h | 2 +- + 4 files changed, 7 insertions(+), 4 deletions(-) + +diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c +index 1874949..47b8835 100644 +--- a/xen/arch/x86/domctl.c ++++ b/xen/arch/x86/domctl.c +@@ -1408,7 +1408,8 @@ long arch_do_domctl( + * ignored) when STIBP isn't enumerated in hardware. + */ + +- if ( msr.value & ~(SPEC_CTRL_IBRS | SPEC_CTRL_STIBP) ) ++ if ( msr.value & ~(SPEC_CTRL_IBRS | SPEC_CTRL_STIBP | ++ (d->arch.cpuid->feat.ssbd ? SPEC_CTRL_SSBD : 0)) ) + break; + v->arch.spec_ctrl = msr.value; + continue; +diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c +index 1a47ed9..de47c20 100644 +--- a/xen/arch/x86/hvm/hvm.c ++++ b/xen/arch/x86/hvm/hvm.c +@@ -3619,7 +3619,8 @@ int hvm_msr_write_intercept(unsigned int msr, uint64_t msr_content, + * when STIBP isn't enumerated in hardware. + */ + +- if ( msr_content & ~(SPEC_CTRL_IBRS | SPEC_CTRL_STIBP) ) ++ if ( msr_content & ~(SPEC_CTRL_IBRS | SPEC_CTRL_STIBP | ++ (d->arch.cpuid->feat.ssbd ? SPEC_CTRL_SSBD : 0)) ) + goto gp_fault; /* Rsvd bit set? */ + + v->arch.spec_ctrl = msr_content; +diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c +index b6add03..93b909c 100644 +--- a/xen/arch/x86/traps.c ++++ b/xen/arch/x86/traps.c +@@ -2858,7 +2858,8 @@ static int priv_op_write_msr(unsigned int reg, uint64_t val, + * when STIBP isn't enumerated in hardware. + */ + +- if ( val & ~(SPEC_CTRL_IBRS | SPEC_CTRL_STIBP) ) ++ if ( val & ~(SPEC_CTRL_IBRS | SPEC_CTRL_STIBP | ++ (currd->arch.cpuid->feat.ssbd ? SPEC_CTRL_SSBD : 0)) ) + break; /* Rsvd bit set? */ + + curr->arch.spec_ctrl = val; +diff --git a/xen/include/public/arch-x86/cpufeatureset.h b/xen/include/public/arch-x86/cpufeatureset.h +index 43f42b6..f2baea4 100644 +--- a/xen/include/public/arch-x86/cpufeatureset.h ++++ b/xen/include/public/arch-x86/cpufeatureset.h +@@ -244,7 +244,7 @@ XEN_CPUFEATURE(AVX512_4FMAPS, 9*32+ 3) /*A AVX512 Multiply Accumulation Single + XEN_CPUFEATURE(IBRSB, 9*32+26) /*A IBRS and IBPB support (used by Intel) */ + XEN_CPUFEATURE(STIBP, 9*32+27) /*A! STIBP */ + XEN_CPUFEATURE(ARCH_CAPS, 9*32+29) /* IA32_ARCH_CAPABILITIES MSR */ +-XEN_CPUFEATURE(SSBD, 9*32+31) /* MSR_SPEC_CTRL.SSBD available */ ++XEN_CPUFEATURE(SSBD, 9*32+31) /*A MSR_SPEC_CTRL.SSBD available */ + + #endif /* XEN_CPUFEATURE */ + +-- +2.1.4 + diff --git a/main/xen/APKBUILD b/main/xen/APKBUILD index 9d2334b889..5febfefd5f 100644 --- a/main/xen/APKBUILD +++ b/main/xen/APKBUILD @@ -3,7 +3,7 @@ # Maintainer: William Pitcock <nenolod@dereferenced.org> pkgname=xen pkgver=4.9.2 -pkgrel=2 +pkgrel=3 pkgdesc="Xen hypervisor" url="http://www.xen.org/" arch="x86_64 armhf aarch64" @@ -119,6 +119,9 @@ options="!strip" # - CVE-2018-8897 XSA-260 # - CVE-2018-10982 XSA-261 # - CVE-2018-10981 XSA-262 +# 4.9.2-r3: +# - CVE-2018-3639 XSA-263 +# - CVE-2018-3665 XSA-267 case "$CARCH" in x86*) @@ -194,6 +197,31 @@ source="https://downloads.xenproject.org/release/$pkgname/$pkgver/$pkgname-$pkgv xsa261-4.9.patch xsa262-4.9.patch + x86-log-XPTI-enabled-status.patch + x86-disable-XPTI-when-RDCL_NO.patch + x86-spec_ctrl-Updates-to-retpoline-safety-decision-m.patch + x86-spec_ctrl-Fix-several-bugs-in-SPEC_CTRL_ENTRY_FR.patch + x86-suppress-BTI-mitigations-around-S3-suspend-resum.patch + 0001-x86-spec_ctrl-Read-MSR_ARCH_CAPABILITIES-only-once.patch + 0002-x86-spec_ctrl-Express-Xen-s-choice-of-MSR_SPEC_CTRL-.patch + 0003-x86-spec_ctrl-Merge-bti_ist_info-and-use_shadow_spec.patch + 0004-x86-spec_ctrl-Fold-the-XEN_IBRS_-SET-CLEAR-ALTERNATI.patch + 0005-x86-spec_ctrl-Rename-bits-of-infrastructure-to-avoid.patch + 0006-x86-spec_ctrl-Elide-MSR_SPEC_CTRL-handling-in-idle-c.patch + 0007-x86-spec_ctrl-Split-X86_FEATURE_SC_MSR-into-PV-and-H.patch + 0008-x86-spec_ctrl-Explicitly-set-Xen-s-default-MSR_SPEC_.patch + 0009-x86-cpuid-Improvements-to-guest-policies-for-specula.patch + 0010-x86-spec_ctrl-Introduce-a-new-spec-ctrl-command-line.patch + 0011-x86-AMD-Mitigations-for-GPZ-SP4-Speculative-Store-By.patch + 0012-x86-Intel-Mitigations-for-GPZ-SP4-Speculative-Store-.patch + 0013-x86-msr-Virtualise-MSR_SPEC_CTRL.SSBD-for-guests-to-.patch + + x86-xpti-avoid-copying-L4-page-table-contents-when-p.patch + xen-x86-add-a-function-for-modifying-cr3.patch + xen-x86-support-per-domain-flag-for-xpti.patch + xsa267-4.9-1.patch + xsa267-4.9-2.patch + xenstored.initd xenstored.confd xenconsoled.initd @@ -455,6 +483,29 @@ af38aae378414e88c2553dd61c499a7016e0be9bfc663d134b90fc4fba7eb792c34bfbbc5b52eb19 34ad2d35f20f0be9b88ea93454497bd2e5539b91eac767f885257fef19d304e39bcc1ece5e06475208dafb8ca0cfe9941191ccb580037ae4bdb82b249e09bff9 xsa260-4.patch 78c537f82b759bfbcec9d8e7f06b72501695978735a16d4f1ef71dbf5ea87a1e9b1d7fb9a3a56013e4aada33c1d9cb5de74a3b058946285485db20481a7317e1 xsa261-4.9.patch 05dc19a710290b49ba6dbd1181dd0e69fc9ad524870c008813d22c8b0c2d6af573034e7a44b0b75dd2d112989caf1447b0d6b42d007f1bffc3442828a88ac8f3 xsa262-4.9.patch +a8877fe633ac7e887ee1d6cd970840b93c1befb901855e2f51646390565c1794450c86b90a351309567fa5e7e74454e42823fdbd5f8418a63e0141ee1e265501 x86-log-XPTI-enabled-status.patch +0c70e4365619d0e64eab5a791393b430b90a504bf70f6ad55738e54e0f6de4c0a27068ab97455c3f59fb16792ee8710682faeb887a4a839902dd423836ea6903 x86-disable-XPTI-when-RDCL_NO.patch +54554a9a2c2186a690bb96d0b990f3f149cee58c3fd874721e4712995ff702d8d83fd44c1da3b93ebb63400a50775a2567d4e80908717ef6c97751c37cfa128c x86-spec_ctrl-Updates-to-retpoline-safety-decision-m.patch +1cc28b2d1814bda58ac3d51843d144a5f0245a39615c8dfbd064623177c663053e545017b4a9d6f039a0cd708047555d75021aaf0958b98aa09947aceee72546 x86-spec_ctrl-Fix-several-bugs-in-SPEC_CTRL_ENTRY_FR.patch +af068ac9a2f0fab4e688571a9dc6a16577e87a4758070702b12547a97fed2f77e9a59bc2a64aa5e78f81a275541b73c0f8122d49266236f21901b70b23b53bcc x86-suppress-BTI-mitigations-around-S3-suspend-resum.patch +eb1f291678134d7f22ed23e66bd5af20dad31654d8f3e53b8c8b4a2e3465e4efe058d1850dbed0ceef1c2cb3d82e1abf049087a359c10cd143624627873f5108 0001-x86-spec_ctrl-Read-MSR_ARCH_CAPABILITIES-only-once.patch +2ee96424f55f148ba6b58cdafb5e3a49bbae8418f18363fd2e16b5e617290d962289a687ab711626db7e1ed56e0b5a83c38e321d784d62abed2b1062af1d9978 0002-x86-spec_ctrl-Express-Xen-s-choice-of-MSR_SPEC_CTRL-.patch +7adaff8730355883f113715be2a6a095b889d0168b900a2d68d96d0563a9cd992ff8de5f521e540fabbed739b2f0f1a1105fad20fb9dab5be8b873d48ad33d9c 0003-x86-spec_ctrl-Merge-bti_ist_info-and-use_shadow_spec.patch +b6ce53f8abe92034bd8b051317d5733cfe282622c24f2b6e2c68b58a4b9b64301a6ca715f79323d13b38db3b9fd82db51ca8c5351be089b8f609e1b8399bd1f9 0004-x86-spec_ctrl-Fold-the-XEN_IBRS_-SET-CLEAR-ALTERNATI.patch +ddc70323d755d63c04db34309022900c8d8ae7a5c7b8786bdfae9f7f8432e70452310bd98a05504b05d9fbf107dfe21e9052c44d96ecae2636ee259069659d03 0005-x86-spec_ctrl-Rename-bits-of-infrastructure-to-avoid.patch +96d12a703ea1174b855df88e8734ebae6544ca5a30dcb7a848d94b04ac50e311d2f4fe3f3d4d8f019d4cddf7e4ac56a457e537248f864d2e4dbad712763d5eee 0006-x86-spec_ctrl-Elide-MSR_SPEC_CTRL-handling-in-idle-c.patch +8620bd970c6b7b0de941a39e1a1c521197e05f030225825b7fe9481b4e8e4c29a9a154de3a3cb3d059b3ef9d829300badf60a1d40fdad947bdc54a7ba3347ecc 0007-x86-spec_ctrl-Split-X86_FEATURE_SC_MSR-into-PV-and-H.patch +09afd8e3c67a9b35280be04d7f3988f34738e77e7258682486889777a6ff66f1971c0d9515a8951476ea663fffe3c220149356a26bb23c7a641ee9864a5b703b 0008-x86-spec_ctrl-Explicitly-set-Xen-s-default-MSR_SPEC_.patch +bc775ed9d3c8da2a5451889ef9e800f97cf72b31b18a84dcc634414cbddf1a45da3af5d41b55ccadc716cd0132e16ae33bef8251353ff113747a26f70801f8f5 0009-x86-cpuid-Improvements-to-guest-policies-for-specula.patch +9a3c0a0dba17481fec5215a87dbc689511eead2c22f8927dbd382b978bf4d8f31ff190f4d842505dc1d9bf21a36422b24ac9b1370d7fa6efbcc532815384d56f 0010-x86-spec_ctrl-Introduce-a-new-spec-ctrl-command-line.patch +2bdaad7daccb67180b06dbd6f9c32aca4b4010da6246034018d8fad8a175151a9bcb277c2dcf339c84d7b413360b06652570418e4a740d3cd00ffda8c6169fa3 0011-x86-AMD-Mitigations-for-GPZ-SP4-Speculative-Store-By.patch +6c67220cb20abda6c4c532d8165ef8aa36488acd3fe87b2385c842848e5e185aa77a2d4bebaf1f70ff7cb6cea8e65d87bb347d64e8372c17e3d9baad48316c39 0012-x86-Intel-Mitigations-for-GPZ-SP4-Speculative-Store-.patch +608615226f87e5b5e0aa6575781a24128095b4c90fd24360cb43e94d488f21b375a2eb5ee69f8a5fc3550b7928457b9a622ac8cef59e3febd602674e2dc3b712 0013-x86-msr-Virtualise-MSR_SPEC_CTRL.SSBD-for-guests-to-.patch +4f03e72d0a6a5ecf1ea576a940a13db1a06e7bf0f4a9533428899df7a77515b5ad42b3cbff6c18aff79d7a493f009b99631da292f69ceebe7ad14e1705ddd263 x86-xpti-avoid-copying-L4-page-table-contents-when-p.patch +66460970095e0f23cfec007c1ea477274bd6d72d0cc54eccbfe1ab9c2092a1d46e5eb614dcec055e4d1e97b86572f2a03abaebad029396e9a07efa2870c0a3b8 xen-x86-add-a-function-for-modifying-cr3.patch +24f236c05ea9c779beda10ae30a65e2890598c8fee7bcfc2559d821720928c1c5fbd22b5f3e15b00a663316fddb927203d501b6c6c65ba34f5aac56f351c6387 xen-x86-support-per-domain-flag-for-xpti.patch +d09e4f9253e239276e1480ca222ea980092116cf17b95f70f5ae1f9687cc5f6d17d2173d4bc865a99c7c637d650f4d5ab550055cf5f3af586bb1885e5b16dae6 xsa267-4.9-1.patch +795d4e8daf4f4d0626e8a8e9b35a4484f935d7f15b1b3b63985f8083ef36ff203db52c9dfe453878171d95af0eb9d9c7521f1debd4943ef8a636b89eaa19c71a xsa267-4.9-2.patch 52c43beb2596d645934d0f909f2d21f7587b6898ed5e5e7046799a8ed6d58f7a09c5809e1634fa26152f3fd4f3e7cfa07da7076f01b4a20cc8f5df8b9cb77e50 xenstored.initd 093f7fbd43faf0a16a226486a0776bade5dc1681d281c5946a3191c32d74f9699c6bf5d0ab8de9d1195a2461165d1660788e92a3156c9b3c7054d7b2d52d7ff0 xenstored.confd 3c86ed48fbee0af4051c65c4a3893f131fa66e47bf083caf20c9b6aa4b63fdead8832f84a58d0e27964bc49ec8397251b34e5be5c212c139f556916dc8da9523 xenconsoled.initd diff --git a/main/xen/x86-AMD-Mitigations-for-GPZ-SP4-Speculative-Store-By.patch b/main/xen/x86-AMD-Mitigations-for-GPZ-SP4-Speculative-Store-By.patch new file mode 100644 index 0000000000..f40c148408 --- /dev/null +++ b/main/xen/x86-AMD-Mitigations-for-GPZ-SP4-Speculative-Store-By.patch @@ -0,0 +1,123 @@ +From 1ed34667b1865c645f0404d9b611128aa2773aa3 Mon Sep 17 00:00:00 2001 +From: Andrew Cooper <andrew.cooper3@citrix.com> +Date: Thu, 26 Apr 2018 10:56:28 +0100 +Subject: [PATCH] x86/AMD: Mitigations for GPZ SP4 - Speculative Store Bypass + +AMD processors will execute loads and stores with the same base register in +program order, which is typically how a compiler emits code. + +Therefore, by default no mitigating actions are taken, despite there being +corner cases which are vulnerable to the issue. + +For performance testing, or for users with particularly sensitive workloads, +the `spec-ctrl=ssbd` command line option is available to force Xen to disable +Memory Disambiguation on applicable hardware. + +Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> +Reviewed-by: Jan Beulich <jbeulich@suse.com> +--- + docs/misc/xen-command-line.markdown | 7 ++++++- + xen/arch/x86/cpu/amd.c | 20 ++++++++++++++++++++ + xen/arch/x86/spec_ctrl.c | 3 +++ + xen/include/asm-x86/spec_ctrl.h | 1 + + 4 files changed, 30 insertions(+), 1 deletion(-) + +diff --git a/docs/misc/xen-command-line.markdown b/docs/misc/xen-command-line.markdown +index cf88419f23..e2b363fd0c 100644 +--- a/docs/misc/xen-command-line.markdown ++++ b/docs/misc/xen-command-line.markdown +@@ -1611,7 +1611,7 @@ false disable the quirk workaround, which is also the default. + + ### spec-ctrl (x86) + > `= List of [ <bool>, xen=<bool>, {pv,hvm,msr-sc,rsb}=<bool>, +-> bti-thunk=retpoline|lfence|jmp, {ibrs,ibpb}=<bool> ]` ++> bti-thunk=retpoline|lfence|jmp, {ibrs,ibpb,ssbd}=<bool> ]` + + Controls for speculative execution sidechannel mitigations. By default, Xen + will pick the most appropriate mitigations based on compiled in support, +@@ -1655,6 +1655,11 @@ On hardware supporting IBPB (Indirect Branch Prediction Barrier), the `ibpb=` + option can be used to force (the default) or prevent Xen from issuing branch + prediction barriers on vcpu context switches. + ++On hardware supporting SSBD (Speculative Store Bypass Disable), the `ssbd=` ++option can be used to force or prevent Xen using the feature itself. On AMD ++hardware, this is a global option applied at boot, and not virtualised for ++guest use. ++ + ### sync\_console + > `= <boolean>` + +diff --git a/xen/arch/x86/cpu/amd.c b/xen/arch/x86/cpu/amd.c +index 40c0bac80b..e4fea603c3 100644 +--- a/xen/arch/x86/cpu/amd.c ++++ b/xen/arch/x86/cpu/amd.c +@@ -9,6 +9,7 @@ + #include <asm/amd.h> + #include <asm/hvm/support.h> + #include <asm/setup.h> /* amd_init_cpu */ ++#include <asm/spec_ctrl.h> + #include <asm/acpi.h> + #include <asm/apic.h> + +@@ -590,6 +591,25 @@ static void init_amd(struct cpuinfo_x86 *c) + c->x86_capability); + } + ++ /* ++ * If the user has explicitly chosen to disable Memory Disambiguation ++ * to mitigiate Speculative Store Bypass, poke the appropriate MSR. ++ */ ++ if (opt_ssbd) { ++ int bit = -1; ++ ++ switch (c->x86) { ++ case 0x15: bit = 54; break; ++ case 0x16: bit = 33; break; ++ case 0x17: bit = 10; break; ++ } ++ ++ if (bit >= 0 && !rdmsr_safe(MSR_AMD64_LS_CFG, value)) { ++ value |= 1ull << bit; ++ wrmsr_safe(MSR_AMD64_LS_CFG, value); ++ } ++ } ++ + /* MFENCE stops RDTSC speculation */ + if (!cpu_has_lfence_dispatch) + __set_bit(X86_FEATURE_MFENCE_RDTSC, c->x86_capability); +diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c +index 8099587bb0..61c046edfd 100644 +--- a/xen/arch/x86/spec_ctrl.c ++++ b/xen/arch/x86/spec_ctrl.c +@@ -43,6 +43,7 @@ static enum ind_thunk { + } opt_thunk __initdata = THUNK_DEFAULT; + static int8_t __initdata opt_ibrs = -1; + bool __read_mostly opt_ibpb = true; ++bool __read_mostly opt_ssbd = false; + + bool __initdata bsp_delay_spec_ctrl; + uint8_t __read_mostly default_xen_spec_ctrl; +@@ -164,6 +165,8 @@ static int __init parse_spec_ctrl(char *s) + opt_ibrs = val; + else if ( (val = parse_boolean("ibpb", s, ss)) >= 0 ) + opt_ibpb = val; ++ else if ( (val = parse_boolean("ssbd", s, ss)) >= 0 ) ++ opt_ssbd = val; + else + rc = -EINVAL; + +diff --git a/xen/include/asm-x86/spec_ctrl.h b/xen/include/asm-x86/spec_ctrl.h +index c6a38f495d..4678a40ba5 100644 +--- a/xen/include/asm-x86/spec_ctrl.h ++++ b/xen/include/asm-x86/spec_ctrl.h +@@ -27,6 +27,7 @@ + void init_speculation_mitigations(void); + + extern bool opt_ibpb; ++extern bool opt_ssbd; + + extern bool bsp_delay_spec_ctrl; + extern uint8_t default_xen_spec_ctrl; +-- +2.15.2 + diff --git a/main/xen/x86-disable-XPTI-when-RDCL_NO.patch b/main/xen/x86-disable-XPTI-when-RDCL_NO.patch new file mode 100644 index 0000000000..8aa70cae01 --- /dev/null +++ b/main/xen/x86-disable-XPTI-when-RDCL_NO.patch @@ -0,0 +1,185 @@ +From 7a590155c572c9a10b1ec5a5c1cad662286eb3b2 Mon Sep 17 00:00:00 2001 +From: Jan Beulich <jbeulich@suse.com> +Date: Wed, 18 Apr 2018 16:40:14 +0200 +Subject: [PATCH] x86: disable XPTI when RDCL_NO + +Use the respective ARCH_CAPABILITIES MSR bit, but don't expose the MSR +to guests yet. + +Signed-off-by: Jan Beulich <jbeulich@suse.com> +Tested-by: Juergen Gross <jgross@suse.com> +Reviewed-by: Juergen Gross <jgross@suse.com> +Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com> +Acked-by: Wei Liu <wei.liu2@citrix.com> +master commit: bee0732d2066691d8204e418d10110930ee4d4f8 +master date: 2018-04-05 15:48:23 +0100 +--- + tools/libxl/libxl_cpuid.c | 1 + + tools/misc/xen-cpuid.c | 3 ++- + xen/arch/x86/mm.c | 2 +- + xen/arch/x86/setup.c | 19 +++++++++++++++++++ + xen/arch/x86/smpboot.c | 7 +------ + xen/include/asm-x86/cpufeature.h | 1 + + xen/include/asm-x86/cpufeatures.h | 1 + + xen/include/asm-x86/msr-index.h | 2 ++ + xen/include/public/arch-x86/cpufeatureset.h | 1 + + 9 files changed, 29 insertions(+), 8 deletions(-) + +diff --git a/tools/libxl/libxl_cpuid.c b/tools/libxl/libxl_cpuid.c +index 8292654c86..3c00bb5c1d 100644 +--- a/tools/libxl/libxl_cpuid.c ++++ b/tools/libxl/libxl_cpuid.c +@@ -160,6 +160,7 @@ int libxl_cpuid_parse_config(libxl_cpuid_policy_list *cpuid, const char* str) + {"fpu", 0x00000001, NA, CPUID_REG_EDX, 0, 1}, + {"ibrsb", 0x00000007, 0, CPUID_REG_EDX, 26, 1}, + {"stibp", 0x00000007, 0, CPUID_REG_EDX, 27, 1}, ++ {"arch-caps", 0x00000007, 0, CPUID_REG_EDX, 29, 1}, + {"topoext", 0x80000001, NA, CPUID_REG_ECX, 22, 1}, + {"tbm", 0x80000001, NA, CPUID_REG_ECX, 21, 1}, + {"nodeid", 0x80000001, NA, CPUID_REG_ECX, 19, 1}, +diff --git a/tools/misc/xen-cpuid.c b/tools/misc/xen-cpuid.c +index 0bb2bca975..24800fd6da 100644 +--- a/tools/misc/xen-cpuid.c ++++ b/tools/misc/xen-cpuid.c +@@ -160,8 +160,9 @@ static const char *str_7d0[32] = + [4 ... 25] = "REZ", + + [26] = "ibrsb", [27] = "stibp", ++ [28] = "REZ", [29] = "arch_caps", + +- [28 ... 31] = "REZ", ++ [30 ... 31] = "REZ", + }; + + static struct { +diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c +index d847dfcf64..63a933fd5f 100644 +--- a/xen/arch/x86/mm.c ++++ b/xen/arch/x86/mm.c +@@ -4057,7 +4057,7 @@ long do_mmu_update( + * to the page lock we hold, its pinned status, and uses on + * this (v)CPU. + */ +- if ( !rc && this_cpu(root_pgt) && ++ if ( !rc && !cpu_has_no_xpti && + ((page->u.inuse.type_info & PGT_count_mask) > + (1 + !!(page->u.inuse.type_info & PGT_pinned) + + (pagetable_get_pfn(curr->arch.guest_table) == mfn) + +diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c +index d6135df0a7..29cbe42950 100644 +--- a/xen/arch/x86/setup.c ++++ b/xen/arch/x86/setup.c +@@ -152,6 +152,9 @@ static void __init parse_smap_param(char *s) + } + custom_param("smap", parse_smap_param); + ++static int8_t __initdata opt_xpti = -1; ++boolean_param("xpti", opt_xpti); ++ + bool_t __read_mostly acpi_disabled; + bool_t __initdata acpi_force; + static char __initdata acpi_param[10] = ""; +@@ -1486,6 +1489,22 @@ void __init noreturn __start_xen(unsigned long mbi_p) + + cr4_pv32_mask = mmu_cr4_features & XEN_CR4_PV32_BITS; + ++ if ( opt_xpti < 0 ) ++ { ++ uint64_t caps = 0; ++ ++ if ( boot_cpu_data.x86_vendor == X86_VENDOR_AMD ) ++ caps = ARCH_CAPABILITIES_RDCL_NO; ++ else if ( boot_cpu_has(X86_FEATURE_ARCH_CAPS) ) ++ rdmsrl(MSR_ARCH_CAPABILITIES, caps); ++ ++ opt_xpti = !(caps & ARCH_CAPABILITIES_RDCL_NO); ++ } ++ if ( opt_xpti ) ++ setup_clear_cpu_cap(X86_FEATURE_NO_XPTI); ++ else ++ setup_force_cpu_cap(X86_FEATURE_NO_XPTI); ++ + if ( cpu_has_fsgsbase ) + set_in_cr4(X86_CR4_FSGSBASE); + +diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c +index 8c5bfbceb7..9e59869735 100644 +--- a/xen/arch/x86/smpboot.c ++++ b/xen/arch/x86/smpboot.c +@@ -750,8 +750,6 @@ static int clone_mapping(const void *ptr, root_pgentry_t *rpt) + return 0; + } + +-static __read_mostly int8_t opt_xpti = -1; +-boolean_param("xpti", opt_xpti); + DEFINE_PER_CPU(root_pgentry_t *, root_pgt); + + static root_pgentry_t common_pgt; +@@ -764,7 +762,7 @@ static int setup_cpu_root_pgt(unsigned int cpu) + unsigned int off; + int rc; + +- if ( !opt_xpti ) ++ if ( cpu_has_no_xpti ) + return 0; + + rpt = alloc_xen_pagetable(); +@@ -1040,9 +1038,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus) + + stack_base[0] = stack_start; + +- if ( opt_xpti < 0 ) +- opt_xpti = boot_cpu_data.x86_vendor != X86_VENDOR_AMD; +- + rc = setup_cpu_root_pgt(0); + if ( rc ) + panic("Error %d setting up PV root page table\n", rc); +diff --git a/xen/include/asm-x86/cpufeature.h b/xen/include/asm-x86/cpufeature.h +index adc333f20e..62465b20c7 100644 +--- a/xen/include/asm-x86/cpufeature.h ++++ b/xen/include/asm-x86/cpufeature.h +@@ -105,6 +105,7 @@ + #define cpu_has_cpuid_faulting boot_cpu_has(X86_FEATURE_CPUID_FAULTING) + #define cpu_has_aperfmperf boot_cpu_has(X86_FEATURE_APERFMPERF) + #define cpu_has_lfence_dispatch boot_cpu_has(X86_FEATURE_LFENCE_DISPATCH) ++#define cpu_has_no_xpti boot_cpu_has(X86_FEATURE_NO_XPTI) + + enum _cache_type { + CACHE_TYPE_NULL = 0, +diff --git a/xen/include/asm-x86/cpufeatures.h b/xen/include/asm-x86/cpufeatures.h +index b96d313e14..84d5c5ba07 100644 +--- a/xen/include/asm-x86/cpufeatures.h ++++ b/xen/include/asm-x86/cpufeatures.h +@@ -32,3 +32,4 @@ XEN_CPUFEATURE(XEN_IBRS_SET, (FSCAPINTS+0)*32+18) /* IBRSB && IRBS set in Xen + XEN_CPUFEATURE(XEN_IBRS_CLEAR, (FSCAPINTS+0)*32+19) /* IBRSB && IBRS clear in Xen */ + XEN_CPUFEATURE(RSB_NATIVE, (FSCAPINTS+0)*32+20) /* RSB overwrite needed for native */ + XEN_CPUFEATURE(RSB_VMEXIT, (FSCAPINTS+0)*32+21) /* RSB overwrite needed for vmexit */ ++XEN_CPUFEATURE(NO_XPTI, (FSCAPINTS+0)*32+22) /* XPTI mitigation not in use */ +diff --git a/xen/include/asm-x86/msr-index.h b/xen/include/asm-x86/msr-index.h +index 0fc72b6267..723ce8efc1 100644 +--- a/xen/include/asm-x86/msr-index.h ++++ b/xen/include/asm-x86/msr-index.h +@@ -40,6 +40,8 @@ + #define PRED_CMD_IBPB (_AC(1, ULL) << 0) + + #define MSR_ARCH_CAPABILITIES 0x0000010a ++#define ARCH_CAPABILITIES_RDCL_NO (_AC(1, ULL) << 0) ++#define ARCH_CAPABILITIES_IBRS_ALL (_AC(1, ULL) << 1) + + /* Intel MSRs. Some also available on other CPUs */ + #define MSR_IA32_PERFCTR0 0x000000c1 +diff --git a/xen/include/public/arch-x86/cpufeatureset.h b/xen/include/public/arch-x86/cpufeatureset.h +index 816a2f8b53..f4b4c0fa57 100644 +--- a/xen/include/public/arch-x86/cpufeatureset.h ++++ b/xen/include/public/arch-x86/cpufeatureset.h +@@ -243,6 +243,7 @@ XEN_CPUFEATURE(AVX512_4VNNIW, 9*32+ 2) /*A AVX512 Neural Network Instructions * + XEN_CPUFEATURE(AVX512_4FMAPS, 9*32+ 3) /*A AVX512 Multiply Accumulation Single Precision */ + XEN_CPUFEATURE(IBRSB, 9*32+26) /*A IBRS and IBPB support (used by Intel) */ + XEN_CPUFEATURE(STIBP, 9*32+27) /*A! STIBP */ ++XEN_CPUFEATURE(ARCH_CAPS, 9*32+29) /* IA32_ARCH_CAPABILITIES MSR */ + + #endif /* XEN_CPUFEATURE */ + +-- +2.15.2 + diff --git a/main/xen/x86-log-XPTI-enabled-status.patch b/main/xen/x86-log-XPTI-enabled-status.patch new file mode 100644 index 0000000000..219299168e --- /dev/null +++ b/main/xen/x86-log-XPTI-enabled-status.patch @@ -0,0 +1,92 @@ +From 47d41f6885a83fae09545146c97d5243f1b99c7a Mon Sep 17 00:00:00 2001 +From: Jan Beulich <jbeulich@suse.com> +Date: Wed, 18 Apr 2018 16:40:50 +0200 +Subject: [PATCH] x86: log XPTI enabled status + +At the same time also report the state of the two defined +ARCH_CAPABILITIES MSR bits. To avoid further complicating the +conditional around that printk(), drop it (it's a debug level one only +anyway). + +Issue the main message without any XENLOG_*, and also drop XENLOG_INFO +from the respective BTI message, to make sure they're visible at default +log level also in release builds. + +Signed-off-by: Jan Beulich <jbeulich@suse.com> +Tested-by: Juergen Gross <jgross@suse.com> +Reviewed-by: Juergen Gross <jgross@suse.com> +Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com> +Reviewed-by: Wei Liu <wei.liu2@citrix.com> +master commit: 442b303cdaf7d774c0be8096fe5dbab68701abd3 +master date: 2018-04-05 15:48:23 +0100 +--- + xen/arch/x86/spec_ctrl.c | 24 ++++++++++++++---------- + 1 file changed, 14 insertions(+), 10 deletions(-) + +diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c +index 8ad992a700..3c7447bfe6 100644 +--- a/xen/arch/x86/spec_ctrl.c ++++ b/xen/arch/x86/spec_ctrl.c +@@ -21,7 +21,7 @@ + #include <xen/lib.h> + + #include <asm/microcode.h> +-#include <asm/msr-index.h> ++#include <asm/msr.h> + #include <asm/processor.h> + #include <asm/spec_ctrl.h> + #include <asm/spec_ctrl_asm.h> +@@ -84,30 +84,31 @@ custom_param("bti", parse_bti); + static void __init print_details(enum ind_thunk thunk) + { + unsigned int _7d0 = 0, e8b = 0, tmp; ++ uint64_t caps = 0; + + /* Collect diagnostics about available mitigations. */ + if ( boot_cpu_data.cpuid_level >= 7 ) + cpuid_count(7, 0, &tmp, &tmp, &tmp, &_7d0); + if ( boot_cpu_data.extended_cpuid_level >= 0x80000008 ) + cpuid(0x80000008, &tmp, &e8b, &tmp, &tmp); ++ if ( _7d0 & cpufeat_mask(X86_FEATURE_ARCH_CAPS) ) ++ rdmsrl(MSR_ARCH_CAPABILITIES, caps); + + printk(XENLOG_DEBUG "Speculative mitigation facilities:\n"); + + /* Hardware features which pertain to speculative mitigations. */ +- if ( (_7d0 & (cpufeat_mask(X86_FEATURE_IBRSB) | +- cpufeat_mask(X86_FEATURE_STIBP))) || +- (e8b & cpufeat_mask(X86_FEATURE_IBPB)) ) +- printk(XENLOG_DEBUG " Hardware features:%s%s%s\n", +- (_7d0 & cpufeat_mask(X86_FEATURE_IBRSB)) ? " IBRS/IBPB" : "", +- (_7d0 & cpufeat_mask(X86_FEATURE_STIBP)) ? " STIBP" : "", +- (e8b & cpufeat_mask(X86_FEATURE_IBPB)) ? " IBPB" : ""); ++ printk(XENLOG_DEBUG " Hardware features:%s%s%s%s%s\n", ++ (_7d0 & cpufeat_mask(X86_FEATURE_IBRSB)) ? " IBRS/IBPB" : "", ++ (_7d0 & cpufeat_mask(X86_FEATURE_STIBP)) ? " STIBP" : "", ++ (e8b & cpufeat_mask(X86_FEATURE_IBPB)) ? " IBPB" : "", ++ (caps & ARCH_CAPABILITIES_IBRS_ALL) ? " IBRS_ALL" : "", ++ (caps & ARCH_CAPABILITIES_RDCL_NO) ? " RDCL_NO" : ""); + + /* Compiled-in support which pertains to BTI mitigations. */ + if ( IS_ENABLED(CONFIG_INDIRECT_THUNK) ) + printk(XENLOG_DEBUG " Compiled-in support: INDIRECT_THUNK\n"); + +- printk(XENLOG_INFO +- "BTI mitigations: Thunk %s, Others:%s%s%s%s\n", ++ printk("BTI mitigations: Thunk %s, Others:%s%s%s%s\n", + thunk == THUNK_NONE ? "N/A" : + thunk == THUNK_RETPOLINE ? "RETPOLINE" : + thunk == THUNK_LFENCE ? "LFENCE" : +@@ -117,6 +118,9 @@ static void __init print_details(enum ind_thunk thunk) + opt_ibpb ? " IBPB" : "", + boot_cpu_has(X86_FEATURE_RSB_NATIVE) ? " RSB_NATIVE" : "", + boot_cpu_has(X86_FEATURE_RSB_VMEXIT) ? " RSB_VMEXIT" : ""); ++ ++ printk("XPTI: %s\n", ++ boot_cpu_has(X86_FEATURE_NO_XPTI) ? "disabled" : "enabled"); + } + + /* Calculate whether Retpoline is known-safe on this CPU. */ +-- +2.15.2 + diff --git a/main/xen/x86-spec_ctrl-Fix-several-bugs-in-SPEC_CTRL_ENTRY_FR.patch b/main/xen/x86-spec_ctrl-Fix-several-bugs-in-SPEC_CTRL_ENTRY_FR.patch new file mode 100644 index 0000000000..180118f932 --- /dev/null +++ b/main/xen/x86-spec_ctrl-Fix-several-bugs-in-SPEC_CTRL_ENTRY_FR.patch @@ -0,0 +1,94 @@ +From 6d4c4f06467e3d126ca45c2e6b09a66a2a60a1ae Mon Sep 17 00:00:00 2001 +From: Andrew Cooper <andrew.cooper3@citrix.com> +Date: Wed, 18 Apr 2018 16:38:50 +0200 +Subject: [PATCH] x86/spec_ctrl: Fix several bugs in + SPEC_CTRL_ENTRY_FROM_INTR_IST +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +DO_OVERWRITE_RSB clobbers %rax, meaning in practice that the bti_ist_info +field gets zeroed. Older versions of this code had the DO_OVERWRITE_RSB +register selectable, so reintroduce this ability and use it to cause the +INTR_IST path to use %rdx instead. + +The use of %dl for the %cs.rpl check means that when an IST interrupt hits +Xen, we try to load 1 into the high 32 bits of MSR_SPEC_CTRL, suffering a #GP +fault instead. + +Also, drop an unused label which was a copy/paste mistake. + +Reported-by: Boris Ostrovsky <boris.ostrovsky@oracle.com> +Reported-by: Zhenzhong Duan <zhenzhong.duan@oracle.com> +Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> +Reviewed-by: Jan Beulich <jbeulich@suse.com> +Reviewed-by: Wei Liu <wei.liu2@citrix.com> +Reviewed-by: Roger Pau Monné <roger.pau@citrix.com> +master commit: a2b08fbed388f18235fda5ba1655c1483ef3e215 +master date: 2018-02-14 13:22:15 +0000 +--- + xen/include/asm-x86/spec_ctrl_asm.h | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/xen/include/asm-x86/spec_ctrl_asm.h b/xen/include/asm-x86/spec_ctrl_asm.h +index 7a43daf231..69cf3cc2f1 100644 +--- a/xen/include/asm-x86/spec_ctrl_asm.h ++++ b/xen/include/asm-x86/spec_ctrl_asm.h +@@ -79,10 +79,10 @@ + * - SPEC_CTRL_EXIT_TO_GUEST + */ + +-.macro DO_OVERWRITE_RSB ++.macro DO_OVERWRITE_RSB tmp=rax + /* + * Requires nothing +- * Clobbers %rax, %rcx ++ * Clobbers \tmp (%rax by default), %rcx + * + * Requires 256 bytes of stack space, but %rsp has no net change. Based on + * Google's performance numbers, the loop is unrolled to 16 iterations and two +@@ -97,7 +97,7 @@ + * optimised with mov-elimination in modern cores. + */ + mov $16, %ecx /* 16 iterations, two calls per loop */ +- mov %rsp, %rax /* Store the current %rsp */ ++ mov %rsp, %\tmp /* Store the current %rsp */ + + .L\@_fill_rsb_loop: + +@@ -114,7 +114,7 @@ + + sub $1, %ecx + jnz .L\@_fill_rsb_loop +- mov %rax, %rsp /* Restore old %rsp */ ++ mov %\tmp, %rsp /* Restore old %rsp */ + .endm + + .macro DO_SPEC_CTRL_ENTRY_FROM_VMEXIT ibrs_val:req +@@ -273,7 +273,7 @@ + testb $BTI_IST_RSB, %al + jz .L\@_skip_rsb + +- DO_OVERWRITE_RSB ++ DO_OVERWRITE_RSB tmp=rdx /* Clobbers %rcx/%rdx */ + + .L\@_skip_rsb: + +@@ -285,13 +285,13 @@ + setz %dl + and %dl, STACK_CPUINFO_FIELD(use_shadow_spec_ctrl)(%r14) + +-.L\@_entry_from_xen: + /* + * Load Xen's intended value. SPEC_CTRL_IBRS vs 0 is encoded in the + * bottom bit of bti_ist_info, via a deliberate alias with BTI_IST_IBRS. + */ + mov $MSR_SPEC_CTRL, %ecx + and $BTI_IST_IBRS, %eax ++ xor %edx, %edx + wrmsr + + /* Opencoded UNLIKELY_START() with no condition. */ +-- +2.15.2 + diff --git a/main/xen/x86-spec_ctrl-Updates-to-retpoline-safety-decision-m.patch b/main/xen/x86-spec_ctrl-Updates-to-retpoline-safety-decision-m.patch new file mode 100644 index 0000000000..2ffa5d9133 --- /dev/null +++ b/main/xen/x86-spec_ctrl-Updates-to-retpoline-safety-decision-m.patch @@ -0,0 +1,148 @@ +From 2303a9d66097c64e93d3c2c5562627db95820e0b Mon Sep 17 00:00:00 2001 +From: Andrew Cooper <andrew.cooper3@citrix.com> +Date: Fri, 18 May 2018 11:55:25 +0200 +Subject: [PATCH] x86/spec_ctrl: Updates to retpoline-safety decision making + +All of this is as recommended by the Intel whitepaper: + +https://software.intel.com/sites/default/files/managed/1d/46/Retpoline-A-Branch-Target-Injection-Mitigation.pdf + +The 'RSB Alternative' bit in MSR_ARCH_CAPABILITIES may be set by a hypervisor +to indicate that the virtual machine may migrate to a processor which isn't +retpoline-safe. Introduce a shortened name (to reduce code volume), treat it +as authorative in retpoline_safe(), and print its value along with the other +ARCH_CAPS bits. + +The exact processor models which do have RSB semantics which fall back to BTB +predictions are enumerated, and include Kabylake and Coffeelake. Leave a +printk() in the default case to help identify cases which aren't covered. + +The exact microcode versions from Broadwell RSB-safety are taken from the +referenced microcode update file (adjusting for the known-bad microcode +versions). Despite the exact wording of the text, it is only Broadwell +processors which need a microcode check. + +In practice, this means that all Broadwell hardware with up-to-date microcode +will use retpoline in preference to IBRS, which will be a performance +improvement for desktop and server systems which would previously always opt +for IBRS over retpoline. + +Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> +Reviewed-by: Jan Beulich <jbeulich@suse.com> + +x86/spec_ctrl: Fix typo in ARCH_CAPS decode + +Reported-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> +Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> +Acked-by: Jan Beulich <jbeulich@suse.com> +master commit: 1232378bd2fef45f613db049b33852fdf84d7ddf +master date: 2018-04-19 17:28:23 +0100 +master commit: 27170adb54a558e11defcd51989326a9beb95afe +master date: 2018-04-24 13:34:12 +0100 +--- + xen/arch/x86/spec_ctrl.c | 51 +++++++++++++++++++++++++++++++++++------ + xen/include/asm-x86/msr-index.h | 1 + + 2 files changed, 45 insertions(+), 7 deletions(-) + +diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c +index 3c7447bfe6..fa67a0ffbd 100644 +--- a/xen/arch/x86/spec_ctrl.c ++++ b/xen/arch/x86/spec_ctrl.c +@@ -97,12 +97,13 @@ static void __init print_details(enum ind_thunk thunk) + printk(XENLOG_DEBUG "Speculative mitigation facilities:\n"); + + /* Hardware features which pertain to speculative mitigations. */ +- printk(XENLOG_DEBUG " Hardware features:%s%s%s%s%s\n", ++ printk(XENLOG_DEBUG " Hardware features:%s%s%s%s%s%s\n", + (_7d0 & cpufeat_mask(X86_FEATURE_IBRSB)) ? " IBRS/IBPB" : "", + (_7d0 & cpufeat_mask(X86_FEATURE_STIBP)) ? " STIBP" : "", + (e8b & cpufeat_mask(X86_FEATURE_IBPB)) ? " IBPB" : "", + (caps & ARCH_CAPABILITIES_IBRS_ALL) ? " IBRS_ALL" : "", +- (caps & ARCH_CAPABILITIES_RDCL_NO) ? " RDCL_NO" : ""); ++ (caps & ARCH_CAPABILITIES_RDCL_NO) ? " RDCL_NO" : "", ++ (caps & ARCH_CAPS_RSBA) ? " RSBA" : ""); + + /* Compiled-in support which pertains to BTI mitigations. */ + if ( IS_ENABLED(CONFIG_INDIRECT_THUNK) ) +@@ -135,6 +136,20 @@ static bool __init retpoline_safe(void) + boot_cpu_data.x86 != 6 ) + return false; + ++ if ( boot_cpu_has(X86_FEATURE_ARCH_CAPS) ) ++ { ++ uint64_t caps; ++ ++ rdmsrl(MSR_ARCH_CAPABILITIES, caps); ++ ++ /* ++ * RBSA may be set by a hypervisor to indicate that we may move to a ++ * processor which isn't retpoline-safe. ++ */ ++ if ( caps & ARCH_CAPS_RSBA ) ++ return false; ++ } ++ + switch ( boot_cpu_data.x86_model ) + { + case 0x17: /* Penryn */ +@@ -161,18 +176,40 @@ static bool __init retpoline_safe(void) + * versions. + */ + case 0x3d: /* Broadwell */ +- return ucode_rev >= 0x28; ++ return ucode_rev >= 0x2a; + case 0x47: /* Broadwell H */ +- return ucode_rev >= 0x1b; ++ return ucode_rev >= 0x1d; + case 0x4f: /* Broadwell EP/EX */ +- return ucode_rev >= 0xb000025; ++ return ucode_rev >= 0xb000021; + case 0x56: /* Broadwell D */ +- return false; /* TBD. */ ++ switch ( boot_cpu_data.x86_mask ) ++ { ++ case 2: return ucode_rev >= 0x15; ++ case 3: return ucode_rev >= 0x7000012; ++ case 4: return ucode_rev >= 0xf000011; ++ case 5: return ucode_rev >= 0xe000009; ++ default: ++ printk("Unrecognised CPU stepping %#x - assuming not reptpoline safe\n", ++ boot_cpu_data.x86_mask); ++ return false; ++ } ++ break; + + /* +- * Skylake and later processors are not retpoline-safe. ++ * Skylake, Kabylake and Cannonlake processors are not retpoline-safe. + */ ++ case 0x4e: ++ case 0x55: ++ case 0x5e: ++ case 0x66: ++ case 0x67: ++ case 0x8e: ++ case 0x9e: ++ return false; ++ + default: ++ printk("Unrecognised CPU model %#x - assuming not reptpoline safe\n", ++ boot_cpu_data.x86_model); + return false; + } + } +diff --git a/xen/include/asm-x86/msr-index.h b/xen/include/asm-x86/msr-index.h +index 723ce8efc1..6aaf3035c5 100644 +--- a/xen/include/asm-x86/msr-index.h ++++ b/xen/include/asm-x86/msr-index.h +@@ -42,6 +42,7 @@ + #define MSR_ARCH_CAPABILITIES 0x0000010a + #define ARCH_CAPABILITIES_RDCL_NO (_AC(1, ULL) << 0) + #define ARCH_CAPABILITIES_IBRS_ALL (_AC(1, ULL) << 1) ++#define ARCH_CAPS_RSBA (_AC(1, ULL) << 2) + + /* Intel MSRs. Some also available on other CPUs */ + #define MSR_IA32_PERFCTR0 0x000000c1 +-- +2.15.2 + diff --git a/main/xen/x86-suppress-BTI-mitigations-around-S3-suspend-resum.patch b/main/xen/x86-suppress-BTI-mitigations-around-S3-suspend-resum.patch new file mode 100644 index 0000000000..e8f83b1009 --- /dev/null +++ b/main/xen/x86-suppress-BTI-mitigations-around-S3-suspend-resum.patch @@ -0,0 +1,77 @@ +From 62bd851a4469976f036c2d804ebed7ca39741254 Mon Sep 17 00:00:00 2001 +From: Jan Beulich <jbeulich@suse.com> +Date: Fri, 18 May 2018 11:53:13 +0200 +Subject: [PATCH] x86: suppress BTI mitigations around S3 suspend/resume + +NMI and #MC can occur at any time after S3 resume, yet the MSR_SPEC_CTRL +may become available only once we're reloaded microcode. Make +SPEC_CTRL_ENTRY_FROM_INTR_IST and DO_SPEC_CTRL_EXIT_TO_XEN no-ops for +the critical period of time. + +Also set the MSR back to its intended value. + +Signed-off-by: Jan Beulich <jbeulich@suse.com> +Acked-by: Andrew Cooper <andrew.cooper3@citrix.com> + +x86: Use spec_ctrl_{enter,exit}_idle() in the S3/S5 path + +The main purpose of this patch is to avoid opencoding the recovery logic at +the end, but also has the positive side effect of relaxing the SPEC_CTRL +mitigations when working to shut the final CPU down. + +Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> +Reviewed-by: Jan Beulich <jbeulich@suse.com> +master commit: 710a8ebf2bc111a34bba04d1c85b6d07ed3d9389 +master date: 2018-04-16 14:09:55 +0200 +master commit: ef3ab46493f650b7e5cca2b2578a99ca0cbff195 +master date: 2018-04-19 10:55:59 +0100 +--- + xen/arch/x86/acpi/power.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/xen/arch/x86/acpi/power.c b/xen/arch/x86/acpi/power.c +index cb06f842cd..f7085d3c7b 100644 +--- a/xen/arch/x86/acpi/power.c ++++ b/xen/arch/x86/acpi/power.c +@@ -28,6 +28,7 @@ + #include <asm/tboot.h> + #include <asm/apic.h> + #include <asm/io_apic.h> ++#include <asm/spec_ctrl.h> + #include <acpi/cpufreq/cpufreq.h> + + uint32_t system_reset_counter = 1; +@@ -163,6 +164,7 @@ static int enter_state(u32 state) + { + unsigned long flags; + int error; ++ struct cpu_info *ci; + unsigned long cr4; + + if ( (state <= ACPI_STATE_S0) || (state > ACPI_S_STATES_MAX) ) +@@ -210,6 +212,11 @@ static int enter_state(u32 state) + else + error = 0; + ++ ci = get_cpu_info(); ++ spec_ctrl_enter_idle(ci); ++ /* Avoid NMI/#MC using MSR_SPEC_CTRL until we've reloaded microcode. */ ++ ci->bti_ist_info = 0; ++ + ACPI_FLUSH_CPU_CACHE(); + + switch ( state ) +@@ -248,6 +255,10 @@ static int enter_state(u32 state) + + microcode_resume_cpu(0); + ++ /* Re-enabled default NMI/#MC use of MSR_SPEC_CTRL. */ ++ ci->bti_ist_info = default_bti_ist_info; ++ spec_ctrl_exit_idle(ci); ++ + done: + spin_debug_enable(); + local_irq_restore(flags); +-- +2.15.2 + diff --git a/main/xen/x86-xpti-avoid-copying-L4-page-table-contents-when-p.patch b/main/xen/x86-xpti-avoid-copying-L4-page-table-contents-when-p.patch new file mode 100644 index 0000000000..b2ce07cc3e --- /dev/null +++ b/main/xen/x86-xpti-avoid-copying-L4-page-table-contents-when-p.patch @@ -0,0 +1,257 @@ +From ed217c98b003f226500d87e65600f984a692b6ce Mon Sep 17 00:00:00 2001 +From: Juergen Gross <jgross@suse.com> +Date: Tue, 29 May 2018 09:53:24 +0200 +Subject: [PATCH] x86/xpti: avoid copying L4 page table contents when possible + +For mitigation of Meltdown the current L4 page table is copied to the +cpu local root page table each time a 64 bit pv guest is entered. + +Copying can be avoided in cases where the guest L4 page table hasn't +been modified while running the hypervisor, e.g. when handling +interrupts or any hypercall not modifying the L4 page table or %cr3. + +So add a per-cpu flag indicating whether the copying should be +performed and set that flag only when loading a new %cr3 or modifying +the L4 page table. This includes synchronization of the cpu local +root page table with other cpus, so add a special synchronization flag +for that case. + +A simple performance check (compiling the hypervisor via "make -j 4") +in dom0 with 4 vcpus shows a significant improvement: + +- real time drops from 112 seconds to 103 seconds +- system time drops from 142 seconds to 131 seconds + +Signed-off-by: Juergen Gross <jgross@suse.com> +Reviewed-by: Jan Beulich <jbeulich@suse.com> +--- + xen/arch/x86/flushtlb.c | 4 ++++ + xen/arch/x86/mm.c | 36 +++++++++++++++++++++++------------- + xen/arch/x86/mm/shadow/multi.c | 3 +++ + xen/arch/x86/smp.c | 2 +- + xen/arch/x86/x86_64/asm-offsets.c | 1 + + xen/arch/x86/x86_64/entry.S | 9 +++++++-- + xen/arch/x86/x86_64/traps.c | 2 ++ + xen/include/asm-x86/current.h | 8 ++++++++ + xen/include/asm-x86/flushtlb.h | 8 ++++++++ + 9 files changed, 57 insertions(+), 16 deletions(-) + +diff --git a/xen/arch/x86/flushtlb.c b/xen/arch/x86/flushtlb.c +index 8a7a76b8ff..2729ba42e7 100644 +--- a/xen/arch/x86/flushtlb.c ++++ b/xen/arch/x86/flushtlb.c +@@ -8,6 +8,7 @@ + */ + + #include <xen/sched.h> ++#include <xen/smp.h> + #include <xen/softirq.h> + #include <asm/flushtlb.h> + #include <asm/page.h> +@@ -160,5 +161,8 @@ unsigned int flush_area_local(const void *va, unsigned int flags) + + local_irq_restore(irqfl); + ++ if ( flags & FLUSH_ROOT_PGTBL ) ++ get_cpu_info()->root_pgt_changed = true; ++ + return flags; + } +diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c +index 63a933fd5f..171137310b 100644 +--- a/xen/arch/x86/mm.c ++++ b/xen/arch/x86/mm.c +@@ -512,6 +512,7 @@ void make_cr3(struct vcpu *v, unsigned long mfn) + + void write_ptbase(struct vcpu *v) + { ++ get_cpu_info()->root_pgt_changed = true; + write_cr3(v->arch.cr3); + } + +@@ -4052,18 +4053,27 @@ long do_mmu_update( + case PGT_l4_page_table: + rc = mod_l4_entry(va, l4e_from_intpte(req.val), mfn, + cmd == MMU_PT_UPDATE_PRESERVE_AD, v); +- /* +- * No need to sync if all uses of the page can be accounted +- * to the page lock we hold, its pinned status, and uses on +- * this (v)CPU. +- */ +- if ( !rc && !cpu_has_no_xpti && +- ((page->u.inuse.type_info & PGT_count_mask) > +- (1 + !!(page->u.inuse.type_info & PGT_pinned) + +- (pagetable_get_pfn(curr->arch.guest_table) == mfn) + +- (pagetable_get_pfn(curr->arch.guest_table_user) == +- mfn))) ) +- sync_guest = true; ++ if ( !rc && !cpu_has_no_xpti ) ++ { ++ bool local_in_use = false; ++ ++ if ( pagetable_get_pfn(curr->arch.guest_table) == mfn ) ++ { ++ local_in_use = true; ++ get_cpu_info()->root_pgt_changed = true; ++ } ++ ++ /* ++ * No need to sync if all uses of the page can be ++ * accounted to the page lock we hold, its pinned ++ * status, and uses on this (v)CPU. ++ */ ++ if ( (page->u.inuse.type_info & PGT_count_mask) > ++ (1 + !!(page->u.inuse.type_info & PGT_pinned) + ++ (pagetable_get_pfn(curr->arch.guest_table_user) == ++ mfn) + local_in_use) ) ++ sync_guest = true; ++ } + break; + case PGT_writable_page: + perfc_incr(writable_mmu_updates); +@@ -4177,7 +4187,7 @@ long do_mmu_update( + + cpumask_andnot(mask, pt_owner->domain_dirty_cpumask, cpumask_of(cpu)); + if ( !cpumask_empty(mask) ) +- flush_mask(mask, FLUSH_TLB_GLOBAL); ++ flush_mask(mask, FLUSH_TLB_GLOBAL | FLUSH_ROOT_PGTBL); + } + + perfc_add(num_page_updates, i); +diff --git a/xen/arch/x86/mm/shadow/multi.c b/xen/arch/x86/mm/shadow/multi.c +index 93771d9e43..a53d3db56c 100644 +--- a/xen/arch/x86/mm/shadow/multi.c ++++ b/xen/arch/x86/mm/shadow/multi.c +@@ -951,6 +951,8 @@ static int shadow_set_l4e(struct domain *d, + + /* Write the new entry */ + shadow_write_entries(sl4e, &new_sl4e, 1, sl4mfn); ++ flush_root_pgtbl_domain(d); ++ + flags |= SHADOW_SET_CHANGED; + + if ( shadow_l4e_get_flags(old_sl4e) & _PAGE_PRESENT ) +@@ -965,6 +967,7 @@ static int shadow_set_l4e(struct domain *d, + } + sh_put_ref(d, osl3mfn, paddr); + } ++ + return flags; + } + +diff --git a/xen/arch/x86/smp.c b/xen/arch/x86/smp.c +index 70de53d4fe..e8b949da61 100644 +--- a/xen/arch/x86/smp.c ++++ b/xen/arch/x86/smp.c +@@ -208,7 +208,7 @@ void invalidate_interrupt(struct cpu_user_regs *regs) + ack_APIC_irq(); + perfc_incr(ipis); + if ( __sync_local_execstate() ) +- flags &= ~(FLUSH_TLB | FLUSH_TLB_GLOBAL); ++ flags &= ~(FLUSH_TLB | FLUSH_TLB_GLOBAL | FLUSH_ROOT_PGTBL); + flush_area_local(flush_va, flags); + cpumask_clear_cpu(smp_processor_id(), &flush_cpumask); + } +diff --git a/xen/arch/x86/x86_64/asm-offsets.c b/xen/arch/x86/x86_64/asm-offsets.c +index cc97d753df..a347083d23 100644 +--- a/xen/arch/x86/x86_64/asm-offsets.c ++++ b/xen/arch/x86/x86_64/asm-offsets.c +@@ -144,6 +144,7 @@ void __dummy__(void) + OFFSET(CPUINFO_shadow_spec_ctrl, struct cpu_info, shadow_spec_ctrl); + OFFSET(CPUINFO_xen_spec_ctrl, struct cpu_info, xen_spec_ctrl); + OFFSET(CPUINFO_spec_ctrl_flags, struct cpu_info, spec_ctrl_flags); ++ OFFSET(CPUINFO_root_pgt_changed, struct cpu_info, root_pgt_changed); + DEFINE(CPUINFO_sizeof, sizeof(struct cpu_info)); + BLANK(); + +diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S +index cdf5090ec7..67e9b49a5c 100644 +--- a/xen/arch/x86/x86_64/entry.S ++++ b/xen/arch/x86/x86_64/entry.S +@@ -161,11 +161,15 @@ restore_all_guest: + mov VCPU_cr3(%rbx), %r9 + GET_STACK_END(dx) + mov STACK_CPUINFO_FIELD(pv_cr3)(%rdx), %rdi ++ test %rdi, %rdi ++ jz .Lrag_keep_cr3 ++ mov %rdi, %rax ++ cmpb $0, STACK_CPUINFO_FIELD(root_pgt_changed)(%rdx) ++ je .Lrag_copy_done ++ movb $0, STACK_CPUINFO_FIELD(root_pgt_changed)(%rdx) + movabs $PADDR_MASK & PAGE_MASK, %rsi + movabs $DIRECTMAP_VIRT_START, %rcx +- mov %rdi, %rax + and %rsi, %rdi +- jz .Lrag_keep_cr3 + and %r9, %rsi + add %rcx, %rdi + add %rcx, %rsi +@@ -180,6 +184,7 @@ restore_all_guest: + sub $(ROOT_PAGETABLE_FIRST_XEN_SLOT - \ + ROOT_PAGETABLE_LAST_XEN_SLOT - 1) * 8, %rdi + rep movsq ++.Lrag_copy_done: + mov STACK_CPUINFO_FIELD(cr4)(%rdx), %rdi + mov %r9, STACK_CPUINFO_FIELD(xen_cr3)(%rdx) + mov %rdi, %rsi +diff --git a/xen/arch/x86/x86_64/traps.c b/xen/arch/x86/x86_64/traps.c +index 4f92a2e1ca..8bb2f1afe5 100644 +--- a/xen/arch/x86/x86_64/traps.c ++++ b/xen/arch/x86/x86_64/traps.c +@@ -284,6 +284,8 @@ void toggle_guest_pt(struct vcpu *v) + + v->arch.flags ^= TF_kernel_mode; + update_cr3(v); ++ get_cpu_info()->root_pgt_changed = true; ++ + /* Don't flush user global mappings from the TLB. Don't tick TLB clock. */ + asm volatile ( "mov %0, %%cr3" : : "r" (v->arch.cr3) : "memory" ); + +diff --git a/xen/include/asm-x86/current.h b/xen/include/asm-x86/current.h +index 7afff0e245..f0061bd497 100644 +--- a/xen/include/asm-x86/current.h ++++ b/xen/include/asm-x86/current.h +@@ -59,6 +59,14 @@ struct cpu_info { + uint8_t xen_spec_ctrl; + uint8_t spec_ctrl_flags; + ++ /* ++ * The following field controls copying of the L4 page table of 64-bit ++ * PV guests to the per-cpu root page table on entering the guest context. ++ * If set the L4 page table is being copied to the root page table and ++ * the field will be reset. ++ */ ++ bool root_pgt_changed; ++ + unsigned long __pad; + /* get_stack_bottom() must be 16-byte aligned */ + }; +diff --git a/xen/include/asm-x86/flushtlb.h b/xen/include/asm-x86/flushtlb.h +index 5f78bbbe3d..ca2cd16721 100644 +--- a/xen/include/asm-x86/flushtlb.h ++++ b/xen/include/asm-x86/flushtlb.h +@@ -101,6 +101,8 @@ void write_cr3(unsigned long cr3); + #define FLUSH_CACHE 0x400 + /* VA for the flush has a valid mapping */ + #define FLUSH_VA_VALID 0x800 ++ /* Flush the per-cpu root page table */ ++#define FLUSH_ROOT_PGTBL 0x2000 + + /* Flush local TLBs/caches. */ + unsigned int flush_area_local(const void *va, unsigned int flags); +@@ -132,6 +134,12 @@ void flush_area_mask(const cpumask_t *, const void *va, unsigned int flags); + #define flush_tlb_one_all(v) \ + flush_tlb_one_mask(&cpu_online_map, v) + ++#define flush_root_pgtbl_domain(d) \ ++{ \ ++ if ( !cpu_has_no_xpti && is_pv_domain(d) && !is_pv_32bit_domain(d) ) \ ++ flush_mask((d)->domain_dirty_cpumask, FLUSH_ROOT_PGTBL); \ ++} ++ + static inline void flush_page_to_ram(unsigned long mfn) {} + static inline int invalidate_dcache_va_range(const void *p, + unsigned long size) +-- +2.15.2 + diff --git a/main/xen/xen-x86-add-a-function-for-modifying-cr3.patch b/main/xen/xen-x86-add-a-function-for-modifying-cr3.patch new file mode 100644 index 0000000000..e5633e5916 --- /dev/null +++ b/main/xen/xen-x86-add-a-function-for-modifying-cr3.patch @@ -0,0 +1,125 @@ +From 516ac8a982a20a55ef8e28715e36c3aa917b7222 Mon Sep 17 00:00:00 2001 +From: Juergen Gross <jgross@suse.com> +Date: Thu, 26 Apr 2018 13:33:11 +0200 +Subject: [PATCH] xen/x86: add a function for modifying cr3 + +Instead of having multiple places with more or less identical asm +statements just have one function doing a write to cr3. + +As this function should be named write_cr3() rename the current +write_cr3() function to switch_cr3(). + +Suggested-by: Andrew Copper <andrew.cooper3@citrix.com> +Signed-off-by: Juergen Gross <jgross@suse.com> +Reviewed-by: Jan Beulich <jbeulich@suse.com> +--- + xen/arch/x86/flushtlb.c | 4 ++-- + xen/arch/x86/mm.c | 2 +- + xen/arch/x86/x86_64/traps.c | 2 +- + xen/common/efi/runtime.c | 4 ++-- + xen/include/asm-x86/flushtlb.h | 2 +- + xen/include/asm-x86/processor.h | 5 +++++ + 6 files changed, 12 insertions(+), 7 deletions(-) + +diff --git a/xen/arch/x86/flushtlb.c b/xen/arch/x86/flushtlb.c +index 2729ba42e7..1af9221607 100644 +--- a/xen/arch/x86/flushtlb.c ++++ b/xen/arch/x86/flushtlb.c +@@ -72,7 +72,7 @@ static void post_flush(u32 t) + this_cpu(tlbflush_time) = t; + } + +-void write_cr3(unsigned long cr3) ++void switch_cr3(unsigned long cr3) + { + unsigned long flags, cr4; + u32 t; +@@ -84,7 +84,7 @@ void write_cr3(unsigned long cr3) + cr4 = read_cr4(); + + write_cr4(cr4 & ~X86_CR4_PGE); +- asm volatile ( "mov %0, %%cr3" : : "r" (cr3) : "memory" ); ++ write_cr3(cr3); + write_cr4(cr4); + + post_flush(t); +diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c +index 171137310b..d529f48a51 100644 +--- a/xen/arch/x86/mm.c ++++ b/xen/arch/x86/mm.c +@@ -513,7 +513,7 @@ void make_cr3(struct vcpu *v, unsigned long mfn) + void write_ptbase(struct vcpu *v) + { + get_cpu_info()->root_pgt_changed = true; +- write_cr3(v->arch.cr3); ++ switch_cr3(v->arch.cr3); + } + + /* +diff --git a/xen/arch/x86/x86_64/traps.c b/xen/arch/x86/x86_64/traps.c +index 8bb2f1afe5..934fc91069 100644 +--- a/xen/arch/x86/x86_64/traps.c ++++ b/xen/arch/x86/x86_64/traps.c +@@ -287,7 +287,7 @@ void toggle_guest_pt(struct vcpu *v) + get_cpu_info()->root_pgt_changed = true; + + /* Don't flush user global mappings from the TLB. Don't tick TLB clock. */ +- asm volatile ( "mov %0, %%cr3" : : "r" (v->arch.cr3) : "memory" ); ++ write_cr3(v->arch.cr3); + + if ( !(v->arch.flags & TF_kernel_mode) ) + return; +diff --git a/xen/common/efi/runtime.c b/xen/common/efi/runtime.c +index 20bc5328e0..76485f3e3d 100644 +--- a/xen/common/efi/runtime.c ++++ b/xen/common/efi/runtime.c +@@ -111,7 +111,7 @@ struct efi_rs_state efi_rs_enter(void) + asm volatile ( "lgdt %0" : : "m" (gdt_desc) ); + } + +- write_cr3(virt_to_maddr(efi_l4_pgtable)); ++ switch_cr3(virt_to_maddr(efi_l4_pgtable)); + + return state; + } +@@ -120,7 +120,7 @@ void efi_rs_leave(struct efi_rs_state *state) + { + if ( !state->cr3 ) + return; +- write_cr3(state->cr3); ++ switch_cr3(state->cr3); + if ( is_pv_vcpu(current) && !is_idle_vcpu(current) ) + { + struct desc_ptr gdt_desc = { +diff --git a/xen/include/asm-x86/flushtlb.h b/xen/include/asm-x86/flushtlb.h +index ca2cd16721..834b113626 100644 +--- a/xen/include/asm-x86/flushtlb.h ++++ b/xen/include/asm-x86/flushtlb.h +@@ -84,7 +84,7 @@ static inline unsigned long read_cr3(void) + } + + /* Write pagetable base and implicitly tick the tlbflush clock. */ +-void write_cr3(unsigned long cr3); ++void switch_cr3(unsigned long cr3); + + /* flush_* flag fields: */ + /* +diff --git a/xen/include/asm-x86/processor.h b/xen/include/asm-x86/processor.h +index bcf647cbcc..d2c93a67dd 100644 +--- a/xen/include/asm-x86/processor.h ++++ b/xen/include/asm-x86/processor.h +@@ -284,6 +284,11 @@ static inline unsigned long read_cr2(void) + return cr2; + } + ++static inline void write_cr3(unsigned long val) ++{ ++ asm volatile ( "mov %0, %%cr3" : : "r" (val) : "memory" ); ++} ++ + static inline unsigned long read_cr4(void) + { + return get_cpu_info()->cr4; +-- +2.15.2 + diff --git a/main/xen/xen-x86-support-per-domain-flag-for-xpti.patch b/main/xen/xen-x86-support-per-domain-flag-for-xpti.patch new file mode 100644 index 0000000000..3826fa5368 --- /dev/null +++ b/main/xen/xen-x86-support-per-domain-flag-for-xpti.patch @@ -0,0 +1,341 @@ +From 12259ff59c52c601ce7f67799575224b2c35b6a1 Mon Sep 17 00:00:00 2001 +From: Juergen Gross <jgross@suse.com> +Date: Thu, 26 Apr 2018 13:33:12 +0200 +Subject: [PATCH] xen/x86: support per-domain flag for xpti + +Instead of switching XPTI globally on or off add a per-domain flag for +that purpose. This allows to modify the xpti boot parameter to support +running dom0 without Meltdown mitigations. Using "xpti=no-dom0" as boot +parameter will achieve that. + +Move the xpti boot parameter handling to xen/arch/x86/pv/domain.c as +it is pv-domain specific. + +Signed-off-by: Juergen Gross <jgross@suse.com> +Reviewed-by: Jan Beulich <jbeulich@suse.com> +--- + docs/misc/xen-command-line.markdown | 14 ++++++- + xen/arch/x86/domain.c | 5 +++ + xen/arch/x86/mm.c | 17 ++++++++- + xen/arch/x86/pv/dom0_build.c | 1 + + xen/arch/x86/setup.c | 19 ---------- + xen/arch/x86/smpboot.c | 4 +- + xen/arch/x86/spec_ctrl.c | 75 ++++++++++++++++++++++++++++++++++++- + xen/include/asm-x86/current.h | 3 +- + xen/include/asm-x86/domain.h | 3 ++ + xen/include/asm-x86/flushtlb.h | 2 +- + xen/include/asm-x86/spec_ctrl.h | 4 ++ + 11 files changed, 118 insertions(+), 29 deletions(-) + +diff --git a/docs/misc/xen-command-line.markdown b/docs/misc/xen-command-line.markdown +index 4b8e4b66c2..bf3549385d 100644 +--- a/docs/misc/xen-command-line.markdown ++++ b/docs/misc/xen-command-line.markdown +@@ -1887,14 +1887,24 @@ clustered mode. The default, given no hint from the **FADT**, is cluster + mode. + + ### xpti +-> `= <boolean>` ++> `= List of [ default | <boolean> | dom0=<bool> | domu=<bool> ]` + +-> Default: `false` on AMD hardware ++> Default: `false` on hardware not to be vulnerable to Meltdown (e.g. AMD) + > Default: `true` everywhere else + + Override default selection of whether to isolate 64-bit PV guest page + tables. + ++`true` activates page table isolation even on hardware not vulnerable by ++Meltdown for all domains. ++ ++`false` deactivates page table isolation on all systems for all domains. ++ ++`default` sets the default behaviour. ++ ++With `dom0` and `domu` it is possible to control page table isolation ++for dom0 or guest domains only. ++ + ### xsave + > `= <boolean>` + +diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c +index 46068e5cc1..7587f1b79c 100644 +--- a/xen/arch/x86/domain.c ++++ b/xen/arch/x86/domain.c +@@ -380,6 +380,8 @@ int switch_compat(struct domain *d) + + d->arch.x87_fip_width = 4; + ++ d->arch.pv_domain.xpti = false; ++ + return 0; + + undo_and_fail: +@@ -683,6 +685,9 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags, + + /* 64-bit PV guest by default. */ + d->arch.is_32bit_pv = d->arch.has_32bit_shinfo = 0; ++ ++ d->arch.pv_domain.xpti = opt_xpti & (is_hardware_domain(d) ++ ? OPT_XPTI_DOM0 : OPT_XPTI_DOMU); + } + + /* initialize default tsc behavior in case tools don't */ +diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c +index d529f48a51..d42efd82b8 100644 +--- a/xen/arch/x86/mm.c ++++ b/xen/arch/x86/mm.c +@@ -512,8 +512,21 @@ void make_cr3(struct vcpu *v, unsigned long mfn) + + void write_ptbase(struct vcpu *v) + { +- get_cpu_info()->root_pgt_changed = true; +- switch_cr3(v->arch.cr3); ++ struct cpu_info *cpu_info = get_cpu_info(); ++ ++ if ( is_pv_vcpu(v) && v->domain->arch.pv_domain.xpti ) ++ { ++ cpu_info->root_pgt_changed = true; ++ cpu_info->pv_cr3 = __pa(this_cpu(root_pgt)); ++ switch_cr3(v->arch.cr3); ++ } ++ else ++ { ++ /* Make sure to clear xen_cr3 before pv_cr3; switch_cr3() serializes. */ ++ cpu_info->xen_cr3 = 0; ++ switch_cr3(v->arch.cr3); ++ cpu_info->pv_cr3 = 0; ++ } + } + + /* +diff --git a/xen/arch/x86/pv/dom0_build.c b/xen/arch/x86/pv/dom0_build.c +index 52aea4daac..ad3f031499 100644 +--- a/xen/arch/x86/pv/dom0_build.c ++++ b/xen/arch/x86/pv/dom0_build.c +@@ -385,6 +385,7 @@ int __init dom0_construct_pv(struct domain *d, + if ( compat32 ) + { + d->arch.is_32bit_pv = d->arch.has_32bit_shinfo = 1; ++ d->arch.pv_domain.xpti = false; + v->vcpu_info = (void *)&d->shared_info->compat.vcpu_info[0]; + if ( setup_compat_arg_xlat(v) != 0 ) + BUG(); +diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c +index bae9ca00f2..f67c5f1678 100644 +--- a/xen/arch/x86/setup.c ++++ b/xen/arch/x86/setup.c +@@ -152,9 +152,6 @@ static void __init parse_smap_param(char *s) + } + custom_param("smap", parse_smap_param); + +-static int8_t __initdata opt_xpti = -1; +-boolean_param("xpti", opt_xpti); +- + bool_t __read_mostly acpi_disabled; + bool_t __initdata acpi_force; + static char __initdata acpi_param[10] = ""; +@@ -1489,22 +1486,6 @@ void __init noreturn __start_xen(unsigned long mbi_p) + + cr4_pv32_mask = mmu_cr4_features & XEN_CR4_PV32_BITS; + +- if ( opt_xpti < 0 ) +- { +- uint64_t caps = 0; +- +- if ( boot_cpu_data.x86_vendor == X86_VENDOR_AMD ) +- caps = ARCH_CAPABILITIES_RDCL_NO; +- else if ( boot_cpu_has(X86_FEATURE_ARCH_CAPS) ) +- rdmsrl(MSR_ARCH_CAPABILITIES, caps); +- +- opt_xpti = !(caps & ARCH_CAPABILITIES_RDCL_NO); +- } +- if ( opt_xpti ) +- setup_clear_cpu_cap(X86_FEATURE_NO_XPTI); +- else +- setup_force_cpu_cap(X86_FEATURE_NO_XPTI); +- + if ( cpu_has_fsgsbase ) + set_in_cr4(X86_CR4_FSGSBASE); + +diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c +index 30b78e7272..0e35832f0b 100644 +--- a/xen/arch/x86/smpboot.c ++++ b/xen/arch/x86/smpboot.c +@@ -324,7 +324,7 @@ void start_secondary(void *unused) + spin_debug_disable(); + + get_cpu_info()->xen_cr3 = 0; +- get_cpu_info()->pv_cr3 = this_cpu(root_pgt) ? __pa(this_cpu(root_pgt)) : 0; ++ get_cpu_info()->pv_cr3 = 0; + + load_system_tables(); + +@@ -1052,7 +1052,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) + panic("Error %d setting up PV root page table\n", rc); + if ( per_cpu(root_pgt, 0) ) + { +- get_cpu_info()->pv_cr3 = __pa(per_cpu(root_pgt, 0)); ++ get_cpu_info()->pv_cr3 = 0; + + /* + * All entry points which may need to switch page tables have to start +diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c +index 11b02e73ba..80770006eb 100644 +--- a/xen/arch/x86/spec_ctrl.c ++++ b/xen/arch/x86/spec_ctrl.c +@@ -233,8 +233,9 @@ static void __init print_details(enum ind_thunk thunk, uint64_t caps) + boot_cpu_has(X86_FEATURE_SC_MSR_HVM) ? " MSR_SPEC_CTRL" : "", + boot_cpu_has(X86_FEATURE_SC_RSB_HVM) ? " RSB" : ""); + +- printk("XPTI: %s\n", +- boot_cpu_has(X86_FEATURE_NO_XPTI) ? "disabled" : "enabled"); ++ printk(" XPTI (64-bit PV only): Dom0 %s, DomU %s\n", ++ opt_xpti & OPT_XPTI_DOM0 ? "enabled" : "disabled", ++ opt_xpti & OPT_XPTI_DOMU ? "enabled" : "disabled"); + } + + /* Calculate whether Retpoline is known-safe on this CPU. */ +@@ -320,6 +321,70 @@ static bool __init retpoline_safe(uint64_t caps) + } + } + ++#define OPT_XPTI_DEFAULT 0xff ++uint8_t __read_mostly opt_xpti = OPT_XPTI_DEFAULT; ++ ++static __init void xpti_init_default(bool force) ++{ ++ uint64_t caps = 0; ++ ++ if ( !force && (opt_xpti != OPT_XPTI_DEFAULT) ) ++ return; ++ ++ if ( boot_cpu_data.x86_vendor == X86_VENDOR_AMD ) ++ caps = ARCH_CAPABILITIES_RDCL_NO; ++ else if ( boot_cpu_has(X86_FEATURE_ARCH_CAPS) ) ++ rdmsrl(MSR_ARCH_CAPABILITIES, caps); ++ ++ if ( caps & ARCH_CAPABILITIES_RDCL_NO ) ++ opt_xpti = 0; ++ else ++ opt_xpti = OPT_XPTI_DOM0 | OPT_XPTI_DOMU; ++} ++ ++static __init int parse_xpti(char *s) ++{ ++ char *ss; ++ int val, rc = 0; ++ ++ xpti_init_default(false); ++ ++ do { ++ ss = strchr(s, ','); ++ if ( ss ) ++ *ss = '\0'; ++ ++ switch ( parse_bool(s) ) ++ { ++ case 0: ++ opt_xpti = 0; ++ break; ++ ++ case 1: ++ opt_xpti = OPT_XPTI_DOM0 | OPT_XPTI_DOMU; ++ break; ++ ++ default: ++ if ( !strcmp(s, "default") ) ++ xpti_init_default(true); ++ else if ( (val = parse_boolean("dom0", s, ss)) >= 0 ) ++ opt_xpti = (opt_xpti & ~OPT_XPTI_DOM0) | ++ (val ? OPT_XPTI_DOM0 : 0); ++ else if ( (val = parse_boolean("domu", s, ss)) >= 0 ) ++ opt_xpti = (opt_xpti & ~OPT_XPTI_DOMU) | ++ (val ? OPT_XPTI_DOMU : 0); ++ else ++ rc = -EINVAL; ++ break; ++ } ++ ++ s = ss + 1; ++ } while ( ss ); ++ ++ return rc; ++} ++custom_param("xpti", parse_xpti); ++ + void __init init_speculation_mitigations(void) + { + enum ind_thunk thunk = THUNK_DEFAULT; +@@ -461,6 +526,12 @@ void __init init_speculation_mitigations(void) + if ( default_xen_spec_ctrl ) + setup_force_cpu_cap(X86_FEATURE_SC_MSR_IDLE); + ++ xpti_init_default(false); ++ if ( opt_xpti == 0 ) ++ setup_force_cpu_cap(X86_FEATURE_NO_XPTI); ++ else ++ setup_clear_cpu_cap(X86_FEATURE_NO_XPTI); ++ + print_details(thunk, caps); + + /* +diff --git a/xen/include/asm-x86/current.h b/xen/include/asm-x86/current.h +index f0061bd497..89add0e652 100644 +--- a/xen/include/asm-x86/current.h ++++ b/xen/include/asm-x86/current.h +@@ -44,7 +44,8 @@ struct cpu_info { + /* + * Of the two following fields the latter is being set to the CR3 value + * to be used on the given pCPU for loading whenever 64-bit PV guest +- * context is being entered. The value never changes once set. ++ * context is being entered. A value of zero indicates no setting of CR3 ++ * is to be performed. + * The former is the value to restore when re-entering Xen, if any. IOW + * its value being zero means there's nothing to restore. However, its + * value can also be negative, indicating to the exit-to-Xen code that +diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h +index cc1f7916c3..9d509cce54 100644 +--- a/xen/include/asm-x86/domain.h ++++ b/xen/include/asm-x86/domain.h +@@ -253,6 +253,9 @@ struct pv_domain + + atomic_t nr_l4_pages; + ++ /* XPTI active? */ ++ bool xpti; ++ + /* map_domain_page() mapping cache. */ + struct mapcache_domain mapcache; + +diff --git a/xen/include/asm-x86/flushtlb.h b/xen/include/asm-x86/flushtlb.h +index 834b113626..738ada9adb 100644 +--- a/xen/include/asm-x86/flushtlb.h ++++ b/xen/include/asm-x86/flushtlb.h +@@ -136,7 +136,7 @@ void flush_area_mask(const cpumask_t *, const void *va, unsigned int flags); + + #define flush_root_pgtbl_domain(d) \ + { \ +- if ( !cpu_has_no_xpti && is_pv_domain(d) && !is_pv_32bit_domain(d) ) \ ++ if ( is_pv_domain(d) && (d)->arch.pv_domain.xpti ) \ + flush_mask((d)->domain_dirty_cpumask, FLUSH_ROOT_PGTBL); \ + } + +diff --git a/xen/include/asm-x86/spec_ctrl.h b/xen/include/asm-x86/spec_ctrl.h +index 4678a40ba5..91bed1b476 100644 +--- a/xen/include/asm-x86/spec_ctrl.h ++++ b/xen/include/asm-x86/spec_ctrl.h +@@ -33,6 +33,10 @@ extern bool bsp_delay_spec_ctrl; + extern uint8_t default_xen_spec_ctrl; + extern uint8_t default_spec_ctrl_flags; + ++extern uint8_t opt_xpti; ++#define OPT_XPTI_DOM0 0x01 ++#define OPT_XPTI_DOMU 0x02 ++ + static inline void init_shadow_spec_ctrl_state(void) + { + struct cpu_info *info = get_cpu_info(); +-- +2.15.2 + diff --git a/main/xen/xsa267-4.9-1.patch b/main/xen/xsa267-4.9-1.patch new file mode 100644 index 0000000000..48e1e08bf3 --- /dev/null +++ b/main/xen/xsa267-4.9-1.patch @@ -0,0 +1,68 @@ +From: Andrew Cooper <andrew.cooper3@citrix.com> +Subject: x86: Support fully eager FPU context switching + +This is controlled on a per-vcpu bases for flexibility. + +This is part of XSA-267 / CVE-2018-3665 + +Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> +Reviewed-by: Jan Beulich <jbeulich@suse.com> + +diff --git a/xen/arch/x86/i387.c b/xen/arch/x86/i387.c +index 9a172db..1da31af 100644 +--- a/xen/arch/x86/i387.c ++++ b/xen/arch/x86/i387.c +@@ -210,7 +210,7 @@ void vcpu_restore_fpu_eager(struct vcpu *v) + ASSERT(!is_idle_vcpu(v)); + + /* Restore nonlazy extended state (i.e. parts not tracked by CR0.TS). */ +- if ( !v->arch.nonlazy_xstate_used ) ++ if ( !v->arch.fully_eager_fpu && !v->arch.nonlazy_xstate_used ) + return; + + /* Avoid recursion */ +@@ -221,11 +221,19 @@ void vcpu_restore_fpu_eager(struct vcpu *v) + * above) we also need to restore full state, to prevent subsequently + * saving state belonging to another vCPU. + */ +- if ( xstate_all(v) ) ++ if ( v->arch.fully_eager_fpu || (v->arch.xsave_area && xstate_all(v)) ) + { +- fpu_xrstor(v, XSTATE_ALL); ++ if ( cpu_has_xsave ) ++ fpu_xrstor(v, XSTATE_ALL); ++ else ++ fpu_fxrstor(v); ++ + v->fpu_initialised = 1; + v->fpu_dirtied = 1; ++ ++ /* Xen doesn't need TS set, but the guest might. */ ++ if ( is_pv_vcpu(v) && (v->arch.pv_vcpu.ctrlreg[0] & X86_CR0_TS) ) ++ stts(); + } + else + { +@@ -247,6 +255,8 @@ void vcpu_restore_fpu_lazy(struct vcpu *v) + if ( v->fpu_dirtied ) + return; + ++ ASSERT(!v->arch.fully_eager_fpu); ++ + if ( cpu_has_xsave ) + fpu_xrstor(v, XSTATE_LAZY); + else +diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h +index c08ddc0..702ec64 100644 +--- a/xen/include/asm-x86/domain.h ++++ b/xen/include/asm-x86/domain.h +@@ -593,6 +593,9 @@ struct arch_vcpu + * and thus should be saved/restored. */ + bool_t nonlazy_xstate_used; + ++ /* Restore all FPU state (lazy and non-lazy state) on context switch? */ ++ bool fully_eager_fpu; ++ + /* Has the guest enabled CPUID faulting? */ + bool cpuid_faulting; + diff --git a/main/xen/xsa267-4.9-2.patch b/main/xen/xsa267-4.9-2.patch new file mode 100644 index 0000000000..257d1e6e9c --- /dev/null +++ b/main/xen/xsa267-4.9-2.patch @@ -0,0 +1,220 @@ +From: Andrew Cooper <andrew.cooper3@citrix.com> +Subject: x86/spec-ctrl: Mitigations for LazyFPU + +Intel Core processors since at least Nehalem speculate past #NM, which is the +mechanism by which lazy FPU context switching is implemented. + +On affected processors, Xen must use fully eager FPU context switching to +prevent guests from being able to read FPU state (SSE/AVX/etc) from previously +scheduled vcpus. + +This is part of XSA-267 / CVE-2018-3665 + +Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> +Reviewed-by: Jan Beulich <jbeulich@suse.com> + +diff --git a/docs/misc/xen-command-line.markdown b/docs/misc/xen-command-line.markdown +index 6300f69..52ed051 100644 +--- a/docs/misc/xen-command-line.markdown ++++ b/docs/misc/xen-command-line.markdown +@@ -1635,7 +1635,7 @@ false disable the quirk workaround, which is also the default. + + ### spec-ctrl (x86) + > `= List of [ <bool>, xen=<bool>, {pv,hvm,msr-sc,rsb}=<bool>, +-> bti-thunk=retpoline|lfence|jmp, {ibrs,ibpb,ssbd}=<bool> ]` ++> bti-thunk=retpoline|lfence|jmp, {ibrs,ibpb,ssbd,eager-fpu}=<bool> ]` + + Controls for speculative execution sidechannel mitigations. By default, Xen + will pick the most appropriate mitigations based on compiled in support, +@@ -1685,6 +1685,11 @@ hardware, this is a global option applied at boot, and not virtualised for + guest use. On Intel hardware, the feature is virtualised for guests, + independently of Xen's choice of setting. + ++On all hardware, the `eager-fpu=` option can be used to force or prevent Xen ++from using fully eager FPU context switches. This is currently implemented as ++a global control. By default, Xen will choose to use fully eager context ++switches on hardware believed to speculate past #NM exceptions. ++ + ### sync\_console + > `= <boolean>` + +diff --git a/xen/arch/x86/i387.c b/xen/arch/x86/i387.c +index 1da31af..c3fda87 100644 +--- a/xen/arch/x86/i387.c ++++ b/xen/arch/x86/i387.c +@@ -15,6 +15,7 @@ + #include <asm/i387.h> + #include <asm/xstate.h> + #include <asm/asm_defns.h> ++#include <asm/spec_ctrl.h> + + /*******************************/ + /* FPU Restore Functions */ +@@ -307,6 +308,8 @@ int vcpu_init_fpu(struct vcpu *v) + { + int rc; + ++ v->arch.fully_eager_fpu = opt_eager_fpu; ++ + if ( (rc = xstate_alloc_save_area(v)) != 0 ) + return rc; + +diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c +index 8077000..ada4aac 100644 +--- a/xen/arch/x86/spec_ctrl.c ++++ b/xen/arch/x86/spec_ctrl.c +@@ -44,6 +44,7 @@ static enum ind_thunk { + static int8_t __initdata opt_ibrs = -1; + bool __read_mostly opt_ibpb = true; + bool __read_mostly opt_ssbd = false; ++int8_t __read_mostly opt_eager_fpu = -1; + + bool __initdata bsp_delay_spec_ctrl; + uint8_t __read_mostly default_xen_spec_ctrl; +@@ -114,6 +115,7 @@ static int __init parse_spec_ctrl(char *s) + opt_thunk = THUNK_JMP; + opt_ibrs = 0; + opt_ibpb = false; ++ opt_eager_fpu = 0; + } + else if ( val > 0 ) + rc = -EINVAL; +@@ -167,6 +169,8 @@ static int __init parse_spec_ctrl(char *s) + opt_ibpb = val; + else if ( (val = parse_boolean("ssbd", s, ss)) >= 0 ) + opt_ssbd = val; ++ else if ( (val = parse_boolean("eager-fpu", s, ss)) >= 0 ) ++ opt_eager_fpu = val; + else + rc = -EINVAL; + +@@ -223,15 +227,19 @@ static void __init print_details(enum ind_thunk thunk, uint64_t caps) + * Alternatives blocks for protecting against and/or virtualising + * mitigation support for guests. + */ +- printk(" Support for VMs: PV:%s%s%s, HVM:%s%s%s\n", ++ printk(" Support for VMs: PV:%s%s%s%s, HVM:%s%s%s%s\n", + (boot_cpu_has(X86_FEATURE_SC_MSR_PV) || +- boot_cpu_has(X86_FEATURE_SC_RSB_PV)) ? "" : " None", ++ boot_cpu_has(X86_FEATURE_SC_RSB_PV) || ++ opt_eager_fpu) ? "" : " None", + boot_cpu_has(X86_FEATURE_SC_MSR_PV) ? " MSR_SPEC_CTRL" : "", + boot_cpu_has(X86_FEATURE_SC_RSB_PV) ? " RSB" : "", ++ opt_eager_fpu ? " EAGER_FPU" : "", + (boot_cpu_has(X86_FEATURE_SC_MSR_HVM) || +- boot_cpu_has(X86_FEATURE_SC_RSB_HVM)) ? "" : " None", ++ boot_cpu_has(X86_FEATURE_SC_RSB_HVM) || ++ opt_eager_fpu) ? "" : " None", + boot_cpu_has(X86_FEATURE_SC_MSR_HVM) ? " MSR_SPEC_CTRL" : "", +- boot_cpu_has(X86_FEATURE_SC_RSB_HVM) ? " RSB" : ""); ++ boot_cpu_has(X86_FEATURE_SC_RSB_HVM) ? " RSB" : "", ++ opt_eager_fpu ? " EAGER_FPU" : ""); + + printk(" XPTI (64-bit PV only): Dom0 %s, DomU %s\n", + opt_xpti & OPT_XPTI_DOM0 ? "enabled" : "disabled", +@@ -321,6 +329,82 @@ static bool __init retpoline_safe(uint64_t caps) + } + } + ++/* Calculate whether this CPU speculates past #NM */ ++static bool __init should_use_eager_fpu(void) ++{ ++ /* ++ * Assume all unrecognised processors are ok. This is only known to ++ * affect Intel Family 6 processors. ++ */ ++ if ( boot_cpu_data.x86_vendor != X86_VENDOR_INTEL || ++ boot_cpu_data.x86 != 6 ) ++ return false; ++ ++ switch ( boot_cpu_data.x86_model ) ++ { ++ /* ++ * Core processors since at least Nehalem are vulnerable. ++ */ ++ case 0x1e: /* Nehalem */ ++ case 0x1f: /* Auburndale / Havendale */ ++ case 0x1a: /* Nehalem EP */ ++ case 0x2e: /* Nehalem EX */ ++ case 0x25: /* Westmere */ ++ case 0x2c: /* Westmere EP */ ++ case 0x2f: /* Westmere EX */ ++ case 0x2a: /* SandyBridge */ ++ case 0x2d: /* SandyBridge EP/EX */ ++ case 0x3a: /* IvyBridge */ ++ case 0x3e: /* IvyBridge EP/EX */ ++ case 0x3c: /* Haswell */ ++ case 0x3f: /* Haswell EX/EP */ ++ case 0x45: /* Haswell D */ ++ case 0x46: /* Haswell H */ ++ case 0x3d: /* Broadwell */ ++ case 0x47: /* Broadwell H */ ++ case 0x4f: /* Broadwell EP/EX */ ++ case 0x56: /* Broadwell D */ ++ case 0x4e: /* Skylake M */ ++ case 0x55: /* Skylake X */ ++ case 0x5e: /* Skylake D */ ++ case 0x66: /* Cannonlake */ ++ case 0x67: /* Cannonlake? */ ++ case 0x8e: /* Kabylake M */ ++ case 0x9e: /* Kabylake D */ ++ return true; ++ ++ /* ++ * Atom processors are not vulnerable. ++ */ ++ case 0x1c: /* Pineview */ ++ case 0x26: /* Lincroft */ ++ case 0x27: /* Penwell */ ++ case 0x35: /* Cloverview */ ++ case 0x36: /* Cedarview */ ++ case 0x37: /* Baytrail / Valleyview (Silvermont) */ ++ case 0x4d: /* Avaton / Rangely (Silvermont) */ ++ case 0x4c: /* Cherrytrail / Brasswell */ ++ case 0x4a: /* Merrifield */ ++ case 0x5a: /* Moorefield */ ++ case 0x5c: /* Goldmont */ ++ case 0x5f: /* Denverton */ ++ case 0x7a: /* Gemini Lake */ ++ return false; ++ ++ /* ++ * Knights processors are not vulnerable. ++ */ ++ case 0x57: /* Knights Landing */ ++ case 0x85: /* Knights Mill */ ++ return false; ++ ++ default: ++ printk("Unrecognised CPU model %#x - assuming vulnerable to LazyFPU\n", ++ boot_cpu_data.x86_model); ++ return true; ++ } ++} ++ + #define OPT_XPTI_DEFAULT 0xff + uint8_t __read_mostly opt_xpti = OPT_XPTI_DEFAULT; + +@@ -519,6 +603,10 @@ void __init init_speculation_mitigations(void) + if ( !boot_cpu_has(X86_FEATURE_IBRSB) && !boot_cpu_has(X86_FEATURE_IBPB) ) + opt_ibpb = false; + ++ /* Check whether Eager FPU should be enabled by default. */ ++ if ( opt_eager_fpu == -1 ) ++ opt_eager_fpu = should_use_eager_fpu(); ++ + /* (Re)init BSP state now that default_spec_ctrl_flags has been calculated. */ + init_shadow_spec_ctrl_state(); + +diff --git a/xen/include/asm-x86/spec_ctrl.h b/xen/include/asm-x86/spec_ctrl.h +index 91bed1b..5b40afb 100644 +--- a/xen/include/asm-x86/spec_ctrl.h ++++ b/xen/include/asm-x86/spec_ctrl.h +@@ -28,6 +28,7 @@ void init_speculation_mitigations(void); + + extern bool opt_ibpb; + extern bool opt_ssbd; ++extern int8_t opt_eager_fpu; + + extern bool bsp_delay_spec_ctrl; + extern uint8_t default_xen_spec_ctrl; |