import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / arch / arm / kernel / perf_event.c
index ace0ce8f664114deaac968ca0de3df2560919dbb..b41749fe56dcc14a0640152aff73389612241a56 100644 (file)
@@ -12,6 +12,7 @@
  */
 #define pr_fmt(fmt) "hw perfevents: " fmt
 
+#include <linux/cpumask.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
@@ -86,6 +87,9 @@ armpmu_map_event(struct perf_event *event,
                return armpmu_map_cache_event(cache_map, config);
        case PERF_TYPE_RAW:
                return armpmu_map_raw_event(raw_event_mask, config);
+       default:
+               if (event->attr.type >= PERF_TYPE_MAX)
+                       return armpmu_map_raw_event(raw_event_mask, config);
        }
 
        return -ENOENT;
@@ -163,6 +167,8 @@ armpmu_stop(struct perf_event *event, int flags)
        struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
        struct hw_perf_event *hwc = &event->hw;
 
+       if (!cpumask_test_cpu(smp_processor_id(), &armpmu->valid_cpus))
+               return;
        /*
         * ARM pmu always has to update the counter, so ignore
         * PERF_EF_UPDATE, see comments in armpmu_start().
@@ -179,6 +185,8 @@ static void armpmu_start(struct perf_event *event, int flags)
        struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
        struct hw_perf_event *hwc = &event->hw;
 
+       if (!cpumask_test_cpu(smp_processor_id(), &armpmu->valid_cpus))
+               return;
        /*
         * ARM pmu always has to reprogram the period, so ignore
         * PERF_EF_RELOAD, see the comment below.
@@ -206,6 +214,9 @@ armpmu_del(struct perf_event *event, int flags)
        struct hw_perf_event *hwc = &event->hw;
        int idx = hwc->idx;
 
+       if (!cpumask_test_cpu(smp_processor_id(), &armpmu->valid_cpus))
+               return;
+
        armpmu_stop(event, PERF_EF_UPDATE);
        hw_events->events[idx] = NULL;
        clear_bit(idx, hw_events->used_mask);
@@ -222,6 +233,10 @@ armpmu_add(struct perf_event *event, int flags)
        int idx;
        int err = 0;
 
+       /* An event following a process won't be stopped earlier */
+       if (!cpumask_test_cpu(smp_processor_id(), &armpmu->valid_cpus))
+               return 0;
+
        perf_pmu_disable(event->pmu);
 
        /* If we don't have a space for the counter then finish early. */
@@ -431,6 +446,10 @@ static int armpmu_event_init(struct perf_event *event)
        int err = 0;
        atomic_t *active_events = &armpmu->active_events;
 
+       if (event->cpu != -1 &&
+               !cpumask_test_cpu(event->cpu, &armpmu->valid_cpus))
+               return -ENOENT;
+
        /* does not support taken branch sampling */
        if (has_branch_stack(event))
                return -EOPNOTSUPP;