hc
2023-10-25 6c2073b7aa40e29d0eca7d571dd7bc590c7ecaa7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
/*
 * 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__ */