diff mbox series

[6/7] KVM: nVMX: Enable load IA32_PERF_GLOBAL_CTRL vm control if supported

Message ID 20190828234134.132704-7-oupton@google.com (mailing list archive)
State New, archived
Headers show
Series KVM: VMX: Add full nested support for IA32_PERF_GLOBAL_CTRL | expand

Commit Message

Oliver Upton Aug. 28, 2019, 11:41 p.m. UTC
The "load IA32_PERF_GLOBAL_CTRL" high bit for VM-entry and VM-exit should only
be set and made available to the guest iff IA32_PERF_GLOBAL_CTRL is a valid
MSR. Otherwise, the high bit should be cleared.

Creating a new helper function in vmx.c to allow the pmu_refresh code to
update the VM-entry and VM-exit controls. This was done instead of
adding to 'nested_vmx_entry_exit_ctls_update' as the PMU isn't yet
initialized with its values at the time it is called, causing the
'is_valid_msr(vcpu, MSR_CORE_PERF_GLOBAL_CTRL)' check to fail
unconditionally.

Suggested-by: Jim Mattson <jmattson@google.com>
Signed-off-by: Oliver Upton <oupton@google.com>
---
 arch/x86/kvm/vmx/pmu_intel.c |  3 +++
 arch/x86/kvm/vmx/vmx.c       | 21 +++++++++++++++++++++
 arch/x86/kvm/vmx/vmx.h       |  1 +
 3 files changed, 25 insertions(+)

Comments

Jim Mattson Aug. 29, 2019, 5:28 p.m. UTC | #1
On Wed, Aug 28, 2019 at 4:41 PM Oliver Upton <oupton@google.com> wrote:
>
> The "load IA32_PERF_GLOBAL_CTRL" high bit for VM-entry and VM-exit should only
> be set and made available to the guest iff IA32_PERF_GLOBAL_CTRL is a valid
> MSR. Otherwise, the high bit should be cleared.
>
> Creating a new helper function in vmx.c to allow the pmu_refresh code to
> update the VM-entry and VM-exit controls. This was done instead of
> adding to 'nested_vmx_entry_exit_ctls_update' as the PMU isn't yet
> initialized with its values at the time it is called, causing the
> 'is_valid_msr(vcpu, MSR_CORE_PERF_GLOBAL_CTRL)' check to fail
> unconditionally.
>
> Suggested-by: Jim Mattson <jmattson@google.com>
> Signed-off-by: Oliver Upton <oupton@google.com>

One thing that's clear from this change (though it's not anything new)
is that KVM_SET_CPUID should be called before KVM_SET_MSRS, or
unexpected things might happen. Perhaps it's worth adding a note to
api.txt?
diff mbox series

Patch

diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c
index 4dea0e0e7e39..6d42d9b41ddc 100644
--- a/arch/x86/kvm/vmx/pmu_intel.c
+++ b/arch/x86/kvm/vmx/pmu_intel.c
@@ -16,6 +16,7 @@ 
 #include "cpuid.h"
 #include "lapic.h"
 #include "pmu.h"
+#include "vmx.h"
 
 static struct kvm_event_hw_type_mapping intel_arch_events[] = {
 	/* Index must match CPUID 0x0A.EBX bit vector */
@@ -314,6 +315,8 @@  static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
 	    (boot_cpu_has(X86_FEATURE_HLE) || boot_cpu_has(X86_FEATURE_RTM)) &&
 	    (entry->ebx & (X86_FEATURE_HLE|X86_FEATURE_RTM)))
 		pmu->reserved_bits ^= HSW_IN_TX|HSW_IN_TX_CHECKPOINTED;
+
+	nested_vmx_pmu_entry_exit_ctls_update(vcpu);
 }
 
 static void intel_pmu_init(struct kvm_vcpu *vcpu)
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index 42ed3faa6af8..2cad761c913c 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -6407,6 +6407,27 @@  void vmx_update_host_rsp(struct vcpu_vmx *vmx, unsigned long host_rsp)
 	}
 }
 
+void nested_vmx_pmu_entry_exit_ctls_update(struct kvm_vcpu *vcpu)
+{
+	struct vcpu_vmx *vmx;
+
+	if (!nested_vmx_allowed(vcpu))
+		return;
+
+	vmx = to_vmx(vcpu);
+	if (intel_pmu_ops.is_valid_msr(vcpu, MSR_CORE_PERF_GLOBAL_CTRL)) {
+		vmx->nested.msrs.entry_ctls_high |=
+				VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL;
+		vmx->nested.msrs.exit_ctls_high |=
+				VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL;
+	} else {
+		vmx->nested.msrs.entry_ctls_high &=
+				~VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL;
+		vmx->nested.msrs.exit_ctls_high &=
+				~VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL;
+	}
+}
+
 bool __vmx_vcpu_run(struct vcpu_vmx *vmx, unsigned long *regs, bool launched);
 
 static void vmx_vcpu_run(struct kvm_vcpu *vcpu)
diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h
index 82d0bc3a4d52..e06884cf88ad 100644
--- a/arch/x86/kvm/vmx/vmx.h
+++ b/arch/x86/kvm/vmx/vmx.h
@@ -331,6 +331,7 @@  void vmx_set_virtual_apic_mode(struct kvm_vcpu *vcpu);
 struct shared_msr_entry *find_msr_entry(struct vcpu_vmx *vmx, u32 msr);
 void pt_update_intercept_for_msr(struct vcpu_vmx *vmx);
 void vmx_update_host_rsp(struct vcpu_vmx *vmx, unsigned long host_rsp);
+void nested_vmx_pmu_entry_exit_ctls_update(struct kvm_vcpu *vcpu);
 
 #define POSTED_INTR_ON  0
 #define POSTED_INTR_SN  1