Skip to content

Commit 4f1fa2a

Browse files
Like Xubonzini
authored andcommitted
KVM: x86/pmu: Limit the maximum number of supported Intel GP counters
The Intel Architectural IA32_PMCx MSRs addresses range allows for a maximum of 8 GP counters, and KVM cannot address any more. Introduce a local macro (named KVM_INTEL_PMC_MAX_GENERIC) and use it consistently to refer to the number of counters supported by KVM, thus avoiding possible out-of-bound accesses. Suggested-by: Jim Mattson <jmattson@google.com> Signed-off-by: Like Xu <likexu@tencent.com> Reviewed-by: Jim Mattson <jmattson@google.com> Message-Id: <20220919091008.60695-2-likexu@tencent.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent 8631ef5 commit 4f1fa2a

File tree

4 files changed

+15
-9
lines changed

4 files changed

+15
-9
lines changed

arch/x86/include/asm/kvm_host.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,10 @@ struct kvm_pmc {
501501
bool intr;
502502
};
503503

504+
/* More counters may conflict with other existing Architectural MSRs */
505+
#define KVM_INTEL_PMC_MAX_GENERIC 8
506+
#define MSR_ARCH_PERFMON_PERFCTR_MAX (MSR_ARCH_PERFMON_PERFCTR0 + KVM_INTEL_PMC_MAX_GENERIC - 1)
507+
#define MSR_ARCH_PERFMON_EVENTSEL_MAX (MSR_ARCH_PERFMON_EVENTSEL0 + KVM_INTEL_PMC_MAX_GENERIC - 1)
504508
#define KVM_PMC_MAX_FIXED 3
505509
struct kvm_pmu {
506510
unsigned nr_arch_gp_counters;
@@ -516,7 +520,7 @@ struct kvm_pmu {
516520
u64 reserved_bits;
517521
u64 raw_event_mask;
518522
u8 version;
519-
struct kvm_pmc gp_counters[INTEL_PMC_MAX_GENERIC];
523+
struct kvm_pmc gp_counters[KVM_INTEL_PMC_MAX_GENERIC];
520524
struct kvm_pmc fixed_counters[KVM_PMC_MAX_FIXED];
521525
struct irq_work irq_work;
522526
DECLARE_BITMAP(reprogram_pmi, X86_PMC_IDX_MAX);

arch/x86/kvm/pmu.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ static const struct x86_cpu_id vmx_icl_pebs_cpu[] = {
5656
* code. Each pmc, stored in kvm_pmc.idx field, is unique across
5757
* all perf counters (both gp and fixed). The mapping relationship
5858
* between pmc and perf counters is as the following:
59-
* * Intel: [0 .. INTEL_PMC_MAX_GENERIC-1] <=> gp counters
59+
* * Intel: [0 .. KVM_INTEL_PMC_MAX_GENERIC-1] <=> gp counters
6060
* [INTEL_PMC_IDX_FIXED .. INTEL_PMC_IDX_FIXED + 2] <=> fixed
6161
* * AMD: [0 .. AMD64_NUM_COUNTERS-1] and, for families 15H
6262
* and later, [0 .. AMD64_NUM_COUNTERS_CORE-1] <=> gp counters

arch/x86/kvm/vmx/pmu_intel.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -617,7 +617,7 @@ static void intel_pmu_init(struct kvm_vcpu *vcpu)
617617
struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
618618
struct lbr_desc *lbr_desc = vcpu_to_lbr_desc(vcpu);
619619

620-
for (i = 0; i < INTEL_PMC_MAX_GENERIC; i++) {
620+
for (i = 0; i < KVM_INTEL_PMC_MAX_GENERIC; i++) {
621621
pmu->gp_counters[i].type = KVM_PMC_GP;
622622
pmu->gp_counters[i].vcpu = vcpu;
623623
pmu->gp_counters[i].idx = i;
@@ -643,7 +643,7 @@ static void intel_pmu_reset(struct kvm_vcpu *vcpu)
643643
struct kvm_pmc *pmc = NULL;
644644
int i;
645645

646-
for (i = 0; i < INTEL_PMC_MAX_GENERIC; i++) {
646+
for (i = 0; i < KVM_INTEL_PMC_MAX_GENERIC; i++) {
647647
pmc = &pmu->gp_counters[i];
648648

649649
pmc_stop_counter(pmc);

arch/x86/kvm/x86.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1438,6 +1438,9 @@ static const u32 msrs_to_save_all[] = {
14381438
MSR_ARCH_PERFMON_FIXED_CTR0 + 2,
14391439
MSR_CORE_PERF_FIXED_CTR_CTRL, MSR_CORE_PERF_GLOBAL_STATUS,
14401440
MSR_CORE_PERF_GLOBAL_CTRL, MSR_CORE_PERF_GLOBAL_OVF_CTRL,
1441+
MSR_IA32_PEBS_ENABLE, MSR_IA32_DS_AREA, MSR_PEBS_DATA_CFG,
1442+
1443+
/* This part of MSRs should match KVM_INTEL_PMC_MAX_GENERIC. */
14411444
MSR_ARCH_PERFMON_PERFCTR0, MSR_ARCH_PERFMON_PERFCTR1,
14421445
MSR_ARCH_PERFMON_PERFCTR0 + 2, MSR_ARCH_PERFMON_PERFCTR0 + 3,
14431446
MSR_ARCH_PERFMON_PERFCTR0 + 4, MSR_ARCH_PERFMON_PERFCTR0 + 5,
@@ -1446,7 +1449,6 @@ static const u32 msrs_to_save_all[] = {
14461449
MSR_ARCH_PERFMON_EVENTSEL0 + 2, MSR_ARCH_PERFMON_EVENTSEL0 + 3,
14471450
MSR_ARCH_PERFMON_EVENTSEL0 + 4, MSR_ARCH_PERFMON_EVENTSEL0 + 5,
14481451
MSR_ARCH_PERFMON_EVENTSEL0 + 6, MSR_ARCH_PERFMON_EVENTSEL0 + 7,
1449-
MSR_IA32_PEBS_ENABLE, MSR_IA32_DS_AREA, MSR_PEBS_DATA_CFG,
14501452

14511453
MSR_K7_EVNTSEL0, MSR_K7_EVNTSEL1, MSR_K7_EVNTSEL2, MSR_K7_EVNTSEL3,
14521454
MSR_K7_PERFCTR0, MSR_K7_PERFCTR1, MSR_K7_PERFCTR2, MSR_K7_PERFCTR3,
@@ -7031,14 +7033,14 @@ static void kvm_init_msr_list(void)
70317033
intel_pt_validate_hw_cap(PT_CAP_num_address_ranges) * 2)
70327034
continue;
70337035
break;
7034-
case MSR_ARCH_PERFMON_PERFCTR0 ... MSR_ARCH_PERFMON_PERFCTR0 + 7:
7036+
case MSR_ARCH_PERFMON_PERFCTR0 ... MSR_ARCH_PERFMON_PERFCTR_MAX:
70357037
if (msrs_to_save_all[i] - MSR_ARCH_PERFMON_PERFCTR0 >=
7036-
min(INTEL_PMC_MAX_GENERIC, kvm_pmu_cap.num_counters_gp))
7038+
min(KVM_INTEL_PMC_MAX_GENERIC, kvm_pmu_cap.num_counters_gp))
70377039
continue;
70387040
break;
7039-
case MSR_ARCH_PERFMON_EVENTSEL0 ... MSR_ARCH_PERFMON_EVENTSEL0 + 7:
7041+
case MSR_ARCH_PERFMON_EVENTSEL0 ... MSR_ARCH_PERFMON_EVENTSEL_MAX:
70407042
if (msrs_to_save_all[i] - MSR_ARCH_PERFMON_EVENTSEL0 >=
7041-
min(INTEL_PMC_MAX_GENERIC, kvm_pmu_cap.num_counters_gp))
7043+
min(KVM_INTEL_PMC_MAX_GENERIC, kvm_pmu_cap.num_counters_gp))
70427044
continue;
70437045
break;
70447046
case MSR_IA32_XFD:

0 commit comments

Comments
 (0)