Re: [PATCH v14 03/11] KVM: vmx/pmu: Add PMU_CAP_LBR_FMT check when guest LBR is enabled

Paolo Bonzini
2021-02-02T12:02:26Z

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.xu@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