Excerpts from Nicholas Piggin's message of July 2, 2021 10:27 am: > Excerpts from Madhavan Srinivasan's message of July 1, 2021 11:17 pm: >> >> On 6/22/21 4:27 PM, Nicholas Piggin wrote: >>> KVM PMU management code looks for particular frozen/disabled bits in >>> the PMU registers so it knows whether it must clear them when coming >>> out of a guest or not. Setting this up helps KVM make these optimisations >>> without getting confused. Longer term the better approach might be to >>> move guest/host PMU switching to the perf subsystem. >>> >>> Signed-off-by: Nicholas Piggin <npiggin@xxxxxxxxx> >>> --- >>> arch/powerpc/kernel/cpu_setup_power.c | 4 ++-- >>> arch/powerpc/kernel/dt_cpu_ftrs.c | 6 +++--- >>> arch/powerpc/kvm/book3s_hv.c | 5 +++++ >>> arch/powerpc/perf/core-book3s.c | 7 +++++++ >>> 4 files changed, 17 insertions(+), 5 deletions(-) >>> >>> diff --git a/arch/powerpc/kernel/cpu_setup_power.c b/arch/powerpc/kernel/cpu_setup_power.c >>> index a29dc8326622..3dc61e203f37 100644 >>> --- a/arch/powerpc/kernel/cpu_setup_power.c >>> +++ b/arch/powerpc/kernel/cpu_setup_power.c >>> @@ -109,7 +109,7 @@ static void init_PMU_HV_ISA207(void) >>> static void init_PMU(void) >>> { >>> mtspr(SPRN_MMCRA, 0); >>> - mtspr(SPRN_MMCR0, 0); >>> + mtspr(SPRN_MMCR0, MMCR0_FC); >> >> Sticky point here is, currently if not frozen, pmc5/6 will >> keep countering. And not freezing them at boot is quiet useful >> sometime, like say when running in a simulation where we could calculate >> approx CPIs for micro benchmarks without perf subsystem. > > You even can't use the sysfs files in this sim environment? In that case > what if we added a boot option that could set some things up? In that > case possibly you could even gather some more types of events too. What if we added this to allow sim environments to run PMC5/6 and additionally specify MMCR1 without userspace involvement? Thanks, Nick --- diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c index af8a4981c6f6..454771243529 100644 --- a/arch/powerpc/perf/core-book3s.c +++ b/arch/powerpc/perf/core-book3s.c @@ -2425,8 +2425,24 @@ int register_power_pmu(struct power_pmu *pmu) } #ifdef CONFIG_PPC64 +static bool pmu_override = false; +static unsigned long pmu_override_val; +static void do_pmu_override(void *data) +{ + ppc_set_pmu_inuse(1); + if (pmu_override_val) + mtspr(SPRN_MMCR1, pmu_override_val); + mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) & ~MMCR0_FC); +} + static int __init init_ppc64_pmu(void) { + if (cpu_has_feature(CPU_FTR_HVMODE) && pmu_override) { + printk(KERN_WARNING "perf: disabling perf due to pmu= command line option.\n"); + on_each_cpu(do_pmu_override, NULL, 1); + return 0; + } + /* run through all the pmu drivers one at a time */ if (!init_power5_pmu()) return 0; @@ -2448,4 +2464,23 @@ static int __init init_ppc64_pmu(void) return init_generic_compat_pmu(); } early_initcall(init_ppc64_pmu); + +static int __init pmu_setup(char *str) +{ + unsigned long val; + + if (!early_cpu_has_feature(CPU_FTR_HVMODE)) + return 0; + + pmu_override = true; + + if (kstrtoul(str, 0, &val)) + val = 0; + + pmu_override_val = val; + + return 1; +} +__setup("pmu=", pmu_setup); + #endif