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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
|
From db6ca8176ccc4ff7dfe3c06969af9ebfab0d7b04 Mon Sep 17 00:00:00 2001
From: Andrew Cooper <andrew.cooper3@citrix.com>
Date: Tue, 12 Jul 2022 11:13:33 +0200
Subject: [PATCH 37/51] x86/spec-ctrl: Knobs for STIBP and PSFD, and follow
hardware STIBP hint
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
STIBP and PSFD are slightly weird bits, because they're both implied by other
bits in MSR_SPEC_CTRL. Add fine grain controls for them, and take the
implications into account when setting IBRS/SSBD.
Rearrange the IBPB text/variables/logic to keep all the MSR_SPEC_CTRL bits
together, for consistency.
However, AMD have a hardware hint CPUID bit recommending that STIBP be set
unilaterally. This is advertised on Zen3, so follow the recommendation.
Furthermore, in such cases, set STIBP behind the guest's back for now. This
has negligible overhead for the guest, but saves a WRMSR on vmentry. This is
the only default change.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
master commit: fef244b179c06fcdfa581f7d57fa6e578c49ff50
master date: 2022-06-30 18:07:13 +0100
---
docs/misc/xen-command-line.pandoc | 21 +++++++---
xen/arch/x86/hvm/svm/vmcb.c | 9 +++++
xen/arch/x86/spec_ctrl.c | 67 ++++++++++++++++++++++++++-----
3 files changed, 82 insertions(+), 15 deletions(-)
diff --git a/docs/misc/xen-command-line.pandoc b/docs/misc/xen-command-line.pandoc
index a642e43476a2..46e9c58d35cd 100644
--- a/docs/misc/xen-command-line.pandoc
+++ b/docs/misc/xen-command-line.pandoc
@@ -2234,8 +2234,9 @@ By default SSBD will be mitigated at runtime (i.e `ssbd=runtime`).
### spec-ctrl (x86)
> `= List of [ <bool>, xen=<bool>, {pv,hvm,msr-sc,rsb,md-clear}=<bool>,
-> bti-thunk=retpoline|lfence|jmp, {ibrs,ibpb,ssbd,eager-fpu,
-> l1d-flush,branch-harden,srb-lock,unpriv-mmio}=<bool> ]`
+> bti-thunk=retpoline|lfence|jmp, {ibrs,ibpb,ssbd,psfd,
+> eager-fpu,l1d-flush,branch-harden,srb-lock,
+> unpriv-mmio}=<bool> ]`
Controls for speculative execution sidechannel mitigations. By default, Xen
will pick the most appropriate mitigations based on compiled in support,
@@ -2285,9 +2286,10 @@ On hardware supporting IBRS (Indirect Branch Restricted Speculation), the
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.
+On hardware supporting STIBP (Single Thread Indirect Branch Predictors), the
+`stibp=` option can be used to force or prevent Xen using the feature itself.
+By default, Xen will use STIBP when IBRS is in use (IBRS implies STIBP), and
+when hardware hints recommend using it as a blanket setting.
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
@@ -2295,6 +2297,15 @@ 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 hardware supporting PSFD (Predictive Store Forwarding Disable), the `psfd=`
+option can be used to force or prevent Xen using the feature itself. By
+default, Xen will not use PSFD. PSFD is implied by SSBD, and SSBD is off by
+default.
+
+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 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
diff --git a/xen/arch/x86/hvm/svm/vmcb.c b/xen/arch/x86/hvm/svm/vmcb.c
index 565e997155f2..ef7224eb5dd7 100644
--- a/xen/arch/x86/hvm/svm/vmcb.c
+++ b/xen/arch/x86/hvm/svm/vmcb.c
@@ -29,6 +29,7 @@
#include <asm/hvm/support.h>
#include <asm/hvm/svm/svm.h>
#include <asm/hvm/svm/svmdebug.h>
+#include <asm/spec_ctrl.h>
struct vmcb_struct *alloc_vmcb(void)
{
@@ -176,6 +177,14 @@ static int construct_vmcb(struct vcpu *v)
vmcb->_pause_filter_thresh = SVM_PAUSETHRESH_INIT;
}
+ /*
+ * When default_xen_spec_ctrl simply SPEC_CTRL_STIBP, default this behind
+ * the back of the VM too. Our SMT topology isn't accurate, the overhead
+ * is neglegable, and doing this saves a WRMSR on the vmentry path.
+ */
+ if ( default_xen_spec_ctrl == SPEC_CTRL_STIBP )
+ v->arch.msrs->spec_ctrl.raw = SPEC_CTRL_STIBP;
+
return 0;
}
diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c
index 1ed5ceda8b46..dfdd45c358c4 100644
--- a/xen/arch/x86/spec_ctrl.c
+++ b/xen/arch/x86/spec_ctrl.c
@@ -48,9 +48,13 @@ static enum ind_thunk {
THUNK_LFENCE,
THUNK_JMP,
} opt_thunk __initdata = THUNK_DEFAULT;
+
static int8_t __initdata opt_ibrs = -1;
+int8_t __initdata opt_stibp = -1;
+bool __read_mostly opt_ssbd;
+int8_t __initdata opt_psfd = -1;
+
bool __read_mostly opt_ibpb = true;
-bool __read_mostly opt_ssbd = false;
int8_t __read_mostly opt_eager_fpu = -1;
int8_t __read_mostly opt_l1d_flush = -1;
static bool __initdata opt_branch_harden = true;
@@ -172,12 +176,20 @@ static int __init parse_spec_ctrl(const char *s)
else
rc = -EINVAL;
}
+
+ /* Bits in MSR_SPEC_CTRL. */
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 if ( (val = parse_boolean("stibp", s, ss)) >= 0 )
+ opt_stibp = val;
else if ( (val = parse_boolean("ssbd", s, ss)) >= 0 )
opt_ssbd = val;
+ else if ( (val = parse_boolean("psfd", s, ss)) >= 0 )
+ opt_psfd = val;
+
+ /* Misc settings. */
+ else if ( (val = parse_boolean("ibpb", s, ss)) >= 0 )
+ opt_ibpb = val;
else if ( (val = parse_boolean("eager-fpu", s, ss)) >= 0 )
opt_eager_fpu = val;
else if ( (val = parse_boolean("l1d-flush", s, ss)) >= 0 )
@@ -376,7 +388,7 @@ static void __init print_details(enum ind_thunk thunk, uint64_t caps)
"\n");
/* Settings for Xen's protection, irrespective of guests. */
- printk(" Xen settings: BTI-Thunk %s, SPEC_CTRL: %s%s%s%s, Other:%s%s%s%s%s\n",
+ printk(" Xen settings: BTI-Thunk %s, SPEC_CTRL: %s%s%s%s%s, Other:%s%s%s%s%s\n",
thunk == THUNK_NONE ? "N/A" :
thunk == THUNK_RETPOLINE ? "RETPOLINE" :
thunk == THUNK_LFENCE ? "LFENCE" :
@@ -390,6 +402,9 @@ static void __init print_details(enum ind_thunk thunk, uint64_t caps)
(!boot_cpu_has(X86_FEATURE_SSBD) &&
!boot_cpu_has(X86_FEATURE_AMD_SSBD)) ? "" :
(default_xen_spec_ctrl & SPEC_CTRL_SSBD) ? " SSBD+" : " SSBD-",
+ (!boot_cpu_has(X86_FEATURE_PSFD) &&
+ !boot_cpu_has(X86_FEATURE_INTEL_PSFD)) ? "" :
+ (default_xen_spec_ctrl & SPEC_CTRL_PSFD) ? " PSFD+" : " PSFD-",
!(caps & ARCH_CAPS_TSX_CTRL) ? "" :
(opt_tsx & 1) ? " TSX+" : " TSX-",
!cpu_has_srbds_ctrl ? "" :
@@ -979,10 +994,7 @@ void __init init_speculation_mitigations(void)
if ( !has_spec_ctrl )
printk(XENLOG_WARNING "?!? CET active, but no MSR_SPEC_CTRL?\n");
else if ( opt_ibrs == -1 )
- {
opt_ibrs = ibrs = true;
- default_xen_spec_ctrl |= SPEC_CTRL_IBRS | SPEC_CTRL_STIBP;
- }
if ( opt_thunk == THUNK_DEFAULT || opt_thunk == THUNK_RETPOLINE )
thunk = THUNK_JMP;
@@ -1086,14 +1098,49 @@ void __init init_speculation_mitigations(void)
setup_force_cpu_cap(X86_FEATURE_SC_MSR_HVM);
}
- /* If we have IBRS available, see whether we should use it. */
+ /* Figure out default_xen_spec_ctrl. */
if ( has_spec_ctrl && ibrs )
- default_xen_spec_ctrl |= SPEC_CTRL_IBRS;
+ {
+ /* IBRS implies STIBP. */
+ if ( opt_stibp == -1 )
+ opt_stibp = 1;
+
+ default_xen_spec_ctrl |= SPEC_CTRL_IBRS;
+ }
+
+ /*
+ * Use STIBP by default if the hardware hint is set. Otherwise, leave it
+ * off as it a severe performance pentalty on pre-eIBRS Intel hardware
+ * where it was retrofitted in microcode.
+ */
+ if ( opt_stibp == -1 )
+ opt_stibp = !!boot_cpu_has(X86_FEATURE_STIBP_ALWAYS);
+
+ if ( opt_stibp && (boot_cpu_has(X86_FEATURE_STIBP) ||
+ boot_cpu_has(X86_FEATURE_AMD_STIBP)) )
+ default_xen_spec_ctrl |= SPEC_CTRL_STIBP;
- /* If we have SSBD available, see whether we should use it. */
if ( opt_ssbd && (boot_cpu_has(X86_FEATURE_SSBD) ||
boot_cpu_has(X86_FEATURE_AMD_SSBD)) )
+ {
+ /* SSBD implies PSFD */
+ if ( opt_psfd == -1 )
+ opt_psfd = 1;
+
default_xen_spec_ctrl |= SPEC_CTRL_SSBD;
+ }
+
+ /*
+ * Don't use PSFD by default. AMD designed the predictor to
+ * auto-clear on privilege change. PSFD is implied by SSBD, which is
+ * off by default.
+ */
+ if ( opt_psfd == -1 )
+ opt_psfd = 0;
+
+ if ( opt_psfd && (boot_cpu_has(X86_FEATURE_PSFD) ||
+ boot_cpu_has(X86_FEATURE_INTEL_PSFD)) )
+ default_xen_spec_ctrl |= SPEC_CTRL_PSFD;
/*
* PV guests can create RSB entries for any linear address they control,
--
2.35.1
|