Skip to content

Commit c49aa98

Browse files
committed
KVM: x86/pmu: Restrict GLOBAL_{CTRL,STATUS}, fixed PMCs, and PEBS to PMU v2+
Restrict support for GLOBAL_CTRL, GLOBAL_STATUS, fixed PMCs, and PEBS to v2 or later vPMUs. The SDM explicitly states that GLOBAL_{CTRL,STATUS} and fixed counters were introduced with PMU v2, and PEBS has hard dependencies on fixed counters and the bitmap MSR layouts established by PMU v2. Reported-by: Dapeng Mi <[email protected]> Tested-by: Xudong Hao <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Sean Christopherson <[email protected]>
1 parent 9bae7a0 commit c49aa98

File tree

1 file changed

+25
-26
lines changed

1 file changed

+25
-26
lines changed

arch/x86/kvm/vmx/pmu_intel.c

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -541,16 +541,33 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
541541
kvm_pmu_cap.events_mask_len);
542542
pmu->available_event_types = ~entry->ebx & (BIT_ULL(eax.split.mask_length) - 1);
543543

544-
if (pmu->version == 1) {
545-
pmu->nr_arch_fixed_counters = 0;
546-
} else {
547-
pmu->nr_arch_fixed_counters = min_t(int, edx.split.num_counters_fixed,
548-
kvm_pmu_cap.num_counters_fixed);
549-
edx.split.bit_width_fixed = min_t(int, edx.split.bit_width_fixed,
550-
kvm_pmu_cap.bit_width_fixed);
551-
pmu->counter_bitmask[KVM_PMC_FIXED] = BIT_ULL(edx.split.bit_width_fixed) - 1;
544+
entry = kvm_find_cpuid_entry_index(vcpu, 7, 0);
545+
if (entry &&
546+
(boot_cpu_has(X86_FEATURE_HLE) || boot_cpu_has(X86_FEATURE_RTM)) &&
547+
(entry->ebx & (X86_FEATURE_HLE|X86_FEATURE_RTM))) {
548+
pmu->reserved_bits ^= HSW_IN_TX;
549+
pmu->raw_event_mask |= (HSW_IN_TX|HSW_IN_TX_CHECKPOINTED);
552550
}
553551

552+
perf_capabilities = vcpu_get_perf_capabilities(vcpu);
553+
if (intel_pmu_lbr_is_compatible(vcpu) &&
554+
(perf_capabilities & PERF_CAP_LBR_FMT))
555+
memcpy(&lbr_desc->records, &vmx_lbr_caps, sizeof(vmx_lbr_caps));
556+
else
557+
lbr_desc->records.nr = 0;
558+
559+
if (lbr_desc->records.nr)
560+
bitmap_set(pmu->all_valid_pmc_idx, INTEL_PMC_IDX_FIXED_VLBR, 1);
561+
562+
if (pmu->version == 1)
563+
return;
564+
565+
pmu->nr_arch_fixed_counters = min_t(int, edx.split.num_counters_fixed,
566+
kvm_pmu_cap.num_counters_fixed);
567+
edx.split.bit_width_fixed = min_t(int, edx.split.bit_width_fixed,
568+
kvm_pmu_cap.bit_width_fixed);
569+
pmu->counter_bitmask[KVM_PMC_FIXED] = BIT_ULL(edx.split.bit_width_fixed) - 1;
570+
554571
intel_pmu_enable_fixed_counter_bits(pmu, INTEL_FIXED_0_KERNEL |
555572
INTEL_FIXED_0_USER |
556573
INTEL_FIXED_0_ENABLE_PMI);
@@ -571,24 +588,6 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
571588
pmu->global_status_rsvd &=
572589
~MSR_CORE_PERF_GLOBAL_OVF_CTRL_TRACE_TOPA_PMI;
573590

574-
entry = kvm_find_cpuid_entry_index(vcpu, 7, 0);
575-
if (entry &&
576-
(boot_cpu_has(X86_FEATURE_HLE) || boot_cpu_has(X86_FEATURE_RTM)) &&
577-
(entry->ebx & (X86_FEATURE_HLE|X86_FEATURE_RTM))) {
578-
pmu->reserved_bits ^= HSW_IN_TX;
579-
pmu->raw_event_mask |= (HSW_IN_TX|HSW_IN_TX_CHECKPOINTED);
580-
}
581-
582-
perf_capabilities = vcpu_get_perf_capabilities(vcpu);
583-
if (intel_pmu_lbr_is_compatible(vcpu) &&
584-
(perf_capabilities & PERF_CAP_LBR_FMT))
585-
memcpy(&lbr_desc->records, &vmx_lbr_caps, sizeof(vmx_lbr_caps));
586-
else
587-
lbr_desc->records.nr = 0;
588-
589-
if (lbr_desc->records.nr)
590-
bitmap_set(pmu->all_valid_pmc_idx, INTEL_PMC_IDX_FIXED_VLBR, 1);
591-
592591
if (perf_capabilities & PERF_CAP_PEBS_FORMAT) {
593592
if (perf_capabilities & PERF_CAP_PEBS_BASELINE) {
594593
pmu->pebs_enable_rsvd = counter_rsvd;

0 commit comments

Comments
 (0)