diff options
Diffstat (limited to 'arch/x86/kernel/cpu/perf_event.c')
-rw-r--r-- | arch/x86/kernel/cpu/perf_event.c | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index eed3673a8656..e638689279d3 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c | |||
@@ -586,8 +586,12 @@ static int x86_setup_perfctr(struct perf_event *event) | |||
586 | return -EOPNOTSUPP; | 586 | return -EOPNOTSUPP; |
587 | } | 587 | } |
588 | 588 | ||
589 | /* | ||
590 | * Do not allow config1 (extended registers) to propagate, | ||
591 | * there's no sane user-space generalization yet: | ||
592 | */ | ||
589 | if (attr->type == PERF_TYPE_RAW) | 593 | if (attr->type == PERF_TYPE_RAW) |
590 | return x86_pmu_extra_regs(event->attr.config, event); | 594 | return 0; |
591 | 595 | ||
592 | if (attr->type == PERF_TYPE_HW_CACHE) | 596 | if (attr->type == PERF_TYPE_HW_CACHE) |
593 | return set_ext_hw_attr(hwc, event); | 597 | return set_ext_hw_attr(hwc, event); |
@@ -609,8 +613,8 @@ static int x86_setup_perfctr(struct perf_event *event) | |||
609 | /* | 613 | /* |
610 | * Branch tracing: | 614 | * Branch tracing: |
611 | */ | 615 | */ |
612 | if ((attr->config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS) && | 616 | if (attr->config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS && |
613 | (hwc->sample_period == 1)) { | 617 | !attr->freq && hwc->sample_period == 1) { |
614 | /* BTS is not supported by this architecture. */ | 618 | /* BTS is not supported by this architecture. */ |
615 | if (!x86_pmu.bts_active) | 619 | if (!x86_pmu.bts_active) |
616 | return -EOPNOTSUPP; | 620 | return -EOPNOTSUPP; |
@@ -1284,6 +1288,16 @@ static int x86_pmu_handle_irq(struct pt_regs *regs) | |||
1284 | 1288 | ||
1285 | cpuc = &__get_cpu_var(cpu_hw_events); | 1289 | cpuc = &__get_cpu_var(cpu_hw_events); |
1286 | 1290 | ||
1291 | /* | ||
1292 | * Some chipsets need to unmask the LVTPC in a particular spot | ||
1293 | * inside the nmi handler. As a result, the unmasking was pushed | ||
1294 | * into all the nmi handlers. | ||
1295 | * | ||
1296 | * This generic handler doesn't seem to have any issues where the | ||
1297 | * unmasking occurs so it was left at the top. | ||
1298 | */ | ||
1299 | apic_write(APIC_LVTPC, APIC_DM_NMI); | ||
1300 | |||
1287 | for (idx = 0; idx < x86_pmu.num_counters; idx++) { | 1301 | for (idx = 0; idx < x86_pmu.num_counters; idx++) { |
1288 | if (!test_bit(idx, cpuc->active_mask)) { | 1302 | if (!test_bit(idx, cpuc->active_mask)) { |
1289 | /* | 1303 | /* |
@@ -1370,8 +1384,6 @@ perf_event_nmi_handler(struct notifier_block *self, | |||
1370 | return NOTIFY_DONE; | 1384 | return NOTIFY_DONE; |
1371 | } | 1385 | } |
1372 | 1386 | ||
1373 | apic_write(APIC_LVTPC, APIC_DM_NMI); | ||
1374 | |||
1375 | handled = x86_pmu.handle_irq(args->regs); | 1387 | handled = x86_pmu.handle_irq(args->regs); |
1376 | if (!handled) | 1388 | if (!handled) |
1377 | return NOTIFY_DONE; | 1389 | return NOTIFY_DONE; |