summaryrefslogtreecommitdiff
path: root/opt/xen/xsa479.patch
diff options
context:
space:
mode:
authorrawnix ports <ports@rawnix.org>2026-09-26 18:19:05 +0000
committerrawnix ports <ports@rawnix.org>2026-09-26 18:19:05 +0000
commitc82e88dd00d1b0b7fcfb4e5628d99611388cef6f (patch)
tree56d864b5a5c6c145edd96178ae219a8f90e191a6 /opt/xen/xsa479.patch
downloadports-c82e88dd00d1b0b7fcfb4e5628d99611388cef6f.tar.gz
sync 2026-09-26 18:19 UTC
1672 files changed, 151396 insertions(+)
Diffstat (limited to 'opt/xen/xsa479.patch')
-rw-r--r--opt/xen/xsa479.patch81
1 files changed, 81 insertions, 0 deletions
diff --git a/opt/xen/xsa479.patch b/opt/xen/xsa479.patch
new file mode 100644
index 0000000..448d46b
--- /dev/null
+++ b/opt/xen/xsa479.patch
@@ -0,0 +1,81 @@
+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 =