From: Andrew Cooper <andrew.cooper3@citrix.com>
Subject: x86/spec-ctrl: Extend TSA-SQ/L1 mitigations to Zen5 CPUs

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 48a3185eed8d..e797585528d0 100644
--- a/xen/arch/x86/cpu-policy.c
+++ b/xen/arch/x86/cpu-policy.c
@@ -499,6 +499,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.family == 0x1a )
+        {
+            __set_bit(X86_FEATURE_TSA_SQ_NO, fs);
+            __set_bit(X86_FEATURE_TSA_L1_NO, fs);
+        }
         break;
     }
 
@@ -592,6 +609,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 8f77fe4cdb92..3132752090da 100644
--- a/xen/arch/x86/spec_ctrl.c
+++ b/xen/arch/x86/spec_ctrl.c
@@ -1467,18 +1467,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.family > 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.family != 0x19 )
+    if ( boot_cpu_data.family < 0x19 )
     {
         setup_force_cpu_cap(X86_FEATURE_TSA_SQ_NO);
         setup_force_cpu_cap(X86_FEATURE_TSA_L1_NO);
@@ -1486,7 +1490,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;
@@ -2254,6 +2258,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 72c1bde7e6fe..d750b490098e 100644
--- a/xen/include/public/arch-x86/cpufeatureset.h
+++ b/xen/include/public/arch-x86/cpufeatureset.h
@@ -402,8 +402,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 */
 
