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
|
From bb27e11c56963e170d1f6d2fbddbc956f7164121 Mon Sep 17 00:00:00 2001
From: Andrew Cooper <andrew.cooper3@citrix.com>
Date: Tue, 2 Apr 2024 16:17:25 +0200
Subject: [PATCH 60/67] x86/cpu-policy: Hide x2APIC from PV guests
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
PV guests can't write to MSR_APIC_BASE (in order to set EXTD), nor can they
access any of the x2APIC MSR range. Therefore they mustn't see the x2APIC
CPUID bit saying that they can.
Right now, the host x2APIC flag filters into PV guests, meaning that PV guests
generally see x2APIC except on Zen1-and-older AMD systems.
Linux works around this by explicitly hiding the bit itself, and filtering
EXTD out of MSR_APIC_BASE reads. NetBSD behaves more in the spirit of PV
guests, and entirely ignores the APIC when built as a PV guest.
Change the annotation from !A to !S. This has a consequence of stripping it
out of both PV featuremasks. However, as existing guests may have seen the
bit, set it back into the PV Max policy; a VM which saw the bit and is alive
enough to migrate will have ignored it one way or another.
Hiding x2APIC does change the contents of leaf 0xb, but as the information is
nonsense to begin with, this is likely an improvement on the status quo.
Xen's blind assumption that APIC_ID = vCPU_ID * 2 isn't interlinked with the
host's topology structure, where a PV guest may see real host values, and the
APIC_IDs are useless without an MADT to start with. Dom0 is the only PV VM to
get an MADT but it's the host one, meaning the two sets of APIC_IDs are from
different address spaces.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
master commit: 5420aa165dfa5fe95dd84bb71cb96c15459935b1
master date: 2024-03-01 20:14:19 +0000
---
xen/arch/x86/cpu-policy.c | 11 +++++++++--
xen/include/public/arch-x86/cpufeatureset.h | 2 +-
2 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/xen/arch/x86/cpu-policy.c b/xen/arch/x86/cpu-policy.c
index 96c2cee1a8..ed64d56294 100644
--- a/xen/arch/x86/cpu-policy.c
+++ b/xen/arch/x86/cpu-policy.c
@@ -559,6 +559,14 @@ static void __init calculate_pv_max_policy(void)
for ( i = 0; i < ARRAY_SIZE(fs); ++i )
fs[i] &= pv_max_featuremask[i];
+ /*
+ * Xen at the time of writing (Feb 2024, 4.19 dev cycle) used to leak the
+ * host x2APIC capability into PV guests, but never supported the guest
+ * trying to turn x2APIC mode on. Tolerate an incoming VM which saw the
+ * x2APIC CPUID bit and is alive enough to migrate.
+ */
+ __set_bit(X86_FEATURE_X2APIC, fs);
+
/*
* If Xen isn't virtualising MSR_SPEC_CTRL for PV guests (functional
* availability, or admin choice), hide the feature.
@@ -837,11 +845,10 @@ void recalculate_cpuid_policy(struct domain *d)
}
/*
- * Allow the toolstack to set HTT, X2APIC and CMP_LEGACY. These bits
+ * Allow the toolstack to set HTT and CMP_LEGACY. These bits
* affect how to interpret topology information in other cpuid leaves.
*/
__set_bit(X86_FEATURE_HTT, max_fs);
- __set_bit(X86_FEATURE_X2APIC, max_fs);
__set_bit(X86_FEATURE_CMP_LEGACY, max_fs);
/*
diff --git a/xen/include/public/arch-x86/cpufeatureset.h b/xen/include/public/arch-x86/cpufeatureset.h
index 113e6cadc1..bc971f3c6f 100644
--- a/xen/include/public/arch-x86/cpufeatureset.h
+++ b/xen/include/public/arch-x86/cpufeatureset.h
@@ -123,7 +123,7 @@ XEN_CPUFEATURE(PCID, 1*32+17) /*H Process Context ID */
XEN_CPUFEATURE(DCA, 1*32+18) /* Direct Cache Access */
XEN_CPUFEATURE(SSE4_1, 1*32+19) /*A Streaming SIMD Extensions 4.1 */
XEN_CPUFEATURE(SSE4_2, 1*32+20) /*A Streaming SIMD Extensions 4.2 */
-XEN_CPUFEATURE(X2APIC, 1*32+21) /*!A Extended xAPIC */
+XEN_CPUFEATURE(X2APIC, 1*32+21) /*!S Extended xAPIC */
XEN_CPUFEATURE(MOVBE, 1*32+22) /*A movbe instruction */
XEN_CPUFEATURE(POPCNT, 1*32+23) /*A POPCNT instruction */
XEN_CPUFEATURE(TSC_DEADLINE, 1*32+24) /*S TSC Deadline Timer */
--
2.44.0
|