]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
KVM: SVM: Advertise TSA CPUID bits to guests
authorBorislav Petkov <bp@kernel.org>
Tue, 15 Jul 2025 12:37:48 +0000 (14:37 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 17 Jul 2025 16:28:01 +0000 (18:28 +0200)
From: "Borislav Petkov (AMD)" <bp@alien8.de>

Commit 31272abd5974b38ba312e9cf2ec2f09f9dd7dcba upstream.

Synthesize the TSA CPUID feature bits for guests. Set TSA_{SQ,L1}_NO on
unaffected machines.

  [ backporting notes: 5.10 doesn't have the KVM-only CPUID leafs so
    allocate a separate capability leaf for CPUID_8000_0021_ECX to avoid
    backporting the world and more. ]

Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/x86/include/asm/cpufeature.h
arch/x86/include/asm/cpufeatures.h
arch/x86/include/asm/disabled-features.h
arch/x86/include/asm/required-features.h
arch/x86/kernel/cpu/scattered.c
arch/x86/kvm/cpuid.c
arch/x86/kvm/cpuid.h

index 955ca6b13e35f2cfbc86fd431d47bb9cc131443b..c8e966ed7aa4ff89abf7202fe48125d849f3c62e 100644 (file)
@@ -34,6 +34,7 @@ enum cpuid_leafs
        CPUID_8000_001F_EAX,
        CPUID_8000_0021_EAX,
        CPUID_LNX_5,
+       CPUID_8000_0021_ECX,
        NR_CPUID_WORDS,
 };
 
@@ -97,7 +98,7 @@ extern const char * const x86_bug_flags[NBUGINTS*32];
           CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 20, feature_bit) ||    \
           CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 21, feature_bit) ||    \
           REQUIRED_MASK_CHECK                                    ||    \
-          BUILD_BUG_ON_ZERO(NCAPINTS != 22))
+          BUILD_BUG_ON_ZERO(NCAPINTS != 23))
 
 #define DISABLED_MASK_BIT_SET(feature_bit)                             \
         ( CHECK_BIT_IN_MASK_WORD(DISABLED_MASK,  0, feature_bit) ||    \
@@ -123,7 +124,7 @@ extern const char * const x86_bug_flags[NBUGINTS*32];
           CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 20, feature_bit) ||    \
           CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 21, feature_bit) ||    \
           DISABLED_MASK_CHECK                                    ||    \
-          BUILD_BUG_ON_ZERO(NCAPINTS != 22))
+          BUILD_BUG_ON_ZERO(NCAPINTS != 23))
 
 #define cpu_has(c, bit)                                                        \
        (__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 :  \
index bc5221bc31ceb9e5884d67365b8709a8fa093a0b..ae0fbb168656945ca5f1f3cfc8786c3775543392 100644 (file)
@@ -13,7 +13,7 @@
 /*
  * Defines x86 CPU feature bits
  */
-#define NCAPINTS                       22         /* N 32-bit words worth of info */
+#define NCAPINTS                       23         /* N 32-bit words worth of info */
 #define NBUGINTS                       2          /* N 32-bit bug flags */
 
 /*
 #define X86_FEATURE_IBPB_BRTYPE                (20*32+28) /* "" MSR_PRED_CMD[IBPB] flushes all branch type predictions */
 #define X86_FEATURE_SRSO_NO            (20*32+29) /* "" CPU is not affected by SRSO */
 
-#define X86_FEATURE_TSA_SQ_NO          (21*32+11) /* "" AMD CPU not vulnerable to TSA-SQ */
-#define X86_FEATURE_TSA_L1_NO          (21*32+12) /* "" AMD CPU not vulnerable to TSA-L1 */
-#define X86_FEATURE_CLEAR_CPU_BUF_VM   (21*32+13) /* "" Clear CPU buffers using VERW before VMRUN */
+#define X86_FEATURE_TSA_SQ_NO          (22*32+11) /* "" AMD CPU not vulnerable to TSA-SQ */
+#define X86_FEATURE_TSA_L1_NO          (22*32+12) /* "" AMD CPU not vulnerable to TSA-L1 */
+#define X86_FEATURE_CLEAR_CPU_BUF_VM   (22*32+13) /* "" Clear CPU buffers using VERW before VMRUN */
 
 /*
  * BUG word(s)
index e5f44a3e275c1bf95e9c5382718f1bb34f8eeead..170c872533403889edbc534df26ad91257b25686 100644 (file)
 #define DISABLED_MASK19        0
 #define DISABLED_MASK20        0
 #define DISABLED_MASK21        0
-#define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 22)
+#define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 23)
 
 #endif /* _ASM_X86_DISABLED_FEATURES_H */
index 1fbe53583e9529c8860a9b848f17fe457243be40..4e3cd318323b2a04d7eb296f57b1dd0d5fb19f16 100644 (file)
 #define REQUIRED_MASK19        0
 #define REQUIRED_MASK20        0
 #define REQUIRED_MASK21        0
-#define REQUIRED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 22)
+#define REQUIRED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 23)
 
 #endif /* _ASM_X86_REQUIRED_FEATURES_H */
index 5356dc7fe3dc4e5c20181a747dceb61a6272860c..53a9a55dc0866ba10f5a97f5b7fcc9a728be83e2 100644 (file)
@@ -42,8 +42,6 @@ static const struct cpuid_bit cpuid_bits[] = {
        { X86_FEATURE_CPB,              CPUID_EDX,  9, 0x80000007, 0 },
        { X86_FEATURE_PROC_FEEDBACK,    CPUID_EDX, 11, 0x80000007, 0 },
        { X86_FEATURE_MBA,              CPUID_EBX,  6, 0x80000008, 0 },
-       { X86_FEATURE_TSA_SQ_NO,        CPUID_ECX,  1, 0x80000021, 0 },
-       { X86_FEATURE_TSA_L1_NO,        CPUID_ECX,  2, 0x80000021, 0 },
        { 0, 0, 0, 0, 0 }
 };
 
index 8ec86d2c1a4144e401e7b8939b7820e05d5bbbe9..ab0ae4a30fd1544ac50b1624d063874764892216 100644 (file)
@@ -500,6 +500,15 @@ void kvm_set_cpu_caps(void)
         */
        kvm_cpu_cap_mask(CPUID_8000_000A_EDX, 0);
 
+       if (cpu_feature_enabled(X86_FEATURE_VERW_CLEAR))
+               kvm_cpu_cap_set(X86_FEATURE_VERW_CLEAR);
+
+       if (cpu_feature_enabled(X86_FEATURE_TSA_SQ_NO))
+               kvm_cpu_cap_set(X86_FEATURE_TSA_SQ_NO);
+
+       if (cpu_feature_enabled(X86_FEATURE_TSA_L1_NO))
+               kvm_cpu_cap_set(X86_FEATURE_TSA_L1_NO);
+
        kvm_cpu_cap_mask(CPUID_C000_0001_EDX,
                F(XSTORE) | F(XSTORE_EN) | F(XCRYPT) | F(XCRYPT_EN) |
                F(ACE2) | F(ACE2_EN) | F(PHE) | F(PHE_EN) |
@@ -879,18 +888,21 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
                entry->eax = entry->ebx = entry->ecx = entry->edx = 0;
                break;
        case 0x80000021:
-               entry->ebx = entry->ecx = entry->edx = 0;
+               entry->ebx = entry->edx = 0;
                /*
                 * Pass down these bits:
                 *    EAX      0      NNDBP, Processor ignores nested data breakpoints
                 *    EAX      2      LAS, LFENCE always serializing
+                *    EAX      5      VERW_CLEAR, mitigate TSA
                 *    EAX      6      NSCB, Null selector clear base
                 *
                 * Other defined bits are for MSRs that KVM does not expose:
                 *   EAX      3      SPCL, SMM page configuration lock
                 *   EAX      13     PCMSR, Prefetch control MSR
                 */
-               entry->eax &= BIT(0) | BIT(2) | BIT(6);
+               cpuid_entry_override(entry, CPUID_8000_0021_EAX);
+               entry->eax &= BIT(0) | BIT(2) | BIT(5) | BIT(6);
+               cpuid_entry_override(entry, CPUID_8000_0021_ECX);
                break;
        /*Add support for Centaur's CPUID instruction*/
        case 0xC0000000:
index e25853c2eb0fc292394b63e47b014e5784e7f05d..88315d43d38066ba3e3be59f7f2e8ccde83cc69c 100644 (file)
@@ -64,6 +64,7 @@ static const struct cpuid_reg reverse_cpuid[] = {
        [CPUID_7_EDX]         = {         7, 0, CPUID_EDX},
        [CPUID_7_1_EAX]       = {         7, 1, CPUID_EAX},
        [CPUID_8000_0021_EAX] = {0x80000021, 0, CPUID_EAX},
+       [CPUID_8000_0021_ECX] = {0x80000021, 0, CPUID_ECX},
 };
 
 /*