pmu_inuse flag is part of lppaca struct which notifies the hypervisor whether guest/partition is using PMUs. This provides a hint incase of save/restore of PMU registers. And in power_pmu_enable(), linux sets the pmu_inuse flag and then updates the PMU registers. Current sequence in power_pmu_enable() is 1) update pmc_inuse flag 2)update MMCRA, MMCR1, MMCR0 and so on. But with this sequence, there is a window where when updating MMCRA, hypersior could load stale value to MMCR0 which could cause a PMI exception. Patch add a mtmmcr0 with freeze counter bit set right after updating the pmu_inuse flag to avoid any overflow scenarios. --- arch/powerpc/perf/core-book3s.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c index 3fb6d265ed17..f455e274281a 100644 --- a/arch/powerpc/perf/core-book3s.c +++ b/arch/powerpc/perf/core-book3s.c @@ -1351,6 +1351,7 @@ static void power_pmu_enable(struct pmu *pmu) * Then unfreeze the events. */ ppc_set_pmu_inuse(1); + mtspr(SPRN_MMCR0, MMCR0_FC); mtspr(SPRN_MMCRA, cpuhw->mmcr[2] & ~MMCRA_SAMPLE_ENABLE); mtspr(SPRN_MMCR1, cpuhw->mmcr[1]); mtspr(SPRN_MMCR0, (cpuhw->mmcr[0] & ~(MMCR0_PMC1CE | MMCR0_PMCjCE)) -- 2.21.0