summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--virt/kvm/arm/pmu.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/virt/kvm/arm/pmu.c b/virt/kvm/arm/pmu.c
index f291d4ac3519..8731dfeced8b 100644
--- a/virt/kvm/arm/pmu.c
+++ b/virt/kvm/arm/pmu.c
@@ -8,6 +8,7 @@
8#include <linux/kvm.h> 8#include <linux/kvm.h>
9#include <linux/kvm_host.h> 9#include <linux/kvm_host.h>
10#include <linux/perf_event.h> 10#include <linux/perf_event.h>
11#include <linux/perf/arm_pmu.h>
11#include <linux/uaccess.h> 12#include <linux/uaccess.h>
12#include <asm/kvm_emulate.h> 13#include <asm/kvm_emulate.h>
13#include <kvm/arm_pmu.h> 14#include <kvm/arm_pmu.h>
@@ -442,8 +443,25 @@ static void kvm_pmu_perf_overflow(struct perf_event *perf_event,
442 struct pt_regs *regs) 443 struct pt_regs *regs)
443{ 444{
444 struct kvm_pmc *pmc = perf_event->overflow_handler_context; 445 struct kvm_pmc *pmc = perf_event->overflow_handler_context;
446 struct arm_pmu *cpu_pmu = to_arm_pmu(perf_event->pmu);
445 struct kvm_vcpu *vcpu = kvm_pmc_to_vcpu(pmc); 447 struct kvm_vcpu *vcpu = kvm_pmc_to_vcpu(pmc);
446 int idx = pmc->idx; 448 int idx = pmc->idx;
449 u64 period;
450
451 cpu_pmu->pmu.stop(perf_event, PERF_EF_UPDATE);
452
453 /*
454 * Reset the sample period to the architectural limit,
455 * i.e. the point where the counter overflows.
456 */
457 period = -(local64_read(&perf_event->count));
458
459 if (!kvm_pmu_idx_is_64bit(vcpu, pmc->idx))
460 period &= GENMASK(31, 0);
461
462 local64_set(&perf_event->hw.period_left, 0);
463 perf_event->attr.sample_period = period;
464 perf_event->hw.sample_period = period;
447 465
448 __vcpu_sys_reg(vcpu, PMOVSSET_EL0) |= BIT(idx); 466 __vcpu_sys_reg(vcpu, PMOVSSET_EL0) |= BIT(idx);
449 467
@@ -451,6 +469,8 @@ static void kvm_pmu_perf_overflow(struct perf_event *perf_event,
451 kvm_make_request(KVM_REQ_IRQ_PENDING, vcpu); 469 kvm_make_request(KVM_REQ_IRQ_PENDING, vcpu);
452 kvm_vcpu_kick(vcpu); 470 kvm_vcpu_kick(vcpu);
453 } 471 }
472
473 cpu_pmu->pmu.start(perf_event, PERF_EF_RELOAD);
454} 474}
455 475
456/** 476/**