ARMv8 provides support for chained PMU counters, where an event type of 0x001E is set for odd-numbered counters, the event counter will increment by one for each overflow of the preceding even-numbered counter. Let's emulate this in KVM by creating a 64 bit perf counter when a user chains two emulated counters together. Testing has been performed by hard-coding hwc->sample_period in __hw_perf_event_init (arm_pmu.c) to a small value, this results in regular overflows (for non sampling events). The following command was then used to measure chained and non-chained instruction cycles: perf stat -e armv8_pmuv3/long=1,inst_retired/u \ -e armv8_pmuv3/long=0,inst_retired/u dd if=/dev/zero bs=1M \ count=10 | gzip > /dev/null The reported values were identical (and for non-chained was in the same ballpark when running on a kernel without this patchset). Debug was added to verify that the guest received overflow interrupts for the chain counter. Changes since v2: - Rebased onto v5.0-rc7 - Add check for cycle counter in correct patch - Minor style, naming and comment changes - Extract armv8pmu_evtype_is_chain from arch/arm64/kernel/perf_event.c into a common header that KVM can use Changes since v1: - Rename kvm_pmu_{enable,disable}_counter to reflect that they can operate on multiple counters at once and use these functions where possible - Fix bugs with overflow handing, kvm_pmu_get_counter_value did not take into consideration the perf counter value overflowing the low counter - Ensure PMCCFILTR_EL0 is used when operating on the cycle counter - Rename kvm_pmu_reenable_enabled_{pair, single} and similar - Always create perf event disabled to simplify logic elsewhere - Move PMCNTENSET_EL0 test to kvm_pmu_enable_counter_mask Andrew Murray (6): KVM: arm/arm64: rename kvm_pmu_{enable/disable}_counter functions KVM: arm/arm64: extract duplicated code to own function KVM: arm/arm64: re-create event when setting counter value KVM: arm/arm64: lazily create perf events on enable arm64: perf: extract chain helper into header KVM: arm/arm64: support chained PMU counters arch/arm64/include/asm/perf_event.h | 5 + arch/arm64/kernel/perf_event.c | 2 +- arch/arm64/kvm/sys_regs.c | 4 +- include/kvm/arm_pmu.h | 9 +- virt/kvm/arm/pmu.c | 410 ++++++++++++++++++++++++++++++------ 5 files changed, 360 insertions(+), 70 deletions(-) -- 2.7.4