*/
#define INTEL_RDPMC_FIXED INTEL_PMC_FIXED_RDPMC_BASE
+#define INTEL_RDPMC_TYPE_MASK GENMASK(31, 16)
+#define INTEL_RDPMC_INDEX_MASK GENMASK(15, 0)
+
#define MSR_PMC_FULL_WIDTH_BIT (MSR_IA32_PMC0 - MSR_IA32_PERFCTR0)
static void reprogram_fixed_counters(struct kvm_pmu *pmu, u64 data)
static struct kvm_pmc *intel_rdpmc_ecx_to_pmc(struct kvm_vcpu *vcpu,
unsigned int idx, u64 *mask)
{
+ unsigned int type = idx & INTEL_RDPMC_TYPE_MASK;
struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
- bool fixed = idx & INTEL_RDPMC_FIXED;
struct kvm_pmc *counters;
unsigned int num_counters;
+ u64 bitmask;
/*
* The encoding of ECX for RDPMC is different for architectural versus
* i.e. let RDPMC fail due to accessing a non-existent counter.
*/
idx &= ~INTEL_RDPMC_FIXED;
- if (fixed) {
+ if (type == INTEL_RDPMC_FIXED) {
counters = pmu->fixed_counters;
num_counters = pmu->nr_arch_fixed_counters;
+ bitmask = pmu->counter_bitmask[KVM_PMC_FIXED];
} else {
counters = pmu->gp_counters;
num_counters = pmu->nr_arch_gp_counters;
+ bitmask = pmu->counter_bitmask[KVM_PMC_GP];
}
+
if (idx >= num_counters)
return NULL;
- *mask &= pmu->counter_bitmask[fixed ? KVM_PMC_FIXED : KVM_PMC_GP];
+
+ *mask &= bitmask;
return &counters[array_index_nospec(idx, num_counters)];
}