mirror of
https://github.com/torvalds/linux.git
synced 2026-06-03 12:03:54 +02:00
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: Like Xu <likexu@tencent.com> Reviewed-by: Wanpeng Li <wanpengli@tencent.com> Message-Id: <20220518132512.37864-3-likexu@tencent.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
a33095f493
commit
89cb454ea9
|
|
@ -250,14 +250,44 @@ static int cmp_u64(const void *pa, const void *pb)
|
|||
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)
|
||||
{
|
||||
u64 config;
|
||||
u32 type = PERF_TYPE_RAW;
|
||||
struct kvm *kvm = pmc->vcpu->kvm;
|
||||
struct kvm_pmu_event_filter *filter;
|
||||
struct kvm_pmu *pmu = vcpu_to_pmu(pmc->vcpu);
|
||||
bool allow_event = true;
|
||||
struct kvm_pmu *pmu = pmc_to_pmu(pmc);
|
||||
|
||||
if (eventsel & ARCH_PERFMON_EVENTSEL_PIN_CONTROL)
|
||||
printk_once("kvm pmu: pin control bit is ignored\n");
|
||||
|
|
@ -269,17 +299,7 @@ void reprogram_gp_counter(struct kvm_pmc *pmc, u64 eventsel)
|
|||
if (!(eventsel & ARCH_PERFMON_EVENTSEL_ENABLE) || !pmc_is_enabled(pmc))
|
||||
return;
|
||||
|
||||
filter = srcu_dereference(kvm->arch.pmu_event_filter, &kvm->srcu);
|
||||
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)
|
||||
if (!check_pmu_event_filter(pmc))
|
||||
return;
|
||||
|
||||
if (!(eventsel & (ARCH_PERFMON_EVENTSEL_EDGE |
|
||||
|
|
@ -312,23 +332,14 @@ void reprogram_fixed_counter(struct kvm_pmc *pmc, u8 ctrl, int idx)
|
|||
{
|
||||
unsigned en_field = ctrl & 0x3;
|
||||
bool pmi = ctrl & 0x8;
|
||||
struct kvm_pmu_event_filter *filter;
|
||||
struct kvm *kvm = pmc->vcpu->kvm;
|
||||
|
||||
pmc_pause_counter(pmc);
|
||||
|
||||
if (!en_field || !pmc_is_enabled(pmc))
|
||||
return;
|
||||
|
||||
filter = srcu_dereference(kvm->arch.pmu_event_filter, &kvm->srcu);
|
||||
if (filter) {
|
||||
if (filter->action == KVM_PMU_EVENT_DENY &&
|
||||
test_bit(idx, (ulong *)&filter->fixed_counter_bitmap))
|
||||
return;
|
||||
if (filter->action == KVM_PMU_EVENT_ALLOW &&
|
||||
!test_bit(idx, (ulong *)&filter->fixed_counter_bitmap))
|
||||
return;
|
||||
}
|
||||
if (!check_pmu_event_filter(pmc))
|
||||
return;
|
||||
|
||||
if (pmc->current_config == (u64)ctrl && pmc_resume_counter(pmc))
|
||||
return;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user