From 8c91436cb87928408110bfc77ba9e8018d0c0318 Mon Sep 17 00:00:00 2001
From: Andrew Cooper <andrew.cooper3@citrix.com>
Date: Fri, 16 Oct 2026 18:18:56 +0100
Subject: x86/spec-ctrl: Extend TSA-SQ/L1 mitigations to Zen5 CPUs
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

AMD previously said that Zen5 was not affected by TSA.  This statement has
been retracted, along with the recommendation to synthesise the TSA_SQ/L1_NO
bits on Zen5 CPUs.

Simply removing the synthesis of TSA_SQ/L1_NO creates a migration/resume
problem; VMs which had booted between July 2025 and Nov 2026 on Zen5 would no
longer be eligible to run on the same system as before.

Tolerate VMs which have seen TSA_SQ/L1_NO, despite knowing this to be an
unsafe configuration.  The VM is in no worse a position than before.

This is CVE-2024-36350 and CVE-2024-36357, part of XSA-525.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Roger Pau Monné <roger@xenproject.org>

diff --git a/xen/arch/x86/cpu-policy.c b/xen/arch/x86/cpu-policy.c
index aae8e4983c03..2645e208fa81 100644
--- a/xen/arch/x86/cpu-policy.c
+++ b/xen/arch/x86/cpu-policy.c
@@ -515,6 +515,23 @@ static void __init guest_common_max_feature_adjustments(uint32_t *fs)
          * has been around since the 286.
          */
         __set_bit(X86_FEATURE_VERW_CLEAR, fs);
+
+        /*
+         * Between July 2025 and Nov 2026, AMD had said that Zen5 was not
+         * vulnerable to TSA and to synthesise the TSA_SQ/L1_NO bits, but this
+         * statement has been retracted.
+         *
+         * VM's booted during that period on Zen5 CPUs will have seen the
+         * bits.  Tolerate such VMs; they'll be in no worse a position than
+         * prior to Nov 2026.
+         *
+         * Zen6 enumerates TSA_SQ/L1_NO, so there's no change from this logic.
+         */
+        if ( boot_cpu_data.x86 == 0x1a )
+        {
+            __set_bit(X86_FEATURE_TSA_SQ_NO, fs);
+            __set_bit(X86_FEATURE_TSA_L1_NO, fs);
+        }
         break;
     }
 
@@ -604,6 +621,20 @@ static void __init guest_common_default_feature_adjustments(uint32_t *fs)
          */
         if ( !cpu_has_verw_clear )
             __clear_bit(X86_FEATURE_VERW_CLEAR, fs);
+
+        /*
+         * Between July 2025 and Nov 2026, AMD had said that Zen5 was not
+         * vulnerable to TSA and to synthesise the TSA_SQ/L1_NO bits, but this
+         * statement has been retracted.
+         *
+         * The max policy has these set for migration compatibility, but a VM
+         * should not see them by default if the hardware is affected.
+         */
+        if ( !cpu_has_tsa_sq_no )
+            __clear_bit(X86_FEATURE_TSA_SQ_NO, fs);
+
+        if ( !cpu_has_tsa_l1_no )
+            __clear_bit(X86_FEATURE_TSA_L1_NO, fs);
         break;
     }
 
diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c
index e6a1551e0418..c2e6c49c442a 100644
--- a/xen/arch/x86/spec_ctrl.c
+++ b/xen/arch/x86/spec_ctrl.c
@@ -1566,18 +1566,22 @@ static void __init tsa_sq_l1_calculations(void)
         return;
 
     /*
-     * According to the whitepaper, some Fam1A CPUs (Models 0x00...0x4f,
-     * 0x60...0x7f) are not vulnerable but don't enumerate TSA_{SQ,L1}_NO.  If
-     * we see either enumerated, assume both are correct ...
+     * Zen6 and later are stated not to be vulnerable to the 3 known TSA
+     * variants, and enumerate all TSA_*_NO bits.
+     *
+     * Zen5 is vulnerable to all 3.  It gets VERW_CLEAR with new enough
+     * microcode, which is enumerated in CPUID.
+     *
+     * No synthesis should be performed.
      */
-    if ( cpu_has_tsa_sq_no || cpu_has_tsa_l1_no )
+    if ( boot_cpu_data.x86 > 0x19 )
         return;
 
     /*
-     * ... otherwise, synthesise them.  CPUs other than Fam19 (Zen3/4) are
-     * stated to be not vulnerable.
+     * Zen2 and older are stated not to be vulnerable, and need to synthesise
+     * TSA_SQ/L1_NO.
      */
-    if ( boot_cpu_data.x86 != 0x19 )
+    if ( boot_cpu_data.x86 < 0x19 )
     {
         setup_force_cpu_cap(X86_FEATURE_TSA_SQ_NO);
         setup_force_cpu_cap(X86_FEATURE_TSA_L1_NO);
@@ -1585,7 +1589,7 @@ static void __init tsa_sq_l1_calculations(void)
     }
 
     /*
-     * Fam19 CPUs get VERW_CLEAR with new enough microcode, but must
+     * Zen3 and Zen4 get VERW_CLEAR with new enough microcode, but must
      * synthesise the CPUID bit.
      */
     curr_rev = this_cpu(cpu_sig).rev;
@@ -2353,6 +2357,9 @@ void __init init_speculation_mitigations(void)
      *   Note, these microcode updates were produced before the remediation of
      *   the microcode signature issues, and are included in the firwmare
      *   updates fixing the entrysign vulnerability from ~December 2024.
+     *
+     * - September 2026, for TSA-L1/SQ/Fill.  Introduces VERW side effects on
+     *   Zen5, and enumerates VERW_CLEAR.
      */
     mds_calculations();
     rfds_calculations();
diff --git a/xen/include/public/arch-x86/cpufeatureset.h b/xen/include/public/arch-x86/cpufeatureset.h
index 7b80cd0c19c5..55b77506698d 100644
--- a/xen/include/public/arch-x86/cpufeatureset.h
+++ b/xen/include/public/arch-x86/cpufeatureset.h
@@ -350,8 +350,8 @@ XEN_CPUFEATURE(PB_OPT_CTRL,        16*32+32) /*   MSR_PB_OPT_CTRL.IBPB_ALT */
 XEN_CPUFEATURE(ITS_NO,             16*32+62) /*!A No Indirect Target Selection */
 
 /* AMD-defined CPU features, CPUID level 0x80000021.ecx, word 18 */
-XEN_CPUFEATURE(TSA_SQ_NO,          18*32+ 1) /*A  No Store Queue Transitive Scheduler Attacks */
-XEN_CPUFEATURE(TSA_L1_NO,          18*32+ 2) /*A  No L1D Transitive Scheduler Attacks */
+XEN_CPUFEATURE(TSA_SQ_NO,          18*32+ 1) /*!A No Store Queue Transitive Scheduler Attacks */
+XEN_CPUFEATURE(TSA_L1_NO,          18*32+ 2) /*!A No L1D Transitive Scheduler Attacks */
 
 #endif /* XEN_CPUFEATURE */
 
