aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/cpu/perf_event.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/cpu/perf_event.c')
-rw-r--r--arch/x86/kernel/cpu/perf_event.c50
1 files changed, 28 insertions, 22 deletions
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
index eed3673a8656..3a0338b4b179 100644
--- a/arch/x86/kernel/cpu/perf_event.c
+++ b/arch/x86/kernel/cpu/perf_event.c
@@ -31,6 +31,7 @@
31#include <asm/nmi.h> 31#include <asm/nmi.h>
32#include <asm/compat.h> 32#include <asm/compat.h>
33#include <asm/smp.h> 33#include <asm/smp.h>
34#include <asm/alternative.h>
34 35
35#if 0 36#if 0
36#undef wrmsrl 37#undef wrmsrl
@@ -363,12 +364,18 @@ again:
363 return new_raw_count; 364 return new_raw_count;
364} 365}
365 366
366/* using X86_FEATURE_PERFCTR_CORE to later implement ALTERNATIVE() here */
367static inline int x86_pmu_addr_offset(int index) 367static inline int x86_pmu_addr_offset(int index)
368{ 368{
369 if (boot_cpu_has(X86_FEATURE_PERFCTR_CORE)) 369 int offset;
370 return index << 1; 370
371 return index; 371 /* offset = X86_FEATURE_PERFCTR_CORE ? index << 1 : index */
372 alternative_io(ASM_NOP2,
373 "shll $1, %%eax",
374 X86_FEATURE_PERFCTR_CORE,
375 "=a" (offset),
376 "a" (index));
377
378 return offset;
372} 379}
373 380
374static inline unsigned int x86_pmu_config_addr(int index) 381static inline unsigned int x86_pmu_config_addr(int index)
@@ -586,8 +593,12 @@ static int x86_setup_perfctr(struct perf_event *event)
586 return -EOPNOTSUPP; 593 return -EOPNOTSUPP;
587 } 594 }
588 595
596 /*
597 * Do not allow config1 (extended registers) to propagate,
598 * there's no sane user-space generalization yet:
599 */
589 if (attr->type == PERF_TYPE_RAW) 600 if (attr->type == PERF_TYPE_RAW)
590 return x86_pmu_extra_regs(event->attr.config, event); 601 return 0;
591 602
592 if (attr->type == PERF_TYPE_HW_CACHE) 603 if (attr->type == PERF_TYPE_HW_CACHE)
593 return set_ext_hw_attr(hwc, event); 604 return set_ext_hw_attr(hwc, event);
@@ -609,8 +620,8 @@ static int x86_setup_perfctr(struct perf_event *event)
609 /* 620 /*
610 * Branch tracing: 621 * Branch tracing:
611 */ 622 */
612 if ((attr->config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS) && 623 if (attr->config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS &&
613 (hwc->sample_period == 1)) { 624 !attr->freq && hwc->sample_period == 1) {
614 /* BTS is not supported by this architecture. */ 625 /* BTS is not supported by this architecture. */
615 if (!x86_pmu.bts_active) 626 if (!x86_pmu.bts_active)
616 return -EOPNOTSUPP; 627 return -EOPNOTSUPP;
@@ -1284,6 +1295,16 @@ static int x86_pmu_handle_irq(struct pt_regs *regs)
1284 1295
1285 cpuc = &__get_cpu_var(cpu_hw_events); 1296 cpuc = &__get_cpu_var(cpu_hw_events);
1286 1297
1298 /*
1299 * Some chipsets need to unmask the LVTPC in a particular spot
1300 * inside the nmi handler. As a result, the unmasking was pushed
1301 * into all the nmi handlers.
1302 *
1303 * This generic handler doesn't seem to have any issues where the
1304 * unmasking occurs so it was left at the top.
1305 */
1306 apic_write(APIC_LVTPC, APIC_DM_NMI);
1307
1287 for (idx = 0; idx < x86_pmu.num_counters; idx++) { 1308 for (idx = 0; idx < x86_pmu.num_counters; idx++) {
1288 if (!test_bit(idx, cpuc->active_mask)) { 1309 if (!test_bit(idx, cpuc->active_mask)) {
1289 /* 1310 /*
@@ -1370,8 +1391,6 @@ perf_event_nmi_handler(struct notifier_block *self,
1370 return NOTIFY_DONE; 1391 return NOTIFY_DONE;
1371 } 1392 }
1372 1393
1373 apic_write(APIC_LVTPC, APIC_DM_NMI);
1374
1375 handled = x86_pmu.handle_irq(args->regs); 1394 handled = x86_pmu.handle_irq(args->regs);
1376 if (!handled) 1395 if (!handled)
1377 return NOTIFY_DONE; 1396 return NOTIFY_DONE;
@@ -1754,17 +1773,6 @@ static struct pmu pmu = {
1754 * callchain support 1773 * callchain support
1755 */ 1774 */
1756 1775
1757static void
1758backtrace_warning_symbol(void *data, char *msg, unsigned long symbol)
1759{
1760 /* Ignore warnings */
1761}
1762
1763static void backtrace_warning(void *data, char *msg)
1764{
1765 /* Ignore warnings */
1766}
1767
1768static int backtrace_stack(void *data, char *name) 1776static int backtrace_stack(void *data, char *name)
1769{ 1777{
1770 return 0; 1778 return 0;
@@ -1778,8 +1786,6 @@ static void backtrace_address(void *data, unsigned long addr, int reliable)
1778} 1786}
1779 1787
1780static const struct stacktrace_ops backtrace_ops = { 1788static const struct stacktrace_ops backtrace_ops = {
1781 .warning = backtrace_warning,
1782 .warning_symbol = backtrace_warning_symbol,
1783 .stack = backtrace_stack, 1789 .stack = backtrace_stack,
1784 .address = backtrace_address, 1790 .address = backtrace_address,
1785 .walk_stack = print_context_stack_bp, 1791 .walk_stack = print_context_stack_bp,