On 01/02/21 06:10, Like Xu wrote:
Usespace could set the bits [0, 5] of the IA32_PERF_CAPABILITIES
MSR which tells about the record format stored in the LBR records.

The LBR will be enabled on the guest if host perf supports LBR
(checked via x86_perf_get_lbr()) and the vcpu model is compatible
with the host one.

Signed-off-by: Like Xu <like...@linux.intel.com>
---
  arch/x86/kvm/vmx/capabilities.h |  1 +
  arch/x86/kvm/vmx/pmu_intel.c    | 17 +++++++++++++++++
  arch/x86/kvm/vmx/vmx.c          |  7 +++++++
  arch/x86/kvm/vmx/vmx.h          | 11 +++++++++++
  4 files changed, 36 insertions(+)

diff --git a/arch/x86/kvm/vmx/capabilities.h b/arch/x86/kvm/vmx/capabilities.h
index a58cf3655351..db1178a66d93 100644
--- a/arch/x86/kvm/vmx/capabilities.h
+++ b/arch/x86/kvm/vmx/capabilities.h
@@ -19,6 +19,7 @@ extern int __read_mostly pt_mode;
  #define PT_MODE_HOST_GUEST    1
#define PMU_CAP_FW_WRITES (1ULL << 13)
+#define PMU_CAP_LBR_FMT                0x3f
struct nested_vmx_msrs {
        /*
diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c
index f632039173ff..01b2cd8eca47 100644
--- a/arch/x86/kvm/vmx/pmu_intel.c
+++ b/arch/x86/kvm/vmx/pmu_intel.c
@@ -168,6 +168,21 @@ static inline struct kvm_pmc *get_fw_gp_pmc(struct kvm_pmu 
*pmu, u32 msr)
        return get_gp_pmc(pmu, msr, MSR_IA32_PMC0);
  }
+bool intel_pmu_lbr_is_compatible(struct kvm_vcpu *vcpu)
+{
+       struct x86_pmu_lbr *lbr = vcpu_to_lbr_records(vcpu);
+
+       /*
+        * As a first step, a guest could only enable LBR feature if its
+        * cpu model is the same as the host because the LBR registers
+        * would be pass-through to the guest and they're model specific.
+        */
+       if (boot_cpu_data.x86_model != guest_cpuid_model(vcpu))
+               return false;
+
+       return !x86_perf_get_lbr(lbr);

This seems the wrong place to me.  What about adding

+       if (intel_pmu_lbr_is_compatible(vcpu))
+               x86_perf_get_lbr(lbr_desc);
+       else
+               lbr_desc->records.nr = 0;
 }

at the end of intel_pmu_refresh instead?

Paolo

Reply via email to