Skip to content

Commit 4d7404e

Browse files
sean-jcbonzini
authored andcommitted
KVM: x86/pmu: Disable vPMU support on hybrid CPUs (host PMUs)
Disable KVM support for virtualizing PMUs on hosts with hybrid PMUs until KVM gains a sane way to enumeration the hybrid vPMU to userspace and/or gains a mechanism to let userspace opt-in to the dangers of exposing a hybrid vPMU to KVM guests. Virtualizing a hybrid PMU, or at least part of a hybrid PMU, is possible, but it requires careful, deliberate configuration from userspace. E.g. to expose full functionality, vCPUs need to be pinned to pCPUs to prevent migrating a vCPU between a big core and a little core, userspace must enumerate a reasonable topology to the guest, and guest CPUID must be curated per vCPU to enumerate accurate vPMU capabilities. The last point is especially problematic, as KVM doesn't control which pCPU it runs on when enumerating KVM's vPMU capabilities to userspace, i.e. userspace can't rely on KVM_GET_SUPPORTED_CPUID in it's current form. Alternatively, userspace could enable vPMU support by enumerating the set of features that are common and coherent across all cores, e.g. by filtering PMU events and restricting guest capabilities. But again, that requires userspace to take action far beyond reflecting KVM's supported feature set into the guest. For now, simply disable vPMU support on hybrid CPUs to avoid inducing seemingly random #GPs in guests, and punt support for hybrid CPUs to a future enabling effort. Reported-by: Jianfeng Gao <[email protected]> Cc: [email protected] Cc: Andrew Cooper <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Kan Liang <[email protected]> Cc: Andi Kleen <[email protected]> Link: https://lore.kernel.org/all/[email protected] Signed-off-by: Sean Christopherson <[email protected]> Message-Id: <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent 971cecb commit 4d7404e

File tree

1 file changed

+19
-7
lines changed

1 file changed

+19
-7
lines changed

arch/x86/kvm/pmu.h

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -165,15 +165,27 @@ static inline void kvm_init_pmu_capability(void)
165165
{
166166
bool is_intel = boot_cpu_data.x86_vendor == X86_VENDOR_INTEL;
167167

168-
perf_get_x86_pmu_capability(&kvm_pmu_cap);
169-
170-
/*
171-
* For Intel, only support guest architectural pmu
172-
* on a host with architectural pmu.
173-
*/
174-
if ((is_intel && !kvm_pmu_cap.version) || !kvm_pmu_cap.num_counters_gp)
168+
/*
169+
* Hybrid PMUs don't play nice with virtualization without careful
170+
* configuration by userspace, and KVM's APIs for reporting supported
171+
* vPMU features do not account for hybrid PMUs. Disable vPMU support
172+
* for hybrid PMUs until KVM gains a way to let userspace opt-in.
173+
*/
174+
if (cpu_feature_enabled(X86_FEATURE_HYBRID_CPU))
175175
enable_pmu = false;
176176

177+
if (enable_pmu) {
178+
perf_get_x86_pmu_capability(&kvm_pmu_cap);
179+
180+
/*
181+
* For Intel, only support guest architectural pmu
182+
* on a host with architectural pmu.
183+
*/
184+
if ((is_intel && !kvm_pmu_cap.version) ||
185+
!kvm_pmu_cap.num_counters_gp)
186+
enable_pmu = false;
187+
}
188+
177189
if (!enable_pmu) {
178190
memset(&kvm_pmu_cap, 0, sizeof(kvm_pmu_cap));
179191
return;

0 commit comments

Comments
 (0)