Skip to content

Commit dfdeda6

Browse files
suomilewissean-jc
authored andcommitted
KVM: x86/pmu: Prevent the PMU from counting disallowed events
When counting "Instructions Retired" (0xc0) in a guest, KVM will occasionally increment the PMU counter regardless of if that event is being filtered. This is because some PMU events are incremented via kvm_pmu_trigger_event(), which doesn't know about the event filter. Add the event filter to kvm_pmu_trigger_event(), so events that are disallowed do not increment their counters. Fixes: 9cd803d ("KVM: x86: Update vPMCs when retiring instructions") Signed-off-by: Aaron Lewis <aaronlewis@google.com> Reviewed-by: Like Xu <likexu@tencent.com> Link: https://lore.kernel.org/r/20230307141400.1486314-2-aaronlewis@google.com [sean: prepend "pmc" to the new function] Signed-off-by: Sean Christopherson <seanjc@google.com>
1 parent 4fa5843 commit dfdeda6

1 file changed

Lines changed: 8 additions & 5 deletions

File tree

arch/x86/kvm/pmu.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,12 @@ static bool check_pmu_event_filter(struct kvm_pmc *pmc)
400400
return is_fixed_event_allowed(filter, pmc->idx);
401401
}
402402

403+
static bool pmc_event_is_allowed(struct kvm_pmc *pmc)
404+
{
405+
return pmc_is_globally_enabled(pmc) && pmc_speculative_in_use(pmc) &&
406+
check_pmu_event_filter(pmc);
407+
}
408+
403409
static void reprogram_counter(struct kvm_pmc *pmc)
404410
{
405411
struct kvm_pmu *pmu = pmc_to_pmu(pmc);
@@ -409,10 +415,7 @@ static void reprogram_counter(struct kvm_pmc *pmc)
409415

410416
pmc_pause_counter(pmc);
411417

412-
if (!pmc_speculative_in_use(pmc) || !pmc_is_globally_enabled(pmc))
413-
goto reprogram_complete;
414-
415-
if (!check_pmu_event_filter(pmc))
418+
if (!pmc_event_is_allowed(pmc))
416419
goto reprogram_complete;
417420

418421
if (pmc->counter < pmc->prev_counter)
@@ -688,7 +691,7 @@ void kvm_pmu_trigger_event(struct kvm_vcpu *vcpu, u64 perf_hw_id)
688691
for_each_set_bit(i, pmu->all_valid_pmc_idx, X86_PMC_IDX_MAX) {
689692
pmc = static_call(kvm_x86_pmu_pmc_idx_to_pmc)(pmu, i);
690693

691-
if (!pmc || !pmc_is_globally_enabled(pmc) || !pmc_speculative_in_use(pmc))
694+
if (!pmc || !pmc_event_is_allowed(pmc))
692695
continue;
693696

694697
/* Ignore checks for edge detect, pin control, invert and CMASK bits */

0 commit comments

Comments
 (0)