1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
From 5b223f41d59887ea5d13e2406597ff472ba6f2fc 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 482fe11..1995c4c 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -1746,6 +1746,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 f81fc2c..ee8b183 100644
--- a/xen/arch/x86/smpboot.c
+++ b/xen/arch/x86/smpboot.c
@@ -351,6 +351,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);
+
if ( xen_guest )
hypervisor_ap_setup();
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
|