diff mbox series

[3/3] KVM: x86/pmu: Update global enable_pmu when PMU is undetected

Message ID 20220518170118.66263-3-likexu@tencent.com (mailing list archive)
State New, archived
Headers show
Series [1/3] KVM: x86/pmu: Move the vmx_icl_pebs_cpu[] definition out of the header file | expand

Commit Message

Like Xu May 18, 2022, 5:01 p.m. UTC
From: Like Xu <likexu@tencent.com>

On some virt platforms (L1 guest w/o PMU), the value of module parameter
'enable_pmu' for nested L2 guests should be updated at initialisation.

Considering that there is no concept of "architecture pmu" in AMD or Hygon
and that the versions (prior to Zen 4) are all 0, but that the theoretical
available counters are at least AMD64_NUM_COUNTERS, the utility
check_hw_exists() is reused in the initialisation call path.

Opportunistically update Intel specific comments.

Fixes: 8eeac7e999e8 ("KVM: x86/pmu: Add kvm_pmu_cap to optimize perf_get_x86_pmu_capability")
Signed-off-by: Like Xu <likexu@tencent.com>
---
 arch/x86/events/core.c |  6 ++++++
 arch/x86/kvm/pmu.h     | 15 ++++++++++-----
 2 files changed, 16 insertions(+), 5 deletions(-)
diff mbox series

Patch

diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
index 7f1d10dbabc0..865eeb500a71 100644
--- a/arch/x86/events/core.c
+++ b/arch/x86/events/core.c
@@ -2982,6 +2982,12 @@  unsigned long perf_misc_flags(struct pt_regs *regs)
 
 void perf_get_x86_pmu_capability(struct x86_pmu_capability *cap)
 {
+	if (!check_hw_exists(&pmu, x86_pmu.num_counters,
+			     x86_pmu.num_counters_fixed)) {
+		memset(cap, 0, sizeof(*cap));
+		return;
+	}
+
 	cap->version		= x86_pmu.version;
 	/*
 	 * KVM doesn't support the hybrid PMU yet.
diff --git a/arch/x86/kvm/pmu.h b/arch/x86/kvm/pmu.h
index ecf2962510e4..b200d080a8a3 100644
--- a/arch/x86/kvm/pmu.h
+++ b/arch/x86/kvm/pmu.h
@@ -150,14 +150,19 @@  extern struct x86_pmu_capability kvm_pmu_cap;
 
 static inline void kvm_init_pmu_capability(void)
 {
+	bool is_intel = boot_cpu_data.x86_vendor == X86_VENDOR_INTEL;
+
 	perf_get_x86_pmu_capability(&kvm_pmu_cap);
 
-	/*
-	 * Only support guest architectural pmu on
-	 * a host with architectural pmu.
-	 */
-	if (!kvm_pmu_cap.version)
+	 /*
+	  * For Intel, only support guest architectural pmu
+	  * on a host with architectural pmu.
+	  */
+	if ((is_intel && !kvm_pmu_cap.version) || !kvm_pmu_cap.num_counters_gp) {
 		memset(&kvm_pmu_cap, 0, sizeof(kvm_pmu_cap));
+		enable_pmu = false;
+		return;
+	}
 
 	kvm_pmu_cap.version = min(kvm_pmu_cap.version, 2);
 	kvm_pmu_cap.num_counters_fixed = min(kvm_pmu_cap.num_counters_fixed,