LCOV - code coverage report
Current view: top level - arch/arm/kernel - perf_event.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 216 0.0 %
Date: 2014-04-16 Functions: 0 25 0.0 %
Branches: 0 140 0.0 %

           Branch data     Line data    Source code
       1                 :            : #undef DEBUG
       2                 :            : 
       3                 :            : /*
       4                 :            :  * ARM performance counter support.
       5                 :            :  *
       6                 :            :  * Copyright (C) 2009 picoChip Designs, Ltd., Jamie Iles
       7                 :            :  * Copyright (C) 2010 ARM Ltd., Will Deacon <will.deacon@arm.com>
       8                 :            :  *
       9                 :            :  * This code is based on the sparc64 perf event code, which is in turn based
      10                 :            :  * on the x86 code. Callchain code is based on the ARM OProfile backtrace
      11                 :            :  * code.
      12                 :            :  */
      13                 :            : #define pr_fmt(fmt) "hw perfevents: " fmt
      14                 :            : 
      15                 :            : #include <linux/cpumask.h>
      16                 :            : #include <linux/kernel.h>
      17                 :            : #include <linux/platform_device.h>
      18                 :            : #include <linux/pm_runtime.h>
      19                 :            : #include <linux/uaccess.h>
      20                 :            : 
      21                 :            : #include <asm/irq_regs.h>
      22                 :            : #include <asm/pmu.h>
      23                 :            : #include <asm/stacktrace.h>
      24                 :            : 
      25                 :            : static int
      26                 :            : armpmu_map_cache_event(const unsigned (*cache_map)
      27                 :            :                                       [PERF_COUNT_HW_CACHE_MAX]
      28                 :            :                                       [PERF_COUNT_HW_CACHE_OP_MAX]
      29                 :            :                                       [PERF_COUNT_HW_CACHE_RESULT_MAX],
      30                 :            :                        u64 config)
      31                 :            : {
      32                 :            :         unsigned int cache_type, cache_op, cache_result, ret;
      33                 :            : 
      34                 :          0 :         cache_type = (config >>  0) & 0xff;
      35         [ #  # ]:          0 :         if (cache_type >= PERF_COUNT_HW_CACHE_MAX)
      36                 :            :                 return -EINVAL;
      37                 :            : 
      38                 :          0 :         cache_op = (config >>  8) & 0xff;
      39         [ #  # ]:          0 :         if (cache_op >= PERF_COUNT_HW_CACHE_OP_MAX)
      40                 :            :                 return -EINVAL;
      41                 :            : 
      42                 :          0 :         cache_result = (config >> 16) & 0xff;
      43         [ #  # ]:          0 :         if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
      44                 :            :                 return -EINVAL;
      45                 :            : 
      46                 :          0 :         ret = (int)(*cache_map)[cache_type][cache_op][cache_result];
      47                 :            : 
      48         [ #  # ]:          0 :         if (ret == CACHE_OP_UNSUPPORTED)
      49                 :            :                 return -ENOENT;
      50                 :            : 
      51                 :          0 :         return ret;
      52                 :            : }
      53                 :            : 
      54                 :            : static int
      55                 :            : armpmu_map_hw_event(const unsigned (*event_map)[PERF_COUNT_HW_MAX], u64 config)
      56                 :            : {
      57                 :            :         int mapping;
      58                 :            : 
      59         [ #  # ]:          0 :         if (config >= PERF_COUNT_HW_MAX)
      60                 :            :                 return -EINVAL;
      61                 :            : 
      62                 :          0 :         mapping = (*event_map)[config];
      63         [ #  # ]:          0 :         return mapping == HW_OP_UNSUPPORTED ? -ENOENT : mapping;
      64                 :            : }
      65                 :            : 
      66                 :            : static int
      67                 :            : armpmu_map_raw_event(u32 raw_event_mask, u64 config)
      68                 :            : {
      69                 :          0 :         return (int)(config & raw_event_mask);
      70                 :            : }
      71                 :            : 
      72                 :            : int
      73                 :          0 : armpmu_map_event(struct perf_event *event,
      74                 :            :                  const unsigned (*event_map)[PERF_COUNT_HW_MAX],
      75                 :            :                  const unsigned (*cache_map)
      76                 :            :                                 [PERF_COUNT_HW_CACHE_MAX]
      77                 :            :                                 [PERF_COUNT_HW_CACHE_OP_MAX]
      78                 :            :                                 [PERF_COUNT_HW_CACHE_RESULT_MAX],
      79                 :            :                  u32 raw_event_mask)
      80                 :            : {
      81                 :          0 :         u64 config = event->attr.config;
      82                 :            : 
      83   [ #  #  #  # ]:          0 :         switch (event->attr.type) {
      84                 :            :         case PERF_TYPE_HARDWARE:
      85                 :          0 :                 return armpmu_map_hw_event(event_map, config);
      86                 :            :         case PERF_TYPE_HW_CACHE:
      87                 :          0 :                 return armpmu_map_cache_event(cache_map, config);
      88                 :            :         case PERF_TYPE_RAW:
      89                 :          0 :                 return armpmu_map_raw_event(raw_event_mask, config);
      90                 :            :         default:
      91         [ #  # ]:          0 :                 if (event->attr.type >= PERF_TYPE_MAX)
      92                 :          0 :                         return armpmu_map_raw_event(raw_event_mask, config);
      93                 :            :         }
      94                 :            : 
      95                 :            :         return -ENOENT;
      96                 :            : }
      97                 :            : 
      98                 :          0 : int armpmu_event_set_period(struct perf_event *event)
      99                 :            : {
     100                 :          0 :         struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
     101                 :            :         struct hw_perf_event *hwc = &event->hw;
     102                 :          0 :         s64 left = local64_read(&hwc->period_left);
     103                 :          0 :         s64 period = hwc->sample_period;
     104                 :            :         int ret = 0;
     105                 :            : 
     106         [ #  # ]:          0 :         if (unlikely(left <= -period)) {
     107                 :            :                 left = period;
     108                 :            :                 local64_set(&hwc->period_left, left);
     109                 :          0 :                 hwc->last_period = period;
     110                 :            :                 ret = 1;
     111                 :            :         }
     112                 :            : 
     113         [ #  # ]:          0 :         if (unlikely(left <= 0)) {
     114                 :          0 :                 left += period;
     115                 :            :                 local64_set(&hwc->period_left, left);
     116                 :          0 :                 hwc->last_period = period;
     117                 :            :                 ret = 1;
     118                 :            :         }
     119                 :            : 
     120         [ #  # ]:          0 :         if (left > (s64)armpmu->max_period)
     121                 :            :                 left = armpmu->max_period;
     122                 :            : 
     123                 :          0 :         local64_set(&hwc->prev_count, (u64)-left);
     124                 :            : 
     125                 :          0 :         armpmu->write_counter(event, (u64)(-left) & 0xffffffff);
     126                 :            : 
     127                 :          0 :         perf_event_update_userpage(event);
     128                 :            : 
     129                 :          0 :         return ret;
     130                 :            : }
     131                 :            : 
     132                 :          0 : u64 armpmu_event_update(struct perf_event *event)
     133                 :            : {
     134                 :          0 :         struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
     135                 :            :         struct hw_perf_event *hwc = &event->hw;
     136                 :            :         u64 delta, prev_raw_count, new_raw_count;
     137                 :            : 
     138                 :            : again:
     139                 :          0 :         prev_raw_count = local64_read(&hwc->prev_count);
     140                 :          0 :         new_raw_count = armpmu->read_counter(event);
     141                 :            : 
     142         [ #  # ]:          0 :         if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
     143                 :          0 :                              new_raw_count) != prev_raw_count)
     144                 :            :                 goto again;
     145                 :            : 
     146                 :          0 :         delta = (new_raw_count - prev_raw_count) & armpmu->max_period;
     147                 :            : 
     148                 :          0 :         local64_add(delta, &event->count);
     149                 :          0 :         local64_sub(delta, &hwc->period_left);
     150                 :            : 
     151                 :          0 :         return new_raw_count;
     152                 :            : }
     153                 :            : 
     154                 :            : static void
     155                 :          0 : armpmu_read(struct perf_event *event)
     156                 :            : {
     157                 :          0 :         armpmu_event_update(event);
     158                 :          0 : }
     159                 :            : 
     160                 :            : static void
     161                 :          0 : armpmu_stop(struct perf_event *event, int flags)
     162                 :            : {
     163                 :          0 :         struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
     164                 :            :         struct hw_perf_event *hwc = &event->hw;
     165                 :            : 
     166         [ #  # ]:          0 :         if (!cpumask_test_cpu(smp_processor_id(), &armpmu->valid_cpus))
     167                 :          0 :                 return;
     168                 :            :         /*
     169                 :            :          * ARM pmu always has to update the counter, so ignore
     170                 :            :          * PERF_EF_UPDATE, see comments in armpmu_start().
     171                 :            :          */
     172         [ #  # ]:          0 :         if (!(hwc->state & PERF_HES_STOPPED)) {
     173                 :          0 :                 armpmu->disable(event);
     174                 :          0 :                 armpmu_event_update(event);
     175                 :          0 :                 hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE;
     176                 :            :         }
     177                 :            : }
     178                 :            : 
     179                 :          0 : static void armpmu_start(struct perf_event *event, int flags)
     180                 :            : {
     181                 :          0 :         struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
     182                 :            :         struct hw_perf_event *hwc = &event->hw;
     183                 :            : 
     184         [ #  # ]:          0 :         if (!cpumask_test_cpu(smp_processor_id(), &armpmu->valid_cpus))
     185                 :          0 :                 return;
     186                 :            :         /*
     187                 :            :          * ARM pmu always has to reprogram the period, so ignore
     188                 :            :          * PERF_EF_RELOAD, see the comment below.
     189                 :            :          */
     190         [ #  # ]:          0 :         if (flags & PERF_EF_RELOAD)
     191 [ #  # ][ #  # ]:          0 :                 WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));
                 [ #  # ]
     192                 :            : 
     193                 :          0 :         hwc->state = 0;
     194                 :            :         /*
     195                 :            :          * Set the period again. Some counters can't be stopped, so when we
     196                 :            :          * were stopped we simply disabled the IRQ source and the counter
     197                 :            :          * may have been left counting. If we don't do this step then we may
     198                 :            :          * get an interrupt too soon or *way* too late if the overflow has
     199                 :            :          * happened since disabling.
     200                 :            :          */
     201                 :          0 :         armpmu_event_set_period(event);
     202                 :          0 :         armpmu->enable(event);
     203                 :            : }
     204                 :            : 
     205                 :            : static void
     206                 :          0 : armpmu_del(struct perf_event *event, int flags)
     207                 :            : {
     208                 :          0 :         struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
     209                 :          0 :         struct pmu_hw_events *hw_events = armpmu->get_hw_events();
     210                 :            :         struct hw_perf_event *hwc = &event->hw;
     211                 :          0 :         int idx = hwc->idx;
     212                 :            : 
     213         [ #  # ]:          0 :         if (!cpumask_test_cpu(smp_processor_id(), &armpmu->valid_cpus))
     214                 :          0 :                 return;
     215                 :            : 
     216                 :          0 :         armpmu_stop(event, PERF_EF_UPDATE);
     217                 :          0 :         hw_events->events[idx] = NULL;
     218                 :          0 :         clear_bit(idx, hw_events->used_mask);
     219                 :            : 
     220                 :          0 :         perf_event_update_userpage(event);
     221                 :            : }
     222                 :            : 
     223                 :            : static int
     224                 :          0 : armpmu_add(struct perf_event *event, int flags)
     225                 :            : {
     226                 :          0 :         struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
     227                 :          0 :         struct pmu_hw_events *hw_events = armpmu->get_hw_events();
     228                 :            :         struct hw_perf_event *hwc = &event->hw;
     229                 :            :         int idx;
     230                 :            :         int err = 0;
     231                 :            : 
     232                 :            :         /* An event following a process won't be stopped earlier */
     233         [ #  # ]:          0 :         if (!cpumask_test_cpu(smp_processor_id(), &armpmu->valid_cpus))
     234                 :            :                 return 0;
     235                 :            : 
     236                 :          0 :         perf_pmu_disable(event->pmu);
     237                 :            : 
     238                 :            :         /* If we don't have a space for the counter then finish early. */
     239                 :          0 :         idx = armpmu->get_event_idx(hw_events, event);
     240         [ #  # ]:          0 :         if (idx < 0) {
     241                 :            :                 err = idx;
     242                 :            :                 goto out;
     243                 :            :         }
     244                 :            : 
     245                 :            :         /*
     246                 :            :          * If there is an event in the counter we are going to use then make
     247                 :            :          * sure it is disabled.
     248                 :            :          */
     249                 :          0 :         event->hw.idx = idx;
     250                 :          0 :         armpmu->disable(event);
     251                 :          0 :         hw_events->events[idx] = event;
     252                 :            : 
     253                 :          0 :         hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE;
     254         [ #  # ]:          0 :         if (flags & PERF_EF_START)
     255                 :          0 :                 armpmu_start(event, PERF_EF_RELOAD);
     256                 :            : 
     257                 :            :         /* Propagate our changes to the userspace mapping. */
     258                 :          0 :         perf_event_update_userpage(event);
     259                 :            : 
     260                 :            : out:
     261                 :          0 :         perf_pmu_enable(event->pmu);
     262                 :          0 :         return err;
     263                 :            : }
     264                 :            : 
     265                 :            : static int
     266                 :          0 : validate_event(struct pmu_hw_events *hw_events,
     267                 :            :                struct perf_event *event)
     268                 :            : {
     269                 :          0 :         struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
     270                 :            : 
     271         [ #  # ]:          0 :         if (is_software_event(event))
     272                 :            :                 return 1;
     273                 :            : 
     274         [ #  # ]:          0 :         if (event->state < PERF_EVENT_STATE_OFF)
     275                 :            :                 return 1;
     276                 :            : 
     277 [ #  # ][ #  # ]:          0 :         if (event->state == PERF_EVENT_STATE_OFF && !event->attr.enable_on_exec)
     278                 :            :                 return 1;
     279                 :            : 
     280                 :          0 :         return armpmu->get_event_idx(hw_events, event) >= 0;
     281                 :            : }
     282                 :            : 
     283                 :            : static int
     284                 :          0 : validate_group(struct perf_event *event)
     285                 :            : {
     286                 :          0 :         struct perf_event *sibling, *leader = event->group_leader;
     287                 :            :         struct pmu_hw_events fake_pmu;
     288                 :            :         DECLARE_BITMAP(fake_used_mask, ARMPMU_MAX_HWEVENTS);
     289                 :            : 
     290                 :            :         /*
     291                 :            :          * Initialise the fake PMU. We only need to populate the
     292                 :            :          * used_mask for the purposes of validation.
     293                 :            :          */
     294                 :          0 :         memset(fake_used_mask, 0, sizeof(fake_used_mask));
     295                 :          0 :         fake_pmu.used_mask = fake_used_mask;
     296                 :            : 
     297         [ #  # ]:          0 :         if (!validate_event(&fake_pmu, leader))
     298                 :            :                 return -EINVAL;
     299                 :            : 
     300         [ #  # ]:          0 :         list_for_each_entry(sibling, &leader->sibling_list, group_entry) {
     301         [ #  # ]:          0 :                 if (!validate_event(&fake_pmu, sibling))
     302                 :            :                         return -EINVAL;
     303                 :            :         }
     304                 :            : 
     305         [ #  # ]:          0 :         if (!validate_event(&fake_pmu, event))
     306                 :            :                 return -EINVAL;
     307                 :            : 
     308                 :          0 :         return 0;
     309                 :            : }
     310                 :            : 
     311                 :          0 : static irqreturn_t armpmu_dispatch_irq(int irq, void *dev)
     312                 :            : {
     313                 :            :         struct arm_pmu *armpmu = (struct arm_pmu *) dev;
     314                 :          0 :         struct platform_device *plat_device = armpmu->plat_device;
     315                 :          0 :         struct arm_pmu_platdata *plat = dev_get_platdata(&plat_device->dev);
     316                 :            : 
     317 [ #  # ][ #  # ]:          0 :         if (plat && plat->handle_irq)
     318                 :          0 :                 return plat->handle_irq(irq, dev, armpmu->handle_irq);
     319                 :            :         else
     320                 :          0 :                 return armpmu->handle_irq(irq, dev);
     321                 :            : }
     322                 :            : 
     323                 :            : static void
     324                 :            : armpmu_release_hardware(struct arm_pmu *armpmu)
     325                 :            : {
     326                 :          0 :         armpmu->free_irq(armpmu);
     327                 :            :         pm_runtime_put_sync(&armpmu->plat_device->dev);
     328                 :            : }
     329                 :            : 
     330                 :            : static int
     331                 :          0 : armpmu_reserve_hardware(struct arm_pmu *armpmu)
     332                 :            : {
     333                 :            :         int err;
     334                 :          0 :         struct platform_device *pmu_device = armpmu->plat_device;
     335                 :            : 
     336         [ #  # ]:          0 :         if (!pmu_device)
     337                 :            :                 return -ENODEV;
     338                 :            : 
     339                 :            :         pm_runtime_get_sync(&pmu_device->dev);
     340                 :          0 :         err = armpmu->request_irq(armpmu, armpmu_dispatch_irq);
     341         [ #  # ]:          0 :         if (err) {
     342                 :            :                 armpmu_release_hardware(armpmu);
     343                 :          0 :                 return err;
     344                 :            :         }
     345                 :            : 
     346                 :            :         return 0;
     347                 :            : }
     348                 :            : 
     349                 :            : static void
     350                 :          0 : hw_perf_event_destroy(struct perf_event *event)
     351                 :            : {
     352                 :          0 :         struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
     353                 :          0 :         atomic_t *active_events  = &armpmu->active_events;
     354                 :          0 :         struct mutex *pmu_reserve_mutex = &armpmu->reserve_mutex;
     355                 :            : 
     356         [ #  # ]:          0 :         if (atomic_dec_and_mutex_lock(active_events, pmu_reserve_mutex)) {
     357                 :            :                 armpmu_release_hardware(armpmu);
     358                 :          0 :                 mutex_unlock(pmu_reserve_mutex);
     359                 :            :         }
     360                 :          0 : }
     361                 :            : 
     362                 :            : static int
     363                 :            : event_requires_mode_exclusion(struct perf_event_attr *attr)
     364                 :            : {
     365                 :            :         return attr->exclude_idle || attr->exclude_user ||
     366                 :          0 :                attr->exclude_kernel || attr->exclude_hv;
     367                 :            : }
     368                 :            : 
     369                 :            : static int
     370                 :          0 : __hw_perf_event_init(struct perf_event *event)
     371                 :            : {
     372                 :          0 :         struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
     373                 :          0 :         struct hw_perf_event *hwc = &event->hw;
     374                 :            :         int mapping;
     375                 :            : 
     376                 :          0 :         mapping = armpmu->map_event(event);
     377                 :            : 
     378         [ #  # ]:          0 :         if (mapping < 0) {
     379                 :            :                 pr_debug("event %x:%llx not supported\n", event->attr.type,
     380                 :            :                          event->attr.config);
     381                 :            :                 return mapping;
     382                 :            :         }
     383                 :            : 
     384                 :            :         /*
     385                 :            :          * We don't assign an index until we actually place the event onto
     386                 :            :          * hardware. Use -1 to signify that we haven't decided where to put it
     387                 :            :          * yet. For SMP systems, each core has it's own PMU so we can't do any
     388                 :            :          * clever allocation or constraints checking at this point.
     389                 :            :          */
     390                 :          0 :         hwc->idx             = -1;
     391                 :          0 :         hwc->config_base     = 0;
     392                 :          0 :         hwc->config          = 0;
     393                 :          0 :         hwc->event_base              = 0;
     394                 :            : 
     395                 :            :         /*
     396                 :            :          * Check whether we need to exclude the counter from certain modes.
     397                 :            :          */
     398   [ #  #  #  # ]:          0 :         if ((!armpmu->set_event_filter ||
     399         [ #  # ]:          0 :              armpmu->set_event_filter(hwc, &event->attr)) &&
     400                 :            :              event_requires_mode_exclusion(&event->attr)) {
     401                 :            :                 pr_debug("ARM performance counters do not support "
     402                 :            :                          "mode exclusion\n");
     403                 :            :                 return -EOPNOTSUPP;
     404                 :            :         }
     405                 :            : 
     406                 :            :         /*
     407                 :            :          * Store the event encoding into the config_base field.
     408                 :            :          */
     409                 :          0 :         hwc->config_base         |= (unsigned long)mapping;
     410                 :            : 
     411         [ #  # ]:          0 :         if (!hwc->sample_period) {
     412                 :            :                 /*
     413                 :            :                  * For non-sampling runs, limit the sample_period to half
     414                 :            :                  * of the counter width. That way, the new counter value
     415                 :            :                  * is far less likely to overtake the previous one unless
     416                 :            :                  * you have some serious IRQ latency issues.
     417                 :            :                  */
     418                 :          0 :                 hwc->sample_period  = armpmu->max_period >> 1;
     419                 :          0 :                 hwc->last_period    = hwc->sample_period;
     420                 :          0 :                 local64_set(&hwc->period_left, hwc->sample_period);
     421                 :            :         }
     422                 :            : 
     423         [ #  # ]:          0 :         if (event->group_leader != event) {
     424         [ #  # ]:          0 :                 if (validate_group(event) != 0)
     425                 :            :                         return -EINVAL;
     426                 :            :         }
     427                 :            : 
     428                 :            :         return 0;
     429                 :            : }
     430                 :            : 
     431                 :          0 : static int armpmu_event_init(struct perf_event *event)
     432                 :            : {
     433                 :          0 :         struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
     434                 :            :         int err = 0;
     435                 :          0 :         atomic_t *active_events = &armpmu->active_events;
     436                 :            : 
     437 [ #  # ][ #  # ]:          0 :         if (event->cpu != -1 &&
     438                 :          0 :                 !cpumask_test_cpu(event->cpu, &armpmu->valid_cpus))
     439                 :            :                 return -ENOENT;
     440                 :            : 
     441                 :            :         /* does not support taken branch sampling */
     442         [ #  # ]:          0 :         if (has_branch_stack(event))
     443                 :            :                 return -EOPNOTSUPP;
     444                 :            : 
     445         [ #  # ]:          0 :         if (armpmu->map_event(event) == -ENOENT)
     446                 :            :                 return -ENOENT;
     447                 :            : 
     448                 :          0 :         event->destroy = hw_perf_event_destroy;
     449                 :            : 
     450         [ #  # ]:          0 :         if (!atomic_inc_not_zero(active_events)) {
     451                 :          0 :                 mutex_lock(&armpmu->reserve_mutex);
     452         [ #  # ]:          0 :                 if (atomic_read(active_events) == 0)
     453                 :          0 :                         err = armpmu_reserve_hardware(armpmu);
     454                 :            : 
     455         [ #  # ]:          0 :                 if (!err)
     456                 :            :                         atomic_inc(active_events);
     457                 :          0 :                 mutex_unlock(&armpmu->reserve_mutex);
     458                 :            :         }
     459                 :            : 
     460         [ #  # ]:          0 :         if (err)
     461                 :            :                 return err;
     462                 :            : 
     463                 :          0 :         err = __hw_perf_event_init(event);
     464         [ #  # ]:          0 :         if (err)
     465                 :          0 :                 hw_perf_event_destroy(event);
     466                 :            : 
     467                 :          0 :         return err;
     468                 :            : }
     469                 :            : 
     470                 :          0 : static void armpmu_enable(struct pmu *pmu)
     471                 :            : {
     472                 :            :         struct arm_pmu *armpmu = to_arm_pmu(pmu);
     473                 :          0 :         struct pmu_hw_events *hw_events = armpmu->get_hw_events();
     474                 :          0 :         int enabled = bitmap_weight(hw_events->used_mask, armpmu->num_events);
     475                 :            : 
     476         [ #  # ]:          0 :         if (enabled)
     477                 :          0 :                 armpmu->start(armpmu);
     478                 :          0 : }
     479                 :            : 
     480                 :          0 : static void armpmu_disable(struct pmu *pmu)
     481                 :            : {
     482                 :            :         struct arm_pmu *armpmu = to_arm_pmu(pmu);
     483                 :          0 :         armpmu->stop(armpmu);
     484                 :          0 : }
     485                 :            : 
     486                 :            : #ifdef CONFIG_PM_RUNTIME
     487                 :            : static int armpmu_runtime_resume(struct device *dev)
     488                 :            : {
     489                 :            :         struct arm_pmu_platdata *plat = dev_get_platdata(dev);
     490                 :            : 
     491                 :            :         if (plat && plat->runtime_resume)
     492                 :            :                 return plat->runtime_resume(dev);
     493                 :            : 
     494                 :            :         return 0;
     495                 :            : }
     496                 :            : 
     497                 :            : static int armpmu_runtime_suspend(struct device *dev)
     498                 :            : {
     499                 :            :         struct arm_pmu_platdata *plat = dev_get_platdata(dev);
     500                 :            : 
     501                 :            :         if (plat && plat->runtime_suspend)
     502                 :            :                 return plat->runtime_suspend(dev);
     503                 :            : 
     504                 :            :         return 0;
     505                 :            : }
     506                 :            : #endif
     507                 :            : 
     508                 :            : const struct dev_pm_ops armpmu_dev_pm_ops = {
     509                 :            :         SET_RUNTIME_PM_OPS(armpmu_runtime_suspend, armpmu_runtime_resume, NULL)
     510                 :            : };
     511                 :            : 
     512                 :          0 : static void armpmu_init(struct arm_pmu *armpmu)
     513                 :            : {
     514                 :          0 :         atomic_set(&armpmu->active_events, 0);
     515                 :          0 :         mutex_init(&armpmu->reserve_mutex);
     516                 :            : 
     517                 :          0 :         armpmu->pmu = (struct pmu) {
     518                 :            :                 .pmu_enable     = armpmu_enable,
     519                 :            :                 .pmu_disable    = armpmu_disable,
     520                 :            :                 .event_init     = armpmu_event_init,
     521                 :            :                 .add            = armpmu_add,
     522                 :            :                 .del            = armpmu_del,
     523                 :            :                 .start          = armpmu_start,
     524                 :            :                 .stop           = armpmu_stop,
     525                 :            :                 .read           = armpmu_read,
     526                 :            :         };
     527                 :          0 : }
     528                 :            : 
     529                 :          0 : int armpmu_register(struct arm_pmu *armpmu, int type)
     530                 :            : {
     531                 :          0 :         armpmu_init(armpmu);
     532                 :            :         pm_runtime_enable(&armpmu->plat_device->dev);
     533                 :          0 :         pr_info("enabled with %s PMU driver, %d counters available\n",
     534                 :            :                         armpmu->name, armpmu->num_events);
     535                 :          0 :         return perf_pmu_register(&armpmu->pmu, armpmu->name, type);
     536                 :            : }
     537                 :            : 
     538                 :            : /*
     539                 :            :  * Callchain handling code.
     540                 :            :  */
     541                 :            : 
     542                 :            : /*
     543                 :            :  * The registers we're interested in are at the end of the variable
     544                 :            :  * length saved register structure. The fp points at the end of this
     545                 :            :  * structure so the address of this struct is:
     546                 :            :  * (struct frame_tail *)(xxx->fp)-1
     547                 :            :  *
     548                 :            :  * This code has been adapted from the ARM OProfile support.
     549                 :            :  */
     550                 :            : struct frame_tail {
     551                 :            :         struct frame_tail __user *fp;
     552                 :            :         unsigned long sp;
     553                 :            :         unsigned long lr;
     554                 :            : } __attribute__((packed));
     555                 :            : 
     556                 :            : /*
     557                 :            :  * Get the return address for a single stackframe and return a pointer to the
     558                 :            :  * next frame tail.
     559                 :            :  */
     560                 :            : static struct frame_tail __user *
     561                 :          0 : user_backtrace(struct frame_tail __user *tail,
     562                 :            :                struct perf_callchain_entry *entry)
     563                 :            : {
     564                 :            :         struct frame_tail buftail;
     565                 :            : 
     566                 :            :         /* Also check accessibility of one struct frame_tail beyond */
     567         [ #  # ]:          0 :         if (!access_ok(VERIFY_READ, tail, sizeof(buftail)))
     568                 :            :                 return NULL;
     569         [ #  # ]:          0 :         if (__copy_from_user_inatomic(&buftail, tail, sizeof(buftail)))
     570                 :            :                 return NULL;
     571                 :            : 
     572                 :          0 :         perf_callchain_store(entry, buftail.lr);
     573                 :            : 
     574                 :            :         /*
     575                 :            :          * Frame pointers should strictly progress back up the stack
     576                 :            :          * (towards higher addresses).
     577                 :            :          */
     578         [ #  # ]:          0 :         if (tail + 1 >= buftail.fp)
     579                 :            :                 return NULL;
     580                 :            : 
     581                 :          0 :         return buftail.fp - 1;
     582                 :            : }
     583                 :            : 
     584                 :            : void
     585                 :          0 : perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs)
     586                 :            : {
     587                 :            :         struct frame_tail __user *tail;
     588                 :            : 
     589 [ #  # ][ #  # ]:          0 :         if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
     590                 :            :                 /* We don't support guest os callchain now */
     591                 :          0 :                 return;
     592                 :            :         }
     593                 :            : 
     594                 :          0 :         perf_callchain_store(entry, regs->ARM_pc);
     595                 :          0 :         tail = (struct frame_tail __user *)regs->ARM_fp - 1;
     596                 :            : 
     597 [ #  # ][ #  # ]:          0 :         while ((entry->nr < PERF_MAX_STACK_DEPTH) &&
     598         [ #  # ]:          0 :                tail && !((unsigned long)tail & 0x3))
     599                 :          0 :                 tail = user_backtrace(tail, entry);
     600                 :            : }
     601                 :            : 
     602                 :            : /*
     603                 :            :  * Gets called by walk_stackframe() for every stackframe. This will be called
     604                 :            :  * whist unwinding the stackframe and is like a subroutine return so we use
     605                 :            :  * the PC.
     606                 :            :  */
     607                 :            : static int
     608                 :          0 : callchain_trace(struct stackframe *fr,
     609                 :            :                 void *data)
     610                 :            : {
     611                 :            :         struct perf_callchain_entry *entry = data;
     612                 :          0 :         perf_callchain_store(entry, fr->pc);
     613                 :          0 :         return 0;
     614                 :            : }
     615                 :            : 
     616                 :            : void
     617                 :          0 : perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs)
     618                 :            : {
     619                 :            :         struct stackframe fr;
     620                 :            : 
     621 [ #  # ][ #  # ]:          0 :         if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
     622                 :            :                 /* We don't support guest os callchain now */
     623                 :          0 :                 return;
     624                 :            :         }
     625                 :            : 
     626                 :          0 :         fr.fp = regs->ARM_fp;
     627                 :          0 :         fr.sp = regs->ARM_sp;
     628                 :          0 :         fr.lr = regs->ARM_lr;
     629                 :          0 :         fr.pc = regs->ARM_pc;
     630                 :          0 :         walk_stackframe(&fr, callchain_trace, entry);
     631                 :            : }
     632                 :            : 
     633                 :          0 : unsigned long perf_instruction_pointer(struct pt_regs *regs)
     634                 :            : {
     635 [ #  # ][ #  # ]:          0 :         if (perf_guest_cbs && perf_guest_cbs->is_in_guest())
     636                 :          0 :                 return perf_guest_cbs->get_guest_ip();
     637                 :            : 
     638                 :          0 :         return instruction_pointer(regs);
     639                 :            : }
     640                 :            : 
     641                 :          0 : unsigned long perf_misc_flags(struct pt_regs *regs)
     642                 :            : {
     643                 :            :         int misc = 0;
     644                 :            : 
     645 [ #  # ][ #  # ]:          0 :         if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
     646         [ #  # ]:          0 :                 if (perf_guest_cbs->is_user_mode())
     647                 :            :                         misc |= PERF_RECORD_MISC_GUEST_USER;
     648                 :            :                 else
     649                 :            :                         misc |= PERF_RECORD_MISC_GUEST_KERNEL;
     650                 :            :         } else {
     651         [ #  # ]:          0 :                 if (user_mode(regs))
     652                 :            :                         misc |= PERF_RECORD_MISC_USER;
     653                 :            :                 else
     654                 :            :                         misc |= PERF_RECORD_MISC_KERNEL;
     655                 :            :         }
     656                 :            : 
     657                 :          0 :         return misc;
     658                 :            : }

Generated by: LCOV version 1.9