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
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.
}
/*
- * 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);
/*
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 */