aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Christopherson <sean.j.christopherson@intel.com>2019-05-08 12:08:19 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2019-05-15 17:19:19 -0400
commitf93f7ede087f2edcc18e4b02310df5749a6b5a61 (patch)
tree2fa96b9bec29a50b1edc559370267539943bcc19
parent61455bf26236e7f3d72705382a6437fdfd1bd0af (diff)
Revert "KVM: nVMX: Expose RDPMC-exiting only when guest supports PMU"
The RDPMC-exiting control is dependent on the existence of the RDPMC instruction itself, i.e. is not tied to the "Architectural Performance Monitoring" feature. For all intents and purposes, the control exists on all CPUs with VMX support since RDPMC also exists on all VCPUs with VMX supported. Per Intel's SDM: The RDPMC instruction was introduced into the IA-32 Architecture in the Pentium Pro processor and the Pentium processor with MMX technology. The earlier Pentium processors have performance-monitoring counters, but they must be read with the RDMSR instruction. Because RDPMC-exiting always exists, KVM requires the control and refuses to load if it's not available. As a result, hiding the PMU from a guest breaks nested virtualization if the guest attemts to use KVM. While it's not explicitly stated in the RDPMC pseudocode, the VM-Exit check for RDPMC-exiting follows standard fault vs. VM-Exit prioritization for privileged instructions, e.g. occurs after the CPL/CR0.PE/CR4.PCE checks, but before the counter referenced in ECX is checked for validity. In other words, the original KVM behavior of injecting a #GP was correct, and the KVM unit test needs to be adjusted accordingly, e.g. eat the #GP when the unit test guest (L3 in this case) executes RDPMC without RDPMC-exiting set in the unit test host (L2). This reverts commit e51bfdb68725dc052d16241ace40ea3140f938aa. Fixes: e51bfdb68725 ("KVM: nVMX: Expose RDPMC-exiting only when guest supports PMU") Reported-by: David Hill <hilld@binarystorm.net> Cc: Saar Amar <saaramar@microsoft.com> Cc: Mihai Carabas <mihai.carabas@oracle.com> Cc: Jim Mattson <jmattson@google.com> Cc: Liran Alon <liran.alon@oracle.com> Cc: stable@vger.kernel.org Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--arch/x86/kvm/vmx/vmx.c25
1 files changed, 0 insertions, 25 deletions
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index 60306f19105d..0db7ded18951 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -6866,30 +6866,6 @@ static void nested_vmx_entry_exit_ctls_update(struct kvm_vcpu *vcpu)
6866 } 6866 }
6867} 6867}
6868 6868
6869static bool guest_cpuid_has_pmu(struct kvm_vcpu *vcpu)
6870{
6871 struct kvm_cpuid_entry2 *entry;
6872 union cpuid10_eax eax;
6873
6874 entry = kvm_find_cpuid_entry(vcpu, 0xa, 0);
6875 if (!entry)
6876 return false;
6877
6878 eax.full = entry->eax;
6879 return (eax.split.version_id > 0);
6880}
6881
6882static void nested_vmx_procbased_ctls_update(struct kvm_vcpu *vcpu)
6883{
6884 struct vcpu_vmx *vmx = to_vmx(vcpu);
6885 bool pmu_enabled = guest_cpuid_has_pmu(vcpu);
6886
6887 if (pmu_enabled)
6888 vmx->nested.msrs.procbased_ctls_high |= CPU_BASED_RDPMC_EXITING;
6889 else
6890 vmx->nested.msrs.procbased_ctls_high &= ~CPU_BASED_RDPMC_EXITING;
6891}
6892
6893static void update_intel_pt_cfg(struct kvm_vcpu *vcpu) 6869static void update_intel_pt_cfg(struct kvm_vcpu *vcpu)
6894{ 6870{
6895 struct vcpu_vmx *vmx = to_vmx(vcpu); 6871 struct vcpu_vmx *vmx = to_vmx(vcpu);
@@ -6978,7 +6954,6 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu)
6978 if (nested_vmx_allowed(vcpu)) { 6954 if (nested_vmx_allowed(vcpu)) {
6979 nested_vmx_cr_fixed1_bits_update(vcpu); 6955 nested_vmx_cr_fixed1_bits_update(vcpu);
6980 nested_vmx_entry_exit_ctls_update(vcpu); 6956 nested_vmx_entry_exit_ctls_update(vcpu);
6981 nested_vmx_procbased_ctls_update(vcpu);
6982 } 6957 }
6983 6958
6984 if (boot_cpu_has(X86_FEATURE_INTEL_PT) && 6959 if (boot_cpu_has(X86_FEATURE_INTEL_PT) &&