Commit 89cb454e authored by Like Xu's avatar Like Xu Committed by Paolo Bonzini

KVM: x86/pmu: Extract check_pmu_event_filter() handling both GP and fixed counters

Checking the kvm->arch.pmu_event_filter policy in both gp and fixed
code paths was somewhat redundant, so common parts can be extracted,
which reduces code footprint and improves readability.
Signed-off-by: default avatarLike Xu <likexu@tencent.com>
Reviewed-by: default avatarWanpeng Li <wanpengli@tencent.com>
Message-Id: <20220518132512.37864-3-likexu@tencent.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent a33095f4
...@@ -250,14 +250,44 @@ static int cmp_u64(const void *pa, const void *pb) ...@@ -250,14 +250,44 @@ static int cmp_u64(const void *pa, const void *pb)
return (a > b) - (a < b); return (a > b) - (a < b);
} }
static bool check_pmu_event_filter(struct kvm_pmc *pmc)
{
struct kvm_pmu_event_filter *filter;
struct kvm *kvm = pmc->vcpu->kvm;
bool allow_event = true;
__u64 key;
int idx;
filter = srcu_dereference(kvm->arch.pmu_event_filter, &kvm->srcu);
if (!filter)
goto out;
if (pmc_is_gp(pmc)) {
key = pmc->eventsel & AMD64_RAW_EVENT_MASK_NB;
if (bsearch(&key, filter->events, filter->nevents,
sizeof(__u64), cmp_u64))
allow_event = filter->action == KVM_PMU_EVENT_ALLOW;
else
allow_event = filter->action == KVM_PMU_EVENT_DENY;
} else {
idx = pmc->idx - INTEL_PMC_IDX_FIXED;
if (filter->action == KVM_PMU_EVENT_DENY &&
test_bit(idx, (ulong *)&filter->fixed_counter_bitmap))
allow_event = false;
if (filter->action == KVM_PMU_EVENT_ALLOW &&
!test_bit(idx, (ulong *)&filter->fixed_counter_bitmap))
allow_event = false;
}
out:
return allow_event;
}
void reprogram_gp_counter(struct kvm_pmc *pmc, u64 eventsel) void reprogram_gp_counter(struct kvm_pmc *pmc, u64 eventsel)
{ {
u64 config; u64 config;
u32 type = PERF_TYPE_RAW; u32 type = PERF_TYPE_RAW;
struct kvm *kvm = pmc->vcpu->kvm; struct kvm_pmu *pmu = pmc_to_pmu(pmc);
struct kvm_pmu_event_filter *filter;
struct kvm_pmu *pmu = vcpu_to_pmu(pmc->vcpu);
bool allow_event = true;
if (eventsel & ARCH_PERFMON_EVENTSEL_PIN_CONTROL) if (eventsel & ARCH_PERFMON_EVENTSEL_PIN_CONTROL)
printk_once("kvm pmu: pin control bit is ignored\n"); printk_once("kvm pmu: pin control bit is ignored\n");
...@@ -269,17 +299,7 @@ void reprogram_gp_counter(struct kvm_pmc *pmc, u64 eventsel) ...@@ -269,17 +299,7 @@ void reprogram_gp_counter(struct kvm_pmc *pmc, u64 eventsel)
if (!(eventsel & ARCH_PERFMON_EVENTSEL_ENABLE) || !pmc_is_enabled(pmc)) if (!(eventsel & ARCH_PERFMON_EVENTSEL_ENABLE) || !pmc_is_enabled(pmc))
return; return;
filter = srcu_dereference(kvm->arch.pmu_event_filter, &kvm->srcu); if (!check_pmu_event_filter(pmc))
if (filter) {
__u64 key = eventsel & AMD64_RAW_EVENT_MASK_NB;
if (bsearch(&key, filter->events, filter->nevents,
sizeof(__u64), cmp_u64))
allow_event = filter->action == KVM_PMU_EVENT_ALLOW;
else
allow_event = filter->action == KVM_PMU_EVENT_DENY;
}
if (!allow_event)
return; return;
if (!(eventsel & (ARCH_PERFMON_EVENTSEL_EDGE | if (!(eventsel & (ARCH_PERFMON_EVENTSEL_EDGE |
...@@ -312,23 +332,14 @@ void reprogram_fixed_counter(struct kvm_pmc *pmc, u8 ctrl, int idx) ...@@ -312,23 +332,14 @@ void reprogram_fixed_counter(struct kvm_pmc *pmc, u8 ctrl, int idx)
{ {
unsigned en_field = ctrl & 0x3; unsigned en_field = ctrl & 0x3;
bool pmi = ctrl & 0x8; bool pmi = ctrl & 0x8;
struct kvm_pmu_event_filter *filter;
struct kvm *kvm = pmc->vcpu->kvm;
pmc_pause_counter(pmc); pmc_pause_counter(pmc);
if (!en_field || !pmc_is_enabled(pmc)) if (!en_field || !pmc_is_enabled(pmc))
return; return;
filter = srcu_dereference(kvm->arch.pmu_event_filter, &kvm->srcu); if (!check_pmu_event_filter(pmc))
if (filter) {
if (filter->action == KVM_PMU_EVENT_DENY &&
test_bit(idx, (ulong *)&filter->fixed_counter_bitmap))
return; return;
if (filter->action == KVM_PMU_EVENT_ALLOW &&
!test_bit(idx, (ulong *)&filter->fixed_counter_bitmap))
return;
}
if (pmc->current_config == (u64)ctrl && pmc_resume_counter(pmc)) if (pmc->current_config == (u64)ctrl && pmc_resume_counter(pmc))
return; return;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment