mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-23 12:43:55 +08:00
perf/x86/intel/pt: Add Intel PT PMU driver
Add support for Intel Processor Trace (PT) to kernel's perf events. PT is an extension of Intel Architecture that collects information about software execuction such as control flow, execution modes and timings and formats it into highly compressed binary packets. Even being compressed, these packets are generated at hundreds of megabytes per second per core, which makes it impractical to decode them on the fly in the kernel. This driver exports trace data by through AUX space in the perf ring buffer, which is zero-copy mapped into userspace for faster data retrieval. Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: Borislav Petkov <bp@alien8.de> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Kaixu Xia <kaixu.xia@linaro.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Robert Richter <rric@kernel.org> Cc: Stephane Eranian <eranian@google.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: acme@infradead.org Cc: adrian.hunter@intel.com Cc: kan.liang@intel.com Cc: markus.t.metzger@intel.com Cc: mathieu.poirier@linaro.org Link: http://lkml.kernel.org/r/1422614392-114498-1-git-send-email-alexander.shishkin@linux.intel.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
parent
4807034248
commit
52ca9ced3f
@ -74,6 +74,24 @@
|
||||
#define MSR_IA32_PERF_CAPABILITIES 0x00000345
|
||||
#define MSR_PEBS_LD_LAT_THRESHOLD 0x000003f6
|
||||
|
||||
#define MSR_IA32_RTIT_CTL 0x00000570
|
||||
#define RTIT_CTL_TRACEEN BIT(0)
|
||||
#define RTIT_CTL_OS BIT(2)
|
||||
#define RTIT_CTL_USR BIT(3)
|
||||
#define RTIT_CTL_CR3EN BIT(7)
|
||||
#define RTIT_CTL_TOPA BIT(8)
|
||||
#define RTIT_CTL_TSC_EN BIT(10)
|
||||
#define RTIT_CTL_DISRETC BIT(11)
|
||||
#define RTIT_CTL_BRANCH_EN BIT(13)
|
||||
#define MSR_IA32_RTIT_STATUS 0x00000571
|
||||
#define RTIT_STATUS_CONTEXTEN BIT(1)
|
||||
#define RTIT_STATUS_TRIGGEREN BIT(2)
|
||||
#define RTIT_STATUS_ERROR BIT(4)
|
||||
#define RTIT_STATUS_STOPPED BIT(5)
|
||||
#define MSR_IA32_RTIT_CR3_MATCH 0x00000572
|
||||
#define MSR_IA32_RTIT_OUTPUT_BASE 0x00000560
|
||||
#define MSR_IA32_RTIT_OUTPUT_MASK 0x00000561
|
||||
|
||||
#define MSR_MTRRfix64K_00000 0x00000250
|
||||
#define MSR_MTRRfix16K_80000 0x00000258
|
||||
#define MSR_MTRRfix16K_A0000 0x00000259
|
||||
|
@ -40,6 +40,7 @@ endif
|
||||
obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_p6.o perf_event_knc.o perf_event_p4.o
|
||||
obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_lbr.o perf_event_intel_ds.o perf_event_intel.o
|
||||
obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_rapl.o perf_event_intel_cqm.o
|
||||
obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_pt.o
|
||||
|
||||
obj-$(CONFIG_PERF_EVENTS_INTEL_UNCORE) += perf_event_intel_uncore.o \
|
||||
perf_event_intel_uncore_snb.o \
|
||||
|
131
arch/x86/kernel/cpu/intel_pt.h
Normal file
131
arch/x86/kernel/cpu/intel_pt.h
Normal file
@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Intel(R) Processor Trace PMU driver for perf
|
||||
* Copyright (c) 2013-2014, Intel Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* Intel PT is specified in the Intel Architecture Instruction Set Extensions
|
||||
* Programming Reference:
|
||||
* http://software.intel.com/en-us/intel-isa-extensions
|
||||
*/
|
||||
|
||||
#ifndef __INTEL_PT_H__
|
||||
#define __INTEL_PT_H__
|
||||
|
||||
/*
|
||||
* Single-entry ToPA: when this close to region boundary, switch
|
||||
* buffers to avoid losing data.
|
||||
*/
|
||||
#define TOPA_PMI_MARGIN 512
|
||||
|
||||
/*
|
||||
* Table of Physical Addresses bits
|
||||
*/
|
||||
enum topa_sz {
|
||||
TOPA_4K = 0,
|
||||
TOPA_8K,
|
||||
TOPA_16K,
|
||||
TOPA_32K,
|
||||
TOPA_64K,
|
||||
TOPA_128K,
|
||||
TOPA_256K,
|
||||
TOPA_512K,
|
||||
TOPA_1MB,
|
||||
TOPA_2MB,
|
||||
TOPA_4MB,
|
||||
TOPA_8MB,
|
||||
TOPA_16MB,
|
||||
TOPA_32MB,
|
||||
TOPA_64MB,
|
||||
TOPA_128MB,
|
||||
TOPA_SZ_END,
|
||||
};
|
||||
|
||||
static inline unsigned int sizes(enum topa_sz tsz)
|
||||
{
|
||||
return 1 << (tsz + 12);
|
||||
};
|
||||
|
||||
struct topa_entry {
|
||||
u64 end : 1;
|
||||
u64 rsvd0 : 1;
|
||||
u64 intr : 1;
|
||||
u64 rsvd1 : 1;
|
||||
u64 stop : 1;
|
||||
u64 rsvd2 : 1;
|
||||
u64 size : 4;
|
||||
u64 rsvd3 : 2;
|
||||
u64 base : 36;
|
||||
u64 rsvd4 : 16;
|
||||
};
|
||||
|
||||
#define TOPA_SHIFT 12
|
||||
#define PT_CPUID_LEAVES 2
|
||||
|
||||
enum pt_capabilities {
|
||||
PT_CAP_max_subleaf = 0,
|
||||
PT_CAP_cr3_filtering,
|
||||
PT_CAP_topa_output,
|
||||
PT_CAP_topa_multiple_entries,
|
||||
PT_CAP_payloads_lip,
|
||||
};
|
||||
|
||||
struct pt_pmu {
|
||||
struct pmu pmu;
|
||||
u32 caps[4 * PT_CPUID_LEAVES];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct pt_buffer - buffer configuration; one buffer per task_struct or
|
||||
* cpu, depending on perf event configuration
|
||||
* @cpu: cpu for per-cpu allocation
|
||||
* @tables: list of ToPA tables in this buffer
|
||||
* @first: shorthand for first topa table
|
||||
* @last: shorthand for last topa table
|
||||
* @cur: current topa table
|
||||
* @nr_pages: buffer size in pages
|
||||
* @cur_idx: current output region's index within @cur table
|
||||
* @output_off: offset within the current output region
|
||||
* @data_size: running total of the amount of data in this buffer
|
||||
* @lost: if data was lost/truncated
|
||||
* @head: logical write offset inside the buffer
|
||||
* @snapshot: if this is for a snapshot/overwrite counter
|
||||
* @stop_pos: STOP topa entry in the buffer
|
||||
* @intr_pos: INT topa entry in the buffer
|
||||
* @data_pages: array of pages from perf
|
||||
* @topa_index: table of topa entries indexed by page offset
|
||||
*/
|
||||
struct pt_buffer {
|
||||
int cpu;
|
||||
struct list_head tables;
|
||||
struct topa *first, *last, *cur;
|
||||
unsigned int cur_idx;
|
||||
size_t output_off;
|
||||
unsigned long nr_pages;
|
||||
local_t data_size;
|
||||
local_t lost;
|
||||
local64_t head;
|
||||
bool snapshot;
|
||||
unsigned long stop_pos, intr_pos;
|
||||
void **data_pages;
|
||||
struct topa_entry *topa_index[0];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct pt - per-cpu pt context
|
||||
* @handle: perf output handle
|
||||
* @handle_nmi: do handle PT PMI on this cpu, there's an active event
|
||||
*/
|
||||
struct pt {
|
||||
struct perf_output_handle handle;
|
||||
int handle_nmi;
|
||||
};
|
||||
|
||||
#endif /* __INTEL_PT_H__ */
|
@ -808,6 +808,8 @@ void intel_pmu_lbr_init_hsw(void);
|
||||
|
||||
int intel_pmu_setup_lbr_filter(struct perf_event *event);
|
||||
|
||||
void intel_pt_interrupt(void);
|
||||
|
||||
int p4_pmu_init(void);
|
||||
|
||||
int p6_pmu_init(void);
|
||||
|
@ -1589,6 +1589,14 @@ again:
|
||||
x86_pmu.drain_pebs(regs);
|
||||
}
|
||||
|
||||
/*
|
||||
* Intel PT
|
||||
*/
|
||||
if (__test_and_clear_bit(55, (unsigned long *)&status)) {
|
||||
handled++;
|
||||
intel_pt_interrupt();
|
||||
}
|
||||
|
||||
/*
|
||||
* Checkpointed counters can lead to 'spurious' PMIs because the
|
||||
* rollback caused by the PMI will have cleared the overflow status
|
||||
|
1096
arch/x86/kernel/cpu/perf_event_intel_pt.c
Normal file
1096
arch/x86/kernel/cpu/perf_event_intel_pt.c
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user