Skip to content

Commit

Permalink
kvm: x86/pmu: prepare the pmu event filter for masked events
Browse files Browse the repository at this point in the history
Refactor check_pmu_event_filter() in preparation for masked events.

No functional changes intended

Signed-off-by: Aaron Lewis <aaronlewis@google.com>
Link: https://lore.kernel.org/r/20221220161236.555143-4-aaronlewis@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
  • Loading branch information
suomilewis authored and sean-jc committed Jan 19, 2023
1 parent 778e86e commit 11794a3
Showing 1 changed file with 33 additions and 23 deletions.
56 changes: 33 additions & 23 deletions arch/x86/kvm/pmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -263,41 +263,51 @@ static int cmp_u64(const void *pa, const void *pb)
return (a > b) - (a < b);
}

static u64 *find_filter_entry(struct kvm_pmu_event_filter *filter, u64 key)
{
return bsearch(&key, filter->events, filter->nevents,
sizeof(filter->events[0]), cmp_u64);
}

static bool is_gp_event_allowed(struct kvm_pmu_event_filter *filter, u64 eventsel)
{
if (find_filter_entry(filter, eventsel & (kvm_pmu_ops.EVENTSEL_EVENT |
ARCH_PERFMON_EVENTSEL_UMASK)))
return filter->action == KVM_PMU_EVENT_ALLOW;

return filter->action == KVM_PMU_EVENT_DENY;
}

static bool is_fixed_event_allowed(struct kvm_pmu_event_filter *filter, int idx)
{
int fixed_idx = idx - INTEL_PMC_IDX_FIXED;

if (filter->action == KVM_PMU_EVENT_DENY &&
test_bit(fixed_idx, (ulong *)&filter->fixed_counter_bitmap))
return false;
if (filter->action == KVM_PMU_EVENT_ALLOW &&
!test_bit(fixed_idx, (ulong *)&filter->fixed_counter_bitmap))
return false;

return true;
}

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;

if (!static_call(kvm_x86_pmu_hw_event_available)(pmc))
return false;

filter = srcu_dereference(kvm->arch.pmu_event_filter, &kvm->srcu);
if (!filter)
goto out;
return true;

if (pmc_is_gp(pmc)) {
key = pmc->eventsel & (kvm_pmu_ops.EVENTSEL_EVENT |
ARCH_PERFMON_EVENTSEL_UMASK);
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;
}
if (pmc_is_gp(pmc))
return is_gp_event_allowed(filter, pmc->eventsel);

out:
return allow_event;
return is_fixed_event_allowed(filter, pmc->idx);
}

static void reprogram_counter(struct kvm_pmc *pmc)
Expand Down

0 comments on commit 11794a3

Please sign in to comment.