]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
KVM: x86: Advertise support for the immediate form of MSR instructions
authorXin Li <xin@zytor.com>
Tue, 5 Aug 2025 20:22:24 +0000 (13:22 -0700)
committerSean Christopherson <seanjc@google.com>
Tue, 19 Aug 2025 18:59:47 +0000 (11:59 -0700)
Advertise support for the immediate form of MSR instructions to userspace
if the instructions are supported by the underlying CPU, and KVM is using
VMX, i.e. is running on an Intel-compatible CPU.

For SVM, explicitly clear X86_FEATURE_MSR_IMM to ensure KVM doesn't over-
report support if AMD-compatible CPUs ever implement the immediate forms,
as SVM will likely require explicit enablement in KVM.

Signed-off-by: Xin Li (Intel) <xin@zytor.com>
[sean: massage changelog]
Link: https://lore.kernel.org/r/20250805202224.1475590-7-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
arch/x86/include/asm/kvm_host.h
arch/x86/kvm/cpuid.c
arch/x86/kvm/reverse_cpuid.h
arch/x86/kvm/svm/svm.c

index dbdec6025fde54ccd00a2283d91e021602b0e115..735b5d1e62ddd1b5347d25a9d958133ea33c0c56 100644 (file)
@@ -774,6 +774,7 @@ enum kvm_only_cpuid_leafs {
        CPUID_7_2_EDX,
        CPUID_24_0_EBX,
        CPUID_8000_0021_ECX,
+       CPUID_7_1_ECX,
        NR_KVM_CPU_CAPS,
 
        NKVMCAPINTS = NR_KVM_CPU_CAPS - NCAPINTS,
index bee8c869259f7a550688578ef29c2ddfa217735b..2705545f67feea1ad0014b5b1913c0be94d948b2 100644 (file)
@@ -985,6 +985,10 @@ void kvm_set_cpu_caps(void)
                F(LAM),
        );
 
+       kvm_cpu_cap_init(CPUID_7_1_ECX,
+               SCATTERED_F(MSR_IMM),
+       );
+
        kvm_cpu_cap_init(CPUID_7_1_EDX,
                F(AVX_VNNI_INT8),
                F(AVX_NE_CONVERT),
@@ -1411,9 +1415,9 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
                                goto out;
 
                        cpuid_entry_override(entry, CPUID_7_1_EAX);
+                       cpuid_entry_override(entry, CPUID_7_1_ECX);
                        cpuid_entry_override(entry, CPUID_7_1_EDX);
                        entry->ebx = 0;
-                       entry->ecx = 0;
                }
                if (max_idx >= 2) {
                        entry = do_host_cpuid(array, function, 2);
index c53b92379e6e65aa68b0741682f7219063462592..743ab25ba7872b77de8f0a0863559b52355b6c74 100644 (file)
@@ -25,6 +25,9 @@
 #define KVM_X86_FEATURE_SGX2           KVM_X86_FEATURE(CPUID_12_EAX, 1)
 #define KVM_X86_FEATURE_SGX_EDECCSSA   KVM_X86_FEATURE(CPUID_12_EAX, 11)
 
+/* Intel-defined sub-features, CPUID level 0x00000007:1 (ECX) */
+#define KVM_X86_FEATURE_MSR_IMM                KVM_X86_FEATURE(CPUID_7_1_ECX, 5)
+
 /* Intel-defined sub-features, CPUID level 0x00000007:1 (EDX) */
 #define X86_FEATURE_AVX_VNNI_INT8       KVM_X86_FEATURE(CPUID_7_1_EDX, 4)
 #define X86_FEATURE_AVX_NE_CONVERT      KVM_X86_FEATURE(CPUID_7_1_EDX, 5)
@@ -87,6 +90,7 @@ static const struct cpuid_reg reverse_cpuid[] = {
        [CPUID_7_2_EDX]       = {         7, 2, CPUID_EDX},
        [CPUID_24_0_EBX]      = {      0x24, 0, CPUID_EBX},
        [CPUID_8000_0021_ECX] = {0x80000021, 0, CPUID_ECX},
+       [CPUID_7_1_ECX]       = {         7, 1, CPUID_ECX},
 };
 
 /*
@@ -128,6 +132,7 @@ static __always_inline u32 __feature_translate(int x86_feature)
        KVM_X86_TRANSLATE_FEATURE(BHI_CTRL);
        KVM_X86_TRANSLATE_FEATURE(TSA_SQ_NO);
        KVM_X86_TRANSLATE_FEATURE(TSA_L1_NO);
+       KVM_X86_TRANSLATE_FEATURE(MSR_IMM);
        default:
                return x86_feature;
        }
index ca550c4fa1741b3e88b05bfb867d4a87cd63aaa2..7e7821ee8ee187f16f89394cda7171353af1ff31 100644 (file)
@@ -5311,8 +5311,12 @@ static __init void svm_set_cpu_caps(void)
        /* CPUID 0x8000001F (SME/SEV features) */
        sev_set_cpu_caps();
 
-       /* Don't advertise Bus Lock Detect to guest if SVM support is absent */
+       /*
+        * Clear capabilities that are automatically configured by common code,
+        * but that require explicit SVM support (that isn't yet implemented).
+        */
        kvm_cpu_cap_clear(X86_FEATURE_BUS_LOCK_DETECT);
+       kvm_cpu_cap_clear(X86_FEATURE_MSR_IMM);
 }
 
 static __init int svm_hardware_setup(void)