@@ -340,6 +340,9 @@ void kvm_pmu_handle_event(struct kvm_vcpu *vcpu)
*/
if (unlikely(pmu->need_cleanup))
kvm_pmu_cleanup(vcpu);
+
+ if (kvm_x86_ops.pmu_ops->handle_event)
+ kvm_x86_ops.pmu_ops->handle_event(vcpu);
}
/* check if idx is a valid index to access PMU */
@@ -45,6 +45,7 @@ struct kvm_pmu_ops {
void (*refresh)(struct kvm_vcpu *vcpu);
void (*init)(struct kvm_vcpu *vcpu);
void (*reset)(struct kvm_vcpu *vcpu);
+ void (*handle_event)(struct kvm_vcpu *vcpu);
};
static inline u64 pmc_bitmask(struct kvm_pmc *pmc)
@@ -491,6 +491,14 @@ static void intel_pmu_reset(struct kvm_vcpu *vcpu)
pmu->global_ovf_ctrl = 0;
}
+static void intel_pmu_handle_event(struct kvm_vcpu *vcpu)
+{
+ struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
+
+ if (!(pmu->global_ctrl & pmu->pebs_enable))
+ return;
+}
+
struct kvm_pmu_ops intel_pmu_ops = {
.find_arch_event = intel_find_arch_event,
.find_fixed_event = intel_find_fixed_event,
@@ -505,4 +513,5 @@ struct kvm_pmu_ops intel_pmu_ops = {
.refresh = intel_pmu_refresh,
.init = intel_pmu_init,
.reset = intel_pmu_reset,
+ .handle_event = intel_pmu_handle_event,
};
@@ -6542,9 +6542,6 @@ static void atomic_switch_perf_msrs(struct vcpu_vmx *vmx)
if (!msrs)
return;
- if (pmu->counter_cross_mapped)
- msrs[1].guest = 0;
-
if (nr_msrs > 2 && msrs[1].guest) {
msrs[2].guest = pmu->ds_area;
if (nr_msrs > 3)
To emulate PEBS facility, KVM may needs setup context such as guest DS PEBS fields correctly before vm-entry and this part will be implemented in the vmx handle_event() hook. When the cross-map happens to any enabled PEBS counter, it will make PMU request and exit to kvm_pmu_handle_event() for some rewrite stuff and then back to cross-map check again and finally to vm-entry. In this hook, KVM would rewrite the state for the guest and it won't move events, hence races with the NMI PMI are not a problem. Signed-off-by: Like Xu <like.xu@linux.intel.com> --- arch/x86/kvm/pmu.c | 3 +++ arch/x86/kvm/pmu.h | 1 + arch/x86/kvm/vmx/pmu_intel.c | 9 +++++++++ arch/x86/kvm/vmx/vmx.c | 3 --- 4 files changed, 13 insertions(+), 3 deletions(-)