diff options
-rw-r--r-- | arch/powerpc/kernel/perf_counter.c | 23 |
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 | ||
33 | struct power_pmu *ppmu; | 33 | struct 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 | */ | ||
42 | static unsigned int freeze_counters_kernel = MMCR0_FCS; | ||
43 | |||
35 | void perf_counter_print_debug(void) | 44 | void 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 | ||