Re: [PATCH v13 021/113] KVM: TDX: Make pmu_intel.c ignore guest TD case

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Like:

Would you mind to take a look on this patch? It would be nice to have
a r-b also from you. :)

On Sun, 12 Mar 2023 10:55:45 -0700
isaku.yamahata@xxxxxxxxx wrote:

> From: Isaku Yamahata <isaku.yamahata@xxxxxxxxx>
> 
> Because TDX KVM doesn't support PMU yet (it's future work of TDX KVM
> support as another patch series) and pmu_intel.c touches vmx specific
> structure in vcpu initialization, as workaround add dummy structure to
> struct vcpu_tdx and pmu_intel.c can ignore TDX case.
> 
> Signed-off-by: Isaku Yamahata <isaku.yamahata@xxxxxxxxx>
> ---
>  arch/x86/kvm/vmx/pmu_intel.c | 46 +++++++++++++++++++++++++++++++++++-
>  arch/x86/kvm/vmx/pmu_intel.h | 28 ++++++++++++++++++++++
>  arch/x86/kvm/vmx/tdx.h       |  8 ++++++-
>  arch/x86/kvm/vmx/vmx.c       |  2 +-
>  arch/x86/kvm/vmx/vmx.h       | 32 +------------------------
>  5 files changed, 82 insertions(+), 34 deletions(-)
>  create mode 100644 arch/x86/kvm/vmx/pmu_intel.h
> 
> diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c
> index e8a3be0b9df9..df1f4ddfa72d 100644
> --- a/arch/x86/kvm/vmx/pmu_intel.c
> +++ b/arch/x86/kvm/vmx/pmu_intel.c
> @@ -19,6 +19,7 @@
>  #include "lapic.h"
>  #include "nested.h"
>  #include "pmu.h"
> +#include "tdx.h"
>  
>  #define MSR_PMC_FULL_WIDTH_BIT      (MSR_IA32_PMC0 - MSR_IA32_PERFCTR0)
>  
> @@ -40,6 +41,26 @@ static struct {
>  /* mapping between fixed pmc index and intel_arch_events array */
>  static int fixed_pmc_events[] = {1, 0, 7};
>  
> +struct lbr_desc *vcpu_to_lbr_desc(struct kvm_vcpu *vcpu)
> +{
> +#ifdef CONFIG_INTEL_TDX_HOST
> +	if (is_td_vcpu(vcpu))
> +		return &to_tdx(vcpu)->lbr_desc;
> +#endif
> +
> +	return &to_vmx(vcpu)->lbr_desc;
> +}
> +
> +struct x86_pmu_lbr *vcpu_to_lbr_records(struct kvm_vcpu *vcpu)
> +{
> +#ifdef CONFIG_INTEL_TDX_HOST
> +	if (is_td_vcpu(vcpu))
> +		return &to_tdx(vcpu)->lbr_desc.records;
> +#endif
> +
> +	return &to_vmx(vcpu)->lbr_desc.records;
> +}
> +
>  static void reprogram_fixed_counters(struct kvm_pmu *pmu, u64 data)
>  {
>  	struct kvm_pmc *pmc;
> @@ -172,6 +193,23 @@ 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)
> +{
> +	if (is_td_vcpu(vcpu))
> +		return false;
> +	return cpuid_model_is_consistent(vcpu);
> +}
> +
> +bool intel_pmu_lbr_is_enabled(struct kvm_vcpu *vcpu)
> +{
> +	struct x86_pmu_lbr *lbr = vcpu_to_lbr_records(vcpu);
> +
> +	if (is_td_vcpu(vcpu))
> +		return false;
> +
> +	return lbr->nr && (vcpu_get_perf_capabilities(vcpu) & PMU_CAP_LBR_FMT);
> +}
> +
>  static bool intel_pmu_is_valid_lbr_msr(struct kvm_vcpu *vcpu, u32 index)
>  {
>  	struct x86_pmu_lbr *records = vcpu_to_lbr_records(vcpu);
> @@ -282,6 +320,9 @@ int intel_pmu_create_guest_lbr_event(struct kvm_vcpu *vcpu)
>  					PERF_SAMPLE_BRANCH_USER,
>  	};
>  
> +	if (WARN_ON_ONCE(is_td_vcpu(vcpu)))
> +		return 0;
> +
>  	if (unlikely(lbr_desc->event)) {
>  		__set_bit(INTEL_PMC_IDX_FIXED_VLBR, pmu->pmc_in_use);
>  		return 0;
> @@ -591,7 +632,7 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
>  		INTEL_PMC_MAX_GENERIC, pmu->nr_arch_fixed_counters);
>  
>  	perf_capabilities = vcpu_get_perf_capabilities(vcpu);
> -	if (cpuid_model_is_consistent(vcpu) &&
> +	if (intel_pmu_lbr_is_compatible(vcpu) &&
>  	    (perf_capabilities & PMU_CAP_LBR_FMT))
>  		x86_perf_get_lbr(&lbr_desc->records);
>  	else
> @@ -647,6 +688,9 @@ static void intel_pmu_reset(struct kvm_vcpu *vcpu)
>  	struct kvm_pmc *pmc = NULL;
>  	int i;
>  
> +	if (is_td_vcpu(vcpu))
> +		return;
> +
>  	for (i = 0; i < KVM_INTEL_PMC_MAX_GENERIC; i++) {
>  		pmc = &pmu->gp_counters[i];
>  
> diff --git a/arch/x86/kvm/vmx/pmu_intel.h b/arch/x86/kvm/vmx/pmu_intel.h
> new file mode 100644
> index 000000000000..66bba47c1269
> --- /dev/null
> +++ b/arch/x86/kvm/vmx/pmu_intel.h
> @@ -0,0 +1,28 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef __KVM_X86_VMX_PMU_INTEL_H
> +#define  __KVM_X86_VMX_PMU_INTEL_H
> +
> +struct lbr_desc *vcpu_to_lbr_desc(struct kvm_vcpu *vcpu);
> +struct x86_pmu_lbr *vcpu_to_lbr_records(struct kvm_vcpu *vcpu);
> +
> +bool intel_pmu_lbr_is_compatible(struct kvm_vcpu *vcpu);
> +bool intel_pmu_lbr_is_enabled(struct kvm_vcpu *vcpu);
> +int intel_pmu_create_guest_lbr_event(struct kvm_vcpu *vcpu);
> +
> +struct lbr_desc {
> +	/* Basic info about guest LBR records. */
> +	struct x86_pmu_lbr records;
> +
> +	/*
> +	 * Emulate LBR feature via passthrough LBR registers when the
> +	 * per-vcpu guest LBR event is scheduled on the current pcpu.
> +	 *
> +	 * The records may be inaccurate if the host reclaims the LBR.
> +	 */
> +	struct perf_event *event;
> +
> +	/* True if LBRs are marked as not intercepted in the MSR bitmap */
> +	bool msr_passthrough;
> +};
> +
> +#endif /* __KVM_X86_VMX_PMU_INTEL_H */
> diff --git a/arch/x86/kvm/vmx/tdx.h b/arch/x86/kvm/vmx/tdx.h
> index 1e00e75b1c5e..5728820fed5e 100644
> --- a/arch/x86/kvm/vmx/tdx.h
> +++ b/arch/x86/kvm/vmx/tdx.h
> @@ -4,6 +4,7 @@
>  
>  #ifdef CONFIG_INTEL_TDX_HOST
>  
> +#include "pmu_intel.h"
>  #include "tdx_ops.h"
>  
>  struct kvm_tdx {
> @@ -21,7 +22,12 @@ struct kvm_tdx {
>  
>  struct vcpu_tdx {
>  	struct kvm_vcpu	vcpu;
> -	/* TDX specific members follow. */
> +
> +	/*
> +	 * Dummy to make pmu_intel not corrupt memory.
> +	 * TODO: Support PMU for TDX.  Future work.
> +	 */
> +	struct lbr_desc lbr_desc;
>  };
>  
>  static inline bool is_td(struct kvm *kvm)
> diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
> index d23830d92f61..f9e9fd7fde2c 100644
> --- a/arch/x86/kvm/vmx/vmx.c
> +++ b/arch/x86/kvm/vmx/vmx.c
> @@ -2432,7 +2432,7 @@ int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>  			if ((data & PMU_CAP_LBR_FMT) !=
>  			    (kvm_caps.supported_perf_cap & PMU_CAP_LBR_FMT))
>  				return 1;
> -			if (!cpuid_model_is_consistent(vcpu))
> +			if (!intel_pmu_lbr_is_compatible(vcpu))
>  				return 1;
>  		}
>  		if (data & PERF_CAP_PEBS_FORMAT) {
> diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h
> index 2acdc54bc34b..1d15c3c2751b 100644
> --- a/arch/x86/kvm/vmx/vmx.h
> +++ b/arch/x86/kvm/vmx/vmx.h
> @@ -11,6 +11,7 @@
>  #include "capabilities.h"
>  #include "../kvm_cache_regs.h"
>  #include "posted_intr.h"
> +#include "pmu_intel.h"
>  #include "vmcs.h"
>  #include "vmx_ops.h"
>  #include "../cpuid.h"
> @@ -105,22 +106,6 @@ static inline bool intel_pmu_has_perf_global_ctrl(struct kvm_pmu *pmu)
>  	return pmu->version > 1;
>  }
>  
> -struct lbr_desc {
> -	/* Basic info about guest LBR records. */
> -	struct x86_pmu_lbr records;
> -
> -	/*
> -	 * Emulate LBR feature via passthrough LBR registers when the
> -	 * per-vcpu guest LBR event is scheduled on the current pcpu.
> -	 *
> -	 * The records may be inaccurate if the host reclaims the LBR.
> -	 */
> -	struct perf_event *event;
> -
> -	/* True if LBRs are marked as not intercepted in the MSR bitmap */
> -	bool msr_passthrough;
> -};
> -
>  /*
>   * The nested_vmx structure is part of vcpu_vmx, and holds information we need
>   * for correct emulation of VMX (i.e., nested VMX) on this vcpu.
> @@ -650,21 +635,6 @@ static __always_inline struct vcpu_vmx *to_vmx(struct kvm_vcpu *vcpu)
>  	return container_of(vcpu, struct vcpu_vmx, vcpu);
>  }
>  
> -static inline struct lbr_desc *vcpu_to_lbr_desc(struct kvm_vcpu *vcpu)
> -{
> -	return &to_vmx(vcpu)->lbr_desc;
> -}
> -
> -static inline struct x86_pmu_lbr *vcpu_to_lbr_records(struct kvm_vcpu *vcpu)
> -{
> -	return &vcpu_to_lbr_desc(vcpu)->records;
> -}
> -
> -static inline bool intel_pmu_lbr_is_enabled(struct kvm_vcpu *vcpu)
> -{
> -	return !!vcpu_to_lbr_records(vcpu)->nr;
> -}
> -
>  void intel_pmu_cross_mapped_check(struct kvm_pmu *pmu);
>  int intel_pmu_create_guest_lbr_event(struct kvm_vcpu *vcpu);
>  void vmx_passthrough_lbr_msrs(struct kvm_vcpu *vcpu);




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux