x86/cpu: Clear SVM feature if disabled by BIOS
authorPaolo Bonzini <pbonzini@redhat.com>
Thu, 21 Sep 2023 11:49:40 +0000 (07:49 -0400)
committerBorislav Petkov (AMD) <bp@alien8.de>
Fri, 22 Sep 2023 08:55:26 +0000 (10:55 +0200)
When SVM is disabled by BIOS, one cannot use KVM but the
SVM feature is still shown in the output of /proc/cpuinfo.
On Intel machines, VMX is cleared by init_ia32_feat_ctl(),
so do the same on AMD and Hygon processors.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Link: https://lore.kernel.org/r/20230921114940.957141-1-pbonzini@redhat.com
arch/x86/include/asm/msr-index.h
arch/x86/include/asm/svm.h
arch/x86/kernel/cpu/amd.c
arch/x86/kernel/cpu/hygon.c
arch/x86/kvm/svm/svm.c

index 1d111350197f3169a8eec402d77980dd617c6b95..6a6b0f763f67a35a8145119913adc0a49be2bd94 100644 (file)
 #define MSR_IA32_VMX_MISC_INTEL_PT                 (1ULL << 14)
 #define MSR_IA32_VMX_MISC_VMWRITE_SHADOW_RO_FIELDS (1ULL << 29)
 #define MSR_IA32_VMX_MISC_PREEMPTION_TIMER_SCALE   0x1F
-/* AMD-V MSRs */
 
+/* AMD-V MSRs */
 #define MSR_VM_CR                       0xc0010114
 #define MSR_VM_IGNNE                    0xc0010115
 #define MSR_VM_HSAVE_PA                 0xc0010117
 
+#define SVM_VM_CR_VALID_MASK           0x001fULL
+#define SVM_VM_CR_SVM_LOCK_MASK                0x0008ULL
+#define SVM_VM_CR_SVM_DIS_MASK         0x0010ULL
+
 /* Hardware Feedback Interface */
 #define MSR_IA32_HW_FEEDBACK_PTR        0x17d0
 #define MSR_IA32_HW_FEEDBACK_CONFIG     0x17d1
index 19bf955b67e0da097aa7e4187c0feecbf10268e4..fb8366af59da23bee79787e9e14e338cc75761ab 100644 (file)
@@ -229,10 +229,6 @@ struct __attribute__ ((__packed__)) vmcb_control_area {
 #define SVM_IOIO_SIZE_MASK (7 << SVM_IOIO_SIZE_SHIFT)
 #define SVM_IOIO_ASIZE_MASK (7 << SVM_IOIO_ASIZE_SHIFT)
 
-#define SVM_VM_CR_VALID_MASK   0x001fULL
-#define SVM_VM_CR_SVM_LOCK_MASK 0x0008ULL
-#define SVM_VM_CR_SVM_DIS_MASK  0x0010ULL
-
 #define SVM_NESTED_CTL_NP_ENABLE       BIT(0)
 #define SVM_NESTED_CTL_SEV_ENABLE      BIT(1)
 #define SVM_NESTED_CTL_SEV_ES_ENABLE   BIT(2)
@@ -571,8 +567,6 @@ struct vmcb {
 
 #define SVM_CPUID_FUNC 0x8000000a
 
-#define SVM_VM_CR_SVM_DISABLE 4
-
 #define SVM_SELECTOR_S_SHIFT 4
 #define SVM_SELECTOR_DPL_SHIFT 5
 #define SVM_SELECTOR_P_SHIFT 7
index dd8379d844452b17dceaa37ff2c6c45e65e1f0e1..1011ce20f513293a853322615c49bb433369e112 100644 (file)
@@ -1031,6 +1031,8 @@ static void zenbleed_check(struct cpuinfo_x86 *c)
 
 static void init_amd(struct cpuinfo_x86 *c)
 {
+       u64 vm_cr;
+
        early_init_amd(c);
 
        /*
@@ -1082,6 +1084,14 @@ static void init_amd(struct cpuinfo_x86 *c)
 
        init_amd_cacheinfo(c);
 
+       if (cpu_has(c, X86_FEATURE_SVM)) {
+               rdmsrl(MSR_VM_CR, vm_cr);
+               if (vm_cr & SVM_VM_CR_SVM_DIS_MASK) {
+                       pr_notice_once("SVM disabled (by BIOS) in MSR_VM_CR\n");
+                       clear_cpu_cap(c, X86_FEATURE_SVM);
+               }
+       }
+
        if (!cpu_has(c, X86_FEATURE_LFENCE_RDTSC) && cpu_has(c, X86_FEATURE_XMM2)) {
                /*
                 * Use LFENCE for execution serialization.  On families which
index defdc594be14dfc0979bada43c7f572cb5ca7ace..16f34639ecf75bb63f180b8ba122225306539507 100644 (file)
@@ -290,6 +290,8 @@ static void early_init_hygon(struct cpuinfo_x86 *c)
 
 static void init_hygon(struct cpuinfo_x86 *c)
 {
+       u64 vm_cr;
+
        early_init_hygon(c);
 
        /*
@@ -320,6 +322,14 @@ static void init_hygon(struct cpuinfo_x86 *c)
 
        init_hygon_cacheinfo(c);
 
+       if (cpu_has(c, X86_FEATURE_SVM)) {
+               rdmsrl(MSR_VM_CR, vm_cr);
+               if (vm_cr & SVM_VM_CR_SVM_DIS_MASK) {
+                       pr_notice_once("SVM disabled (by BIOS) in MSR_VM_CR\n");
+                       clear_cpu_cap(c, X86_FEATURE_SVM);
+               }
+       }
+
        if (cpu_has(c, X86_FEATURE_XMM2)) {
                /*
                 * Use LFENCE for execution serialization.  On families which
index f283eb47f6acec7d34453c2047536bfaa14b66c5..7b91efb72ea6e5f83a26ff105600ee7f6cb2962f 100644 (file)
@@ -531,8 +531,6 @@ static bool __kvm_is_svm_supported(void)
        int cpu = smp_processor_id();
        struct cpuinfo_x86 *c = &cpu_data(cpu);
 
-       u64 vm_cr;
-
        if (c->x86_vendor != X86_VENDOR_AMD &&
            c->x86_vendor != X86_VENDOR_HYGON) {
                pr_err("CPU %d isn't AMD or Hygon\n", cpu);
@@ -549,12 +547,6 @@ static bool __kvm_is_svm_supported(void)
                return false;
        }
 
-       rdmsrl(MSR_VM_CR, vm_cr);
-       if (vm_cr & (1 << SVM_VM_CR_SVM_DISABLE)) {
-               pr_err("SVM disabled (by BIOS) in MSR_VM_CR on CPU %d\n", cpu);
-               return false;
-       }
-
        return true;
 }