d35869ba34
Now that Intel PT supports more types of trace content than just branch tracing, it may be useful to allow the user to disable branch tracing when it is not needed. The special case is BDW, where not setting BranchEn is not supported. This is slightly trickier than necessary, because up to this moment the driver has been setting BranchEn automatically and the userspace assumes as much. Instead of reversing the semantics of BranchEn, we introduce a 'passthrough' bit, which will forego the default and allow the user to set BranchEn to their heart's content. Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: Arnaldo Carvalho de Melo <acme@infradead.org> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Borislav Petkov <bp@suse.de> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Vince Weaver <vincent.weaver@maine.edu> Cc: vince@deater.net Link: http://lkml.kernel.org/r/20170206144140.14402-1-alexander.shishkin@linux.intel.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
193 lines
5.3 KiB
C
193 lines
5.3 KiB
C
/*
|
|
* 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__
|
|
|
|
/*
|
|
* PT MSR bit definitions
|
|
*/
|
|
#define RTIT_CTL_TRACEEN BIT(0)
|
|
#define RTIT_CTL_CYCLEACC BIT(1)
|
|
#define RTIT_CTL_OS BIT(2)
|
|
#define RTIT_CTL_USR BIT(3)
|
|
#define RTIT_CTL_PWR_EVT_EN BIT(4)
|
|
#define RTIT_CTL_FUP_ON_PTW BIT(5)
|
|
#define RTIT_CTL_CR3EN BIT(7)
|
|
#define RTIT_CTL_TOPA BIT(8)
|
|
#define RTIT_CTL_MTC_EN BIT(9)
|
|
#define RTIT_CTL_TSC_EN BIT(10)
|
|
#define RTIT_CTL_DISRETC BIT(11)
|
|
#define RTIT_CTL_PTW_EN BIT(12)
|
|
#define RTIT_CTL_BRANCH_EN BIT(13)
|
|
#define RTIT_CTL_MTC_RANGE_OFFSET 14
|
|
#define RTIT_CTL_MTC_RANGE (0x0full << RTIT_CTL_MTC_RANGE_OFFSET)
|
|
#define RTIT_CTL_CYC_THRESH_OFFSET 19
|
|
#define RTIT_CTL_CYC_THRESH (0x0full << RTIT_CTL_CYC_THRESH_OFFSET)
|
|
#define RTIT_CTL_PSB_FREQ_OFFSET 24
|
|
#define RTIT_CTL_PSB_FREQ (0x0full << RTIT_CTL_PSB_FREQ_OFFSET)
|
|
#define RTIT_CTL_ADDR0_OFFSET 32
|
|
#define RTIT_CTL_ADDR0 (0x0full << RTIT_CTL_ADDR0_OFFSET)
|
|
#define RTIT_CTL_ADDR1_OFFSET 36
|
|
#define RTIT_CTL_ADDR1 (0x0full << RTIT_CTL_ADDR1_OFFSET)
|
|
#define RTIT_CTL_ADDR2_OFFSET 40
|
|
#define RTIT_CTL_ADDR2 (0x0full << RTIT_CTL_ADDR2_OFFSET)
|
|
#define RTIT_CTL_ADDR3_OFFSET 44
|
|
#define RTIT_CTL_ADDR3 (0x0full << RTIT_CTL_ADDR3_OFFSET)
|
|
#define RTIT_STATUS_FILTEREN BIT(0)
|
|
#define RTIT_STATUS_CONTEXTEN BIT(1)
|
|
#define RTIT_STATUS_TRIGGEREN BIT(2)
|
|
#define RTIT_STATUS_BUFFOVF BIT(3)
|
|
#define RTIT_STATUS_ERROR BIT(4)
|
|
#define RTIT_STATUS_STOPPED BIT(5)
|
|
|
|
/*
|
|
* Single-entry ToPA: when this close to region boundary, switch
|
|
* buffers to avoid losing data.
|
|
*/
|
|
#define TOPA_PMI_MARGIN 512
|
|
|
|
#define TOPA_SHIFT 12
|
|
|
|
static inline unsigned int sizes(unsigned int tsz)
|
|
{
|
|
return 1 << (tsz + TOPA_SHIFT);
|
|
};
|
|
|
|
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 PT_CPUID_LEAVES 2
|
|
#define PT_CPUID_REGS_NUM 4 /* number of regsters (eax, ebx, ecx, edx) */
|
|
|
|
/* TSC to Core Crystal Clock Ratio */
|
|
#define CPUID_TSC_LEAF 0x15
|
|
|
|
enum pt_capabilities {
|
|
PT_CAP_max_subleaf = 0,
|
|
PT_CAP_cr3_filtering,
|
|
PT_CAP_psb_cyc,
|
|
PT_CAP_ip_filtering,
|
|
PT_CAP_mtc,
|
|
PT_CAP_ptwrite,
|
|
PT_CAP_power_event_trace,
|
|
PT_CAP_topa_output,
|
|
PT_CAP_topa_multiple_entries,
|
|
PT_CAP_single_range_output,
|
|
PT_CAP_payloads_lip,
|
|
PT_CAP_num_address_ranges,
|
|
PT_CAP_mtc_periods,
|
|
PT_CAP_cycle_thresholds,
|
|
PT_CAP_psb_periods,
|
|
};
|
|
|
|
struct pt_pmu {
|
|
struct pmu pmu;
|
|
u32 caps[PT_CPUID_REGS_NUM * PT_CPUID_LEAVES];
|
|
bool vmx;
|
|
bool branch_en_always_on;
|
|
unsigned long max_nonturbo_ratio;
|
|
unsigned int tsc_art_num;
|
|
unsigned int tsc_art_den;
|
|
};
|
|
|
|
/**
|
|
* 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;
|
|
local64_t head;
|
|
bool snapshot;
|
|
unsigned long stop_pos, intr_pos;
|
|
void **data_pages;
|
|
struct topa_entry *topa_index[0];
|
|
};
|
|
|
|
#define PT_FILTERS_NUM 4
|
|
|
|
/**
|
|
* struct pt_filter - IP range filter configuration
|
|
* @msr_a: range start, goes to RTIT_ADDRn_A
|
|
* @msr_b: range end, goes to RTIT_ADDRn_B
|
|
* @config: 4-bit field in RTIT_CTL
|
|
*/
|
|
struct pt_filter {
|
|
unsigned long msr_a;
|
|
unsigned long msr_b;
|
|
unsigned long config;
|
|
};
|
|
|
|
/**
|
|
* struct pt_filters - IP range filtering context
|
|
* @filter: filters defined for this context
|
|
* @nr_filters: number of defined filters in the @filter array
|
|
*/
|
|
struct pt_filters {
|
|
struct pt_filter filter[PT_FILTERS_NUM];
|
|
unsigned int nr_filters;
|
|
};
|
|
|
|
/**
|
|
* struct pt - per-cpu pt context
|
|
* @handle: perf output handle
|
|
* @filters: last configured filters
|
|
* @handle_nmi: do handle PT PMI on this cpu, there's an active event
|
|
* @vmx_on: 1 if VMX is ON on this cpu
|
|
*/
|
|
struct pt {
|
|
struct perf_output_handle handle;
|
|
struct pt_filters filters;
|
|
int handle_nmi;
|
|
int vmx_on;
|
|
};
|
|
|
|
#endif /* __INTEL_PT_H__ */
|