aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/kernel/perf_counter.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/arch/powerpc/kernel/perf_counter.c b/arch/powerpc/kernel/perf_counter.c
index bd6ba85beb54..6e27913ec0d8 100644
--- a/arch/powerpc/kernel/perf_counter.c
+++ b/arch/powerpc/kernel/perf_counter.c
@@ -32,6 +32,15 @@ DEFINE_PER_CPU(struct cpu_hw_counters, cpu_hw_counters);
32 32
33struct power_pmu *ppmu; 33struct power_pmu *ppmu;
34 34
35/*
36 * Normally, to ignore kernel events we set the FCS (freeze counters
37 * in supervisor mode) bit in MMCR0, but if the kernel runs with the
38 * hypervisor bit set in the MSR, or if we are running on a processor
39 * where the hypervisor bit is forced to 1 (as on Apple G5 processors),
40 * then we need to use the FCHV bit to ignore kernel events.
41 */
42static unsigned int freeze_counters_kernel = MMCR0_FCS;
43
35void perf_counter_print_debug(void) 44void perf_counter_print_debug(void)
36{ 45{
37} 46}
@@ -364,7 +373,7 @@ void hw_perf_restore(u64 disable)
364 if (counter->hw_event.exclude_user) 373 if (counter->hw_event.exclude_user)
365 cpuhw->mmcr[0] |= MMCR0_FCP; 374 cpuhw->mmcr[0] |= MMCR0_FCP;
366 if (counter->hw_event.exclude_kernel) 375 if (counter->hw_event.exclude_kernel)
367 cpuhw->mmcr[0] |= MMCR0_FCS; 376 cpuhw->mmcr[0] |= freeze_counters_kernel;
368 if (counter->hw_event.exclude_hv) 377 if (counter->hw_event.exclude_hv)
369 cpuhw->mmcr[0] |= MMCR0_FCHV; 378 cpuhw->mmcr[0] |= MMCR0_FCHV;
370 379
@@ -606,10 +615,7 @@ hw_perf_counter_init(struct perf_counter *counter)
606 /* 615 /*
607 * If we are not running on a hypervisor, force the 616 * If we are not running on a hypervisor, force the
608 * exclude_hv bit to 0 so that we don't care what 617 * exclude_hv bit to 0 so that we don't care what
609 * the user set it to. This also means that we don't 618 * the user set it to.
610 * set the MMCR0_FCHV bit, which unconditionally freezes
611 * the counters on the PPC970 variants used in Apple G5
612 * machines (since MSR.HV is always 1 on those machines).
613 */ 619 */
614 if (!firmware_has_feature(FW_FEATURE_LPAR)) 620 if (!firmware_has_feature(FW_FEATURE_LPAR))
615 counter->hw_event.exclude_hv = 0; 621 counter->hw_event.exclude_hv = 0;
@@ -841,6 +847,13 @@ static int init_perf_counters(void)
841 ppmu = &power6_pmu; 847 ppmu = &power6_pmu;
842 break; 848 break;
843 } 849 }
850
851 /*
852 * Use FCHV to ignore kernel events if MSR.HV is set.
853 */
854 if (mfmsr() & MSR_HV)
855 freeze_counters_kernel = MMCR0_FCHV;
856
844 return 0; 857 return 0;
845} 858}
846 859