Merge tag 'kvm-x86-pmu-6.5' of https://github.com/kvm-x86/linux into HEAD
[sfrench/cifs-2.6.git] / arch / x86 / kvm / svm / svm.c
index e1e17c7dc7d52a11de17ee0c7f1ccf09720c9856..c75497f67593fada5ea71f3db5467db44ee0c52a 100644 (file)
@@ -752,7 +752,7 @@ static bool msr_write_intercepted(struct kvm_vcpu *vcpu, u32 msr)
 
        BUG_ON(offset == MSR_INVALID);
 
-       return !!test_bit(bit_write,  &tmp);
+       return test_bit(bit_write, &tmp);
 }
 
 static void set_msr_interception_bitmap(struct kvm_vcpu *vcpu, u32 *msrpm,
@@ -2939,9 +2939,10 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
 
                break;
        case MSR_IA32_CR_PAT:
-               if (!kvm_pat_valid(data))
-                       return 1;
-               vcpu->arch.pat = data;
+               ret = kvm_set_msr_common(vcpu, msr);
+               if (ret)
+                       break;
+
                svm->vmcb01.ptr->save.g_pat = data;
                if (is_guest_mode(vcpu))
                        nested_vmcb02_compute_g_pat(svm);
@@ -3510,7 +3511,7 @@ static bool svm_is_vnmi_pending(struct kvm_vcpu *vcpu)
        if (!is_vnmi_enabled(svm))
                return false;
 
-       return !!(svm->vmcb->control.int_ctl & V_NMI_BLOCKING_MASK);
+       return !!(svm->vmcb->control.int_ctl & V_NMI_PENDING_MASK);
 }
 
 static bool svm_set_vnmi_pending(struct kvm_vcpu *vcpu)
@@ -5025,9 +5026,22 @@ static __init void svm_set_cpu_caps(void)
            boot_cpu_has(X86_FEATURE_AMD_SSBD))
                kvm_cpu_cap_set(X86_FEATURE_VIRT_SSBD);
 
-       /* AMD PMU PERFCTR_CORE CPUID */
-       if (enable_pmu && boot_cpu_has(X86_FEATURE_PERFCTR_CORE))
-               kvm_cpu_cap_set(X86_FEATURE_PERFCTR_CORE);
+       if (enable_pmu) {
+               /*
+                * Enumerate support for PERFCTR_CORE if and only if KVM has
+                * access to enough counters to virtualize "core" support,
+                * otherwise limit vPMU support to the legacy number of counters.
+                */
+               if (kvm_pmu_cap.num_counters_gp < AMD64_NUM_COUNTERS_CORE)
+                       kvm_pmu_cap.num_counters_gp = min(AMD64_NUM_COUNTERS,
+                                                         kvm_pmu_cap.num_counters_gp);
+               else
+                       kvm_cpu_cap_check_and_set(X86_FEATURE_PERFCTR_CORE);
+
+               if (kvm_pmu_cap.version != 2 ||
+                   !kvm_cpu_cap_has(X86_FEATURE_PERFCTR_CORE))
+                       kvm_cpu_cap_clear(X86_FEATURE_PERFMON_V2);
+       }
 
        /* CPUID 0x8000001F (SME/SEV features) */
        sev_set_cpu_caps();