Arch v4 supports streamlined Freeze_LBR_on_PMI, so we set the GLOBAL_STATUS_LBRS_FROZEN bit when the guest reads the global status msr with freezing lbr in use. Signed-off-by: Wei Wang <wei.w.wang@xxxxxxxxx> Cc: Paolo Bonzini <pbonzini@xxxxxxxxxx> Cc: Andi Kleen <ak@xxxxxxxxxxxxxxx> --- arch/x86/kvm/vmx/pmu_intel.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c index bf40941..80d3fcf 100644 --- a/arch/x86/kvm/vmx/pmu_intel.c +++ b/arch/x86/kvm/vmx/pmu_intel.c @@ -420,6 +420,25 @@ static bool intel_pmu_access_lbr_msr(struct kvm_vcpu *vcpu, return ret; } +static void intel_pmu_get_global_status(struct kvm_pmu *pmu, + struct msr_data *msr_info) +{ + u64 guest_debugctl, freeze_lbr_bits = DEBUGCTLMSR_FREEZE_LBRS_ON_PMI | + DEBUGCTLMSR_LBR; + + if (!pmu->global_status) { + msr_info->data = 0; + return; + } + + msr_info->data = pmu->global_status; + if (pmu->version >= 4) { + guest_debugctl = vmcs_read64(GUEST_IA32_DEBUGCTL); + if ((guest_debugctl & freeze_lbr_bits) == freeze_lbr_bits) + msr_info->data |= GLOBAL_STATUS_LBRS_FROZEN; + } +} + static int intel_pmu_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) { struct kvm_pmu *pmu = vcpu_to_pmu(vcpu); @@ -431,7 +450,7 @@ static int intel_pmu_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) msr_info->data = pmu->fixed_ctr_ctrl; return 0; case MSR_CORE_PERF_GLOBAL_STATUS: - msr_info->data = pmu->global_status; + intel_pmu_get_global_status(pmu, msr_info); return 0; case MSR_CORE_PERF_GLOBAL_CTRL: msr_info->data = pmu->global_ctrl; -- 2.7.4