diff options
| -rw-r--r-- | arch/arm/kernel/perf_event.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index 557e128e4df0..4a86a0133ac3 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c | |||
| @@ -259,20 +259,29 @@ out: | |||
| 259 | } | 259 | } |
| 260 | 260 | ||
| 261 | static int | 261 | static int |
| 262 | validate_event(struct pmu_hw_events *hw_events, | 262 | validate_event(struct pmu *pmu, struct pmu_hw_events *hw_events, |
| 263 | struct perf_event *event) | 263 | struct perf_event *event) |
| 264 | { | 264 | { |
| 265 | struct arm_pmu *armpmu = to_arm_pmu(event->pmu); | 265 | struct arm_pmu *armpmu; |
| 266 | 266 | ||
| 267 | if (is_software_event(event)) | 267 | if (is_software_event(event)) |
| 268 | return 1; | 268 | return 1; |
| 269 | 269 | ||
| 270 | /* | ||
| 271 | * Reject groups spanning multiple HW PMUs (e.g. CPU + CCI). The | ||
| 272 | * core perf code won't check that the pmu->ctx == leader->ctx | ||
| 273 | * until after pmu->event_init(event). | ||
| 274 | */ | ||
| 275 | if (event->pmu != pmu) | ||
| 276 | return 0; | ||
| 277 | |||
| 270 | if (event->state < PERF_EVENT_STATE_OFF) | 278 | if (event->state < PERF_EVENT_STATE_OFF) |
| 271 | return 1; | 279 | return 1; |
| 272 | 280 | ||
| 273 | if (event->state == PERF_EVENT_STATE_OFF && !event->attr.enable_on_exec) | 281 | if (event->state == PERF_EVENT_STATE_OFF && !event->attr.enable_on_exec) |
| 274 | return 1; | 282 | return 1; |
| 275 | 283 | ||
| 284 | armpmu = to_arm_pmu(event->pmu); | ||
| 276 | return armpmu->get_event_idx(hw_events, event) >= 0; | 285 | return armpmu->get_event_idx(hw_events, event) >= 0; |
| 277 | } | 286 | } |
| 278 | 287 | ||
| @@ -288,15 +297,15 @@ validate_group(struct perf_event *event) | |||
| 288 | */ | 297 | */ |
| 289 | memset(&fake_pmu.used_mask, 0, sizeof(fake_pmu.used_mask)); | 298 | memset(&fake_pmu.used_mask, 0, sizeof(fake_pmu.used_mask)); |
| 290 | 299 | ||
| 291 | if (!validate_event(&fake_pmu, leader)) | 300 | if (!validate_event(event->pmu, &fake_pmu, leader)) |
| 292 | return -EINVAL; | 301 | return -EINVAL; |
| 293 | 302 | ||
| 294 | list_for_each_entry(sibling, &leader->sibling_list, group_entry) { | 303 | list_for_each_entry(sibling, &leader->sibling_list, group_entry) { |
| 295 | if (!validate_event(&fake_pmu, sibling)) | 304 | if (!validate_event(event->pmu, &fake_pmu, sibling)) |
| 296 | return -EINVAL; | 305 | return -EINVAL; |
| 297 | } | 306 | } |
| 298 | 307 | ||
| 299 | if (!validate_event(&fake_pmu, event)) | 308 | if (!validate_event(event->pmu, &fake_pmu, event)) |
| 300 | return -EINVAL; | 309 | return -EINVAL; |
| 301 | 310 | ||
| 302 | return 0; | 311 | return 0; |
