summaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/pmu.h
diff options
context:
space:
mode:
authorLike Xu <likexu@tencent.com>2022-05-18 19:01:18 +0200
committerPaolo Bonzini <pbonzini@redhat.com>2022-06-08 19:06:15 +0200
commitd7808f739162c003d249168bfe4c571aba18fb8a (patch)
tree985ece12fd30a17b4c68a8ca45d5b34f4414bcb6 /arch/x86/kvm/pmu.h
parentx86: events: Do not return bogus capabilities if PMU is broken (diff)
downloadlinux-d7808f739162c003d249168bfe4c571aba18fb8a.tar.xz
linux-d7808f739162c003d249168bfe4c571aba18fb8a.zip
KVM: x86/pmu: Update global enable_pmu when PMU is undetected
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> Message-Id: <20220518170118.66263-3-likexu@tencent.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'arch/x86/kvm/pmu.h')
-rw-r--r--arch/x86/kvm/pmu.h15
1 files changed, 10 insertions, 5 deletions
diff --git a/arch/x86/kvm/pmu.h b/arch/x86/kvm/pmu.h
index 0e719436b7b8..d59e1cb3b5dc 100644
--- a/arch/x86/kvm/pmu.h
+++ b/arch/x86/kvm/pmu.h
@@ -159,14 +159,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,