Skip to content

Commit 51f34b1

Browse files
committed
KVM: x86/pmu: Snapshot host (i.e. perf's) reported PMU capabilities
Take a snapshot of the unadulterated PMU capabilities provided by perf so that KVM can compare guest vPMU capabilities against hardware capabilities when determining whether or not to intercept PMU MSRs (and RDPMC). Reviewed-by: Sandipan Das <sandipan.das@amd.com> Tested-by: Xudong Hao <xudong.hao@intel.com> Link: https://lore.kernel.org/r/20250806195706.1650976-18-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com>
1 parent e3d1f28 commit 51f34b1

1 file changed

Lines changed: 10 additions & 5 deletions

File tree

arch/x86/kvm/pmu.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@
2626
/* This is enough to filter the vast majority of currently defined events. */
2727
#define KVM_PMU_EVENT_FILTER_MAX_EVENTS 300
2828

29+
/* Unadultered PMU capabilities of the host, i.e. of hardware. */
30+
static struct x86_pmu_capability __read_mostly kvm_host_pmu;
31+
32+
/* KVM's PMU capabilities, i.e. the intersection of KVM and hardware support. */
2933
struct x86_pmu_capability __read_mostly kvm_pmu_cap;
3034
EXPORT_SYMBOL_GPL(kvm_pmu_cap);
3135

@@ -104,6 +108,8 @@ void kvm_init_pmu_capability(const struct kvm_pmu_ops *pmu_ops)
104108
bool is_intel = boot_cpu_data.x86_vendor == X86_VENDOR_INTEL;
105109
int min_nr_gp_ctrs = pmu_ops->MIN_NR_GP_COUNTERS;
106110

111+
perf_get_x86_pmu_capability(&kvm_host_pmu);
112+
107113
/*
108114
* Hybrid PMUs don't play nice with virtualization without careful
109115
* configuration by userspace, and KVM's APIs for reporting supported
@@ -114,18 +120,16 @@ void kvm_init_pmu_capability(const struct kvm_pmu_ops *pmu_ops)
114120
enable_pmu = false;
115121

116122
if (enable_pmu) {
117-
perf_get_x86_pmu_capability(&kvm_pmu_cap);
118-
119123
/*
120124
* WARN if perf did NOT disable hardware PMU if the number of
121125
* architecturally required GP counters aren't present, i.e. if
122126
* there are a non-zero number of counters, but fewer than what
123127
* is architecturally required.
124128
*/
125-
if (!kvm_pmu_cap.num_counters_gp ||
126-
WARN_ON_ONCE(kvm_pmu_cap.num_counters_gp < min_nr_gp_ctrs))
129+
if (!kvm_host_pmu.num_counters_gp ||
130+
WARN_ON_ONCE(kvm_host_pmu.num_counters_gp < min_nr_gp_ctrs))
127131
enable_pmu = false;
128-
else if (is_intel && !kvm_pmu_cap.version)
132+
else if (is_intel && !kvm_host_pmu.version)
129133
enable_pmu = false;
130134
}
131135

@@ -134,6 +138,7 @@ void kvm_init_pmu_capability(const struct kvm_pmu_ops *pmu_ops)
134138
return;
135139
}
136140

141+
memcpy(&kvm_pmu_cap, &kvm_host_pmu, sizeof(kvm_host_pmu));
137142
kvm_pmu_cap.version = min(kvm_pmu_cap.version, 2);
138143
kvm_pmu_cap.num_counters_gp = min(kvm_pmu_cap.num_counters_gp,
139144
pmu_ops->MAX_NR_GP_COUNTERS);

0 commit comments

Comments
 (0)