-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
Xen Security Advisory CVE-2026-23553 / XSA-479
version 2
x86: incomplete IBPB for vCPU isolation
UPDATES IN VERSION 2
====================
Public release.
ISSUE DESCRIPTION
=================
In the context switch logic Xen attempts to skip an IBPB in the case of
a vCPU returning to a CPU on which it was the previous vCPU to run.
While safe for Xen's isolation between vCPUs, this prevents the guest
kernel correctly isolating between tasks. Consider:
1) vCPU runs on CPU A, running task 1.
2) vCPU moves to CPU B, idle gets scheduled on A. Xen skips IBPB.
3) On CPU B, guest kernel switches from task 1 to 2, issuing IBPB.
4) vCPU moves back to CPU A. Xen skips IBPB again.
Now, task 2 is running on CPU A with task 1's training still in the BTB.
IMPACT
======
Guest processes may leverage information leaks to obtain information
intended to be private to other entities in a guest.
VULNERABLE SYSTEMS
==================
Xen versions which had the XSA-254 fixes backported are vulnerable.
Upstream, that is 4.6 and newer.
Only x86 systems are vulnerable. Arm systems are not vulerable.
Systems vulnerable to SRSO (see XSA-434) with default settings use
IBPB-on-entry to protect against SRSO. This is a rather more aggressive
form of flushing than only on context switch, and is believed to be
sufficient to avoid the vulnerability.
MITIGATION
==========
Using "spec-ctrl=ibpb-entry=hvm,ibpb-entry=pv" on the Xen command line
will activate the SRSO mitigation on non-SRSO-vulnerable hardware, but
it is a large overhead.
CREDITS
=======
This issue was discovered by David Kaplan of AMD.
RESOLUTION
==========
Applying the attached patch resolves this issue.
Note that patches for released versions are generally prepared to
apply to the stable branches, and may not apply cleanly to the most
recent release tarball. Downstreams are encouraged to update to the
tip of the stable branch before applying these patches.
xsa479.patch xen-unstable - Xen 4.18.x
$ sha256sum xsa479*
82369898d0287e69272d0d65fb0e6be5fd0106bda19cedb3c9f6e75688f6fb4b xsa479.patch
$
DEPLOYMENT DURING EMBARGO
=========================
Deployment of the patches and/or mitigations described above (or
others which are substantially similar) is permitted during the
embargo, even on public-facing systems with untrusted guest users and
administrators.
But: Distribution of updated software is prohibited (except to other
members of the predisclosure list).
Predisclosure list members who wish to deploy significantly different
patches and/or mitigations, please contact the Xen Project Security
Team.
(Note: this during-embargo deployment notice is retained in
post-embargo publicly released Xen Project advisories, even though it
is then no longer applicable. This is to enable the community to have
oversight of the Xen Project Security Team's decisionmaking.)
For more information about permissible uses of embargoed information,
consult the Xen Project community's agreed Security Policy:
http://www.xenproject.org/security-policy.html
-----BEGIN PGP SIGNATURE-----
iQFABAEBCAAqFiEEI+MiLBRfRHX6gGCng/4UyVfoK9kFAml4qMMMHHBncEB4ZW4u
b3JnAAoJEIP+FMlX6CvZ4TgIAIObkH7IN/btMzEbjNp2aknZ+u2hgP2zu1j00Fwa
dyEi7Bug9X73vmgzLUWjHDCmvF3uoPl01KIjfh12v7s8dERKaTTxD1fGPOKliziA
rdZQJSICVTnrNex15aLONHxkJI3oVwo2JAXChBx1a4Zx9k7M6+Kv7o9xYlnQh27N
he3fmMrxWMCtTjngDgz7YhRonIYvA92wpRVCNklUulx9+oLHXllS8IKyf1rZvNr2
k2suwC82YG/wG6/vVUxZp45BTt45UC6YtengVRcyq70o9h8y6deSof0MoSuAewj7
05Z9kXac7pvGJTMTz2dUnHeRelaVU2Ps736vQSGgyJdIJ/c=
=jCcD
-----END PGP SIGNATURE-----
From: Roger Pau Monné <roger.pau@citrix.com>
Subject: x86/spec-ctrl: Fix incomplete IBPB flushing during context switch
The previous logic attempted to skip an IBPB in the case of vCPU returning to
a CPU on which it was the previous vCPU to run. While safe for Xen's
isolation between vCPUs, this prevents the guest kernel correctly isolation
between tasks. Consider:
1) vCPU runs on CPU A, running task 1.
2) vCPU moves to CPU B, idle gets scheduled on A. Xen skips IBPB.
3) On CPU B, guest kernel switches from task 1 to 2, issuing IBPB.
4) vCPU moves back to CPU A. Xen skips IBPB again.
Now, task 2 is running on CPU A with task 1's training still in the BTB.
Do the flush unconditionally when switching to a vCPU different than the
idle one. Note there's no need to explicitly gate the IBPB to next domain
!= idle, as the context where the IBPB is issued is subject to that
condition already unless the pCPU is going offline, at which point we don't
really care to issue an extra IBPB.
Also add a comment with the reasoning why the IBPB needs to be in
context_switch() rather than __context_switch().
This is XSA-479 / CVE-2026-23553.
Fixes: a2ed643ed783 ("x86/ctxt: Issue a speculation barrier between vcpu contexts")
Reported-by: David Kaplan <david.kaplan@amd.com>
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
xen/arch/x86/domain.c | 36 +++++++++---------------------------
1 file changed, 9 insertions(+), 27 deletions(-)
diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index c29a6b0decee..c1eded3eb604 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -2174,33 +2174,15 @@ void context_switch(struct vcpu *prev, struct vcpu *next)
ctxt_switch_levelling(next);
- if ( opt_ibpb_ctxt_switch && !is_idle_domain(nextd) )
- {
- static DEFINE_PER_CPU(unsigned int, last);
- unsigned int *last_id = &this_cpu(last);
-
- /*
- * Squash the domid and vcpu id together for comparison
- * efficiency. We could in principle stash and compare the struct
- * vcpu pointer, but this risks a false alias if a domain has died
- * and the same 4k page gets reused for a new vcpu.
- */
- unsigned int next_id = (((unsigned int)nextd->domain_id << 16) |
- (uint16_t)next->vcpu_id);
- BUILD_BUG_ON(MAX_VIRT_CPUS > 0xffff);
-
- /*
- * When scheduling from a vcpu, to idle, and back to the same vcpu
- * (which might be common in a lightly loaded system, or when
- * using vcpu pinning), there is no need to issue IBPB, as we are
- * returning to the same security context.
- */
- if ( *last_id != next_id )
- {
- spec_ctrl_new_guest_context();
- *last_id = next_id;
- }
- }
+ /*
+ * Issue an IBPB when scheduling a different vCPU if required.
+ *
+ * IBPB clears the RSB/RAS/RAP, but that's fine as we leave this
+ * function via reset_stack_and_call_ind() rather than via a RET
+ * instruction.
+ */
+ if ( opt_ibpb_ctxt_switch )
+ spec_ctrl_new_guest_context();
/* Update the top-of-stack block with the new speculation settings. */
info->scf =
© 2016 - 2026 Red Hat, Inc.