perfcounters/powerpc: Make exclude_kernel bit work on Apple G5 processors
[deliverable/linux.git] / arch / powerpc / kernel / perf_counter.c
index bd6ba85beb5492badc062e37a662e7af7e6bcc5d..6e27913ec0d88735747e8dec8bdd7325b026da6a 100644 (file)
@@ -32,6 +32,15 @@ DEFINE_PER_CPU(struct cpu_hw_counters, cpu_hw_counters);
 
 struct power_pmu *ppmu;
 
+/*
+ * Normally, to ignore kernel events we set the FCS (freeze counters
+ * in supervisor mode) bit in MMCR0, but if the kernel runs with the
+ * hypervisor bit set in the MSR, or if we are running on a processor
+ * where the hypervisor bit is forced to 1 (as on Apple G5 processors),
+ * then we need to use the FCHV bit to ignore kernel events.
+ */
+static unsigned int freeze_counters_kernel = MMCR0_FCS;
+
 void perf_counter_print_debug(void)
 {
 }
@@ -364,7 +373,7 @@ void hw_perf_restore(u64 disable)
        if (counter->hw_event.exclude_user)
                cpuhw->mmcr[0] |= MMCR0_FCP;
        if (counter->hw_event.exclude_kernel)
-               cpuhw->mmcr[0] |= MMCR0_FCS;
+               cpuhw->mmcr[0] |= freeze_counters_kernel;
        if (counter->hw_event.exclude_hv)
                cpuhw->mmcr[0] |= MMCR0_FCHV;
 
@@ -606,10 +615,7 @@ hw_perf_counter_init(struct perf_counter *counter)
        /*
         * If we are not running on a hypervisor, force the
         * exclude_hv bit to 0 so that we don't care what
-        * the user set it to.  This also means that we don't
-        * set the MMCR0_FCHV bit, which unconditionally freezes
-        * the counters on the PPC970 variants used in Apple G5
-        * machines (since MSR.HV is always 1 on those machines).
+        * the user set it to.
         */
        if (!firmware_has_feature(FW_FEATURE_LPAR))
                counter->hw_event.exclude_hv = 0;
@@ -841,6 +847,13 @@ static int init_perf_counters(void)
                ppmu = &power6_pmu;
                break;
        }
+
+       /*
+        * Use FCHV to ignore kernel events if MSR.HV is set.
+        */
+       if (mfmsr() & MSR_HV)
+               freeze_counters_kernel = MMCR0_FCHV;
+
        return 0;
 }
 
This page took 0.036475 seconds and 5 git commands to generate.