From b1f778a223a2a8ad6262e5233cfc3483bcf6e213 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Sun, 20 Aug 2023 10:01:08 +0100 Subject: KVM: arm64: pmu: Resync EL0 state on counter rotation Huang Shijie reports that, when profiling a guest from the host with a number of events that exceeds the number of available counters, the reported counts are wildly inaccurate. Without the counter oversubscription, the reported counts are correct. Their investigation indicates that upon counter rotation (which takes place on the back of a timer interrupt), we fail to re-apply the guest EL0 enabling, leading to the counting of host events instead of guest events. In order to solve this, add yet another hook between the host PMU driver and KVM, re-applying the guest EL0 configuration if the right conditions apply (the host is VHE, we are in interrupt context, and we interrupted a running vcpu). This triggers a new vcpu request which will apply the correct configuration on guest reentry. With this, we have the correct counts, even when the counters are oversubscribed. Reported-by: Huang Shijie Suggested-by: Oliver Upton Tested_by: Huang Shijie Signed-off-by: Marc Zyngier Cc: Leo Yan Cc: Mark Rutland Cc: Will Deacon Link: https://lore.kernel.org/r/20230809013953.7692-1-shijie@os.amperecomputing.com Acked-by: Mark Rutland Link: https://lore.kernel.org/r/20230820090108.177817-1-maz@kernel.org --- drivers/perf/arm_pmuv3.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/perf/arm_pmuv3.c') diff --git a/drivers/perf/arm_pmuv3.c b/drivers/perf/arm_pmuv3.c index 08b3a1bf0ef6..6a3d8176f54a 100644 --- a/drivers/perf/arm_pmuv3.c +++ b/drivers/perf/arm_pmuv3.c @@ -772,6 +772,8 @@ static void armv8pmu_start(struct arm_pmu *cpu_pmu) /* Enable all counters */ armv8pmu_pmcr_write(armv8pmu_pmcr_read() | ARMV8_PMU_PMCR_E); + + kvm_vcpu_pmu_resync_el0(); } static void armv8pmu_stop(struct arm_pmu *cpu_pmu) -- cgit v1.2.3