[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[xen stable-4.21] x86/spec-ctrl: Fix incomplete IBPB flushing during context switch



commit 3146587dbc489cce60cae471fd63ef822b5c05a4
Author:     Roger Pau Monné <roger.pau@xxxxxxxxxx>
AuthorDate: Tue Jan 27 14:02:52 2026 +0100
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Tue Jan 27 14:02:52 2026 +0100

    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@xxxxxxx>
    Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
    Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>
    master commit: 7beadd61197a959d5fa9d310fdeb7db3148f0c0d
    master date: 2026-01-27 13:55:27 +0100
---
 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 19fd86ce88..d8cf91ba34 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -2204,33 +2204,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 =
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.21



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.