forked from QubesOS/qubes-vmm-xen
-
Notifications
You must be signed in to change notification settings - Fork 0
/
patch-0001-x86-spec-ctrl-Skip-RSB-overwriting-when-safe-to-do-s.patch
133 lines (122 loc) · 5.31 KB
/
patch-0001-x86-spec-ctrl-Skip-RSB-overwriting-when-safe-to-do-s.patch
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
From afab477fba3b4de4ad3887c27677737b96488091 Mon Sep 17 00:00:00 2001
From: Andrew Cooper <[email protected]>
Date: Thu, 19 Aug 2021 13:53:15 +0100
Subject: [PATCH] x86/spec-ctrl: Skip RSB overwriting when safe to do so
In some configurations, it is safe to not overwrite the RSB on entry to Xen.
Both Intel and AMD have guidelines in this area, because of the performance
difference it makes for native kernels.
A simple microperf test, measuring the amount of time a XENVER_version
hypercall takes, shows the following improvements:
KabyLake: -13.9175% +/- 6.85387%
CoffeeLake-R: -9.1183% +/- 5.04519%
Milan: -17.7803% +/- 1.29808%
This is best case improvement, because no real workloads are making
XENVER_version hypercalls in a tight loop. However, this is the hypercall
used by PV kernels to force evtchn delivery if one is pending, so it is a
common hypercall to see, especially in dom0.
The avoidance of RSB-overwriting speeds up all interrupts, exceptions and
system calls from PV or Xen context. RSB-overwriting is still required on
VMExit from HVM guests for now.
In terms of more realistic testing, LMBench in dom0 on an AMD Rome system
shows improvements across the board, with the best improvement at 8% for
simple syscall and simple write.
Signed-off-by: Andrew Cooper <[email protected]>
Reviewed-by: Jan Beulich <[email protected]>
---
xen/arch/x86/spec_ctrl.c | 67 ++++++++++++++++++++++++++++++++++------
1 file changed, 57 insertions(+), 10 deletions(-)
diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c
index 739b7913ff86..750110e9dfcc 100644
--- a/xen/arch/x86/spec_ctrl.c
+++ b/xen/arch/x86/spec_ctrl.c
@@ -33,7 +33,7 @@
/* 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 int8_t __initdata opt_rsb_pv = -1;
static bool __initdata opt_rsb_hvm = true;
static int8_t __initdata opt_md_clear_pv = -1;
static int8_t __initdata opt_md_clear_hvm = -1;
@@ -554,6 +554,35 @@ static bool __init retpoline_safe(uint64_t caps)
}
}
+/*
+ * https://software.intel.com/content/www/us/en/develop/articles/software-security-guidance/technical-documentation/retpoline-branch-target-injection-mitigation.html
+ *
+ * Silvermont and Airmont based cores are 64bit but only have a 32bit wide
+ * RSB, which impacts the safety of using SMEP to avoid RSB-overwriting.
+ */
+static bool __init rsb_is_full_width(void)
+{
+ if ( boot_cpu_data.x86_vendor != X86_VENDOR_INTEL ||
+ boot_cpu_data.x86 != 6 )
+ return true;
+
+ switch ( boot_cpu_data.x86_model )
+ {
+ case 0x37: /* Baytrail / Valleyview (Silvermont) */
+ case 0x4a: /* Merrifield */
+ case 0x4c: /* Cherrytrail / Brasswell */
+ case 0x4d: /* Avaton / Rangely (Silvermont) */
+ case 0x5a: /* Moorefield */
+ case 0x5d: /* SoFIA 3G Granite/ES2.1 */
+ case 0x65: /* SoFIA LTE AOSP */
+ case 0x6e: /* Cougar Mountain */
+ case 0x75: /* Lightning Mountain */
+ return false;
+ }
+
+ return true;
+}
+
/* Calculate whether this CPU speculates past #NM */
static bool __init should_use_eager_fpu(void)
{
@@ -992,18 +1021,36 @@ void __init init_speculation_mitigations(void)
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
- * of the Xen supervisor mappings.
+ * PV guests can create RSB entries for any linear address they control,
+ * which are outside of Xen's mappings.
+ *
+ * SMEP inhibits speculation to any user mappings, so in principle it is
+ * safe to not overwrite the RSB when SMEP is active.
+ *
+ * However, some caveats apply:
+ *
+ * 1) CALL instructions push the next sequential linear address into the
+ * RSB, meaning that there is a boundary case at the user=>supervisor
+ * split. This can be compensated for by having an unmapped or NX
+ * page, or an instruction which halts speculation.
*
- * With SMEP enabled, the processor won't speculate into user mappings.
- * Therefore, in this case, we don't need to worry about poisoned entries
- * from 64bit PV guests.
+ * For Xen, the next sequential linear address is the start of M2P
+ * (mapped NX), or a zapped hole (unmapped).
*
- * 32bit PV guest kernels run in ring 1, so use supervisor mappings.
- * If a processors speculates to 32bit PV guest kernel mappings, it is
- * speculating in 64bit supervisor mode, and can leak data.
+ * 2) 32bit PV kernels execute in Ring 1 and use supervisor mappings.
+ * SMEP offers no protection in this case.
+ *
+ * 3) Some CPUs have RSBs which are not full width, which allow the
+ * attacker's entries to alias Xen addresses.
+ *
+ * It is safe to turn off RSB stuffing when Xen is using SMEP itself, and
+ * 32bit PV guests are disabled, and when the RSB is full width.
*/
+ BUILD_BUG_ON(RO_MPT_VIRT_START != PML4_ADDR(256));
+ if ( opt_rsb_pv == -1 && boot_cpu_has(X86_FEATURE_XEN_SMEP) &&
+ !opt_pv32 && rsb_is_full_width() )
+ opt_rsb_pv = 0;
+
if ( opt_rsb_pv )
{
setup_force_cpu_cap(X86_FEATURE_SC_RSB_PV);
--
2.31.1