cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

intel-pt-decoder.h (7661B)


      1/* SPDX-License-Identifier: GPL-2.0-only */
      2/*
      3 * intel_pt_decoder.h: Intel Processor Trace support
      4 * Copyright (c) 2013-2014, Intel Corporation.
      5 */
      6
      7#ifndef INCLUDE__INTEL_PT_DECODER_H__
      8#define INCLUDE__INTEL_PT_DECODER_H__
      9
     10#include <stdint.h>
     11#include <stddef.h>
     12#include <stdbool.h>
     13
     14#include <linux/rbtree.h>
     15
     16#include "intel-pt-insn-decoder.h"
     17
     18#define INTEL_PT_IN_TX		(1 << 0)
     19#define INTEL_PT_ABORT_TX	(1 << 1)
     20#define INTEL_PT_IFLAG		(1 << 2)
     21#define INTEL_PT_ASYNC		(1 << 2)
     22#define INTEL_PT_FUP_IP		(1 << 3)
     23#define INTEL_PT_SAMPLE_IPC	(1 << 4)
     24
     25enum intel_pt_sample_type {
     26	INTEL_PT_BRANCH		= 1 << 0,
     27	INTEL_PT_INSTRUCTION	= 1 << 1,
     28	INTEL_PT_TRANSACTION	= 1 << 2,
     29	INTEL_PT_PTW		= 1 << 3,
     30	INTEL_PT_MWAIT_OP	= 1 << 4,
     31	INTEL_PT_PWR_ENTRY	= 1 << 5,
     32	INTEL_PT_EX_STOP	= 1 << 6,
     33	INTEL_PT_PWR_EXIT	= 1 << 7,
     34	INTEL_PT_CBR_CHG	= 1 << 8,
     35	INTEL_PT_TRACE_BEGIN	= 1 << 9,
     36	INTEL_PT_TRACE_END	= 1 << 10,
     37	INTEL_PT_BLK_ITEMS	= 1 << 11,
     38	INTEL_PT_PSB_EVT	= 1 << 12,
     39	INTEL_PT_EVT		= 1 << 13,
     40	INTEL_PT_IFLAG_CHG	= 1 << 14,
     41};
     42
     43enum intel_pt_period_type {
     44	INTEL_PT_PERIOD_NONE,
     45	INTEL_PT_PERIOD_INSTRUCTIONS,
     46	INTEL_PT_PERIOD_TICKS,
     47	INTEL_PT_PERIOD_MTC,
     48};
     49
     50enum {
     51	INTEL_PT_ERR_NOMEM = 1,
     52	INTEL_PT_ERR_INTERN,
     53	INTEL_PT_ERR_BADPKT,
     54	INTEL_PT_ERR_NODATA,
     55	INTEL_PT_ERR_NOINSN,
     56	INTEL_PT_ERR_MISMAT,
     57	INTEL_PT_ERR_OVR,
     58	INTEL_PT_ERR_LOST,
     59	INTEL_PT_ERR_UNK,
     60	INTEL_PT_ERR_NELOOP,
     61	INTEL_PT_ERR_EPTW,
     62	INTEL_PT_ERR_MAX,
     63};
     64
     65enum intel_pt_param_flags {
     66	/*
     67	 * FUP packet can contain next linear instruction pointer instead of
     68	 * current linear instruction pointer.
     69	 */
     70	INTEL_PT_FUP_WITH_NLIP	= 1 << 0,
     71};
     72
     73enum intel_pt_blk_type {
     74	INTEL_PT_GP_REGS	= 1,
     75	INTEL_PT_PEBS_BASIC	= 4,
     76	INTEL_PT_PEBS_MEM	= 5,
     77	INTEL_PT_LBR_0		= 8,
     78	INTEL_PT_LBR_1		= 9,
     79	INTEL_PT_LBR_2		= 10,
     80	INTEL_PT_XMM		= 16,
     81	INTEL_PT_BLK_TYPE_MAX
     82};
     83
     84/*
     85 * The block type numbers are not sequential but here they are given sequential
     86 * positions to avoid wasting space for array placement.
     87 */
     88enum intel_pt_blk_type_pos {
     89	INTEL_PT_GP_REGS_POS,
     90	INTEL_PT_PEBS_BASIC_POS,
     91	INTEL_PT_PEBS_MEM_POS,
     92	INTEL_PT_LBR_0_POS,
     93	INTEL_PT_LBR_1_POS,
     94	INTEL_PT_LBR_2_POS,
     95	INTEL_PT_XMM_POS,
     96	INTEL_PT_BLK_TYPE_CNT
     97};
     98
     99/* Get the array position for a block type */
    100static inline int intel_pt_blk_type_pos(enum intel_pt_blk_type blk_type)
    101{
    102#define BLK_TYPE(bt) [INTEL_PT_##bt] = INTEL_PT_##bt##_POS + 1
    103	const int map[INTEL_PT_BLK_TYPE_MAX] = {
    104		BLK_TYPE(GP_REGS),
    105		BLK_TYPE(PEBS_BASIC),
    106		BLK_TYPE(PEBS_MEM),
    107		BLK_TYPE(LBR_0),
    108		BLK_TYPE(LBR_1),
    109		BLK_TYPE(LBR_2),
    110		BLK_TYPE(XMM),
    111	};
    112#undef BLK_TYPE
    113
    114	return blk_type < INTEL_PT_BLK_TYPE_MAX ? map[blk_type] - 1 : -1;
    115}
    116
    117#define INTEL_PT_BLK_ITEM_ID_CNT	32
    118
    119/*
    120 * Use unions so that the block items can be accessed by name or by array index.
    121 * There is an array of 32-bit masks for each block type, which indicate which
    122 * values are present. Then arrays of 32 64-bit values for each block type.
    123 */
    124struct intel_pt_blk_items {
    125	union {
    126		uint32_t mask[INTEL_PT_BLK_TYPE_CNT];
    127		struct {
    128			uint32_t has_rflags:1;
    129			uint32_t has_rip:1;
    130			uint32_t has_rax:1;
    131			uint32_t has_rcx:1;
    132			uint32_t has_rdx:1;
    133			uint32_t has_rbx:1;
    134			uint32_t has_rsp:1;
    135			uint32_t has_rbp:1;
    136			uint32_t has_rsi:1;
    137			uint32_t has_rdi:1;
    138			uint32_t has_r8:1;
    139			uint32_t has_r9:1;
    140			uint32_t has_r10:1;
    141			uint32_t has_r11:1;
    142			uint32_t has_r12:1;
    143			uint32_t has_r13:1;
    144			uint32_t has_r14:1;
    145			uint32_t has_r15:1;
    146			uint32_t has_unused_0:14;
    147			uint32_t has_ip:1;
    148			uint32_t has_applicable_counters:1;
    149			uint32_t has_timestamp:1;
    150			uint32_t has_unused_1:29;
    151			uint32_t has_mem_access_address:1;
    152			uint32_t has_mem_aux_info:1;
    153			uint32_t has_mem_access_latency:1;
    154			uint32_t has_tsx_aux_info:1;
    155			uint32_t has_unused_2:28;
    156			uint32_t has_lbr_0;
    157			uint32_t has_lbr_1;
    158			uint32_t has_lbr_2;
    159			uint32_t has_xmm;
    160		};
    161	};
    162	union {
    163		uint64_t val[INTEL_PT_BLK_TYPE_CNT][INTEL_PT_BLK_ITEM_ID_CNT];
    164		struct {
    165			struct {
    166				uint64_t rflags;
    167				uint64_t rip;
    168				uint64_t rax;
    169				uint64_t rcx;
    170				uint64_t rdx;
    171				uint64_t rbx;
    172				uint64_t rsp;
    173				uint64_t rbp;
    174				uint64_t rsi;
    175				uint64_t rdi;
    176				uint64_t r8;
    177				uint64_t r9;
    178				uint64_t r10;
    179				uint64_t r11;
    180				uint64_t r12;
    181				uint64_t r13;
    182				uint64_t r14;
    183				uint64_t r15;
    184				uint64_t unused_0[INTEL_PT_BLK_ITEM_ID_CNT - 18];
    185			};
    186			struct {
    187				uint64_t ip;
    188				uint64_t applicable_counters;
    189				uint64_t timestamp;
    190				uint64_t unused_1[INTEL_PT_BLK_ITEM_ID_CNT - 3];
    191			};
    192			struct {
    193				uint64_t mem_access_address;
    194				uint64_t mem_aux_info;
    195				uint64_t mem_access_latency;
    196				uint64_t tsx_aux_info;
    197				uint64_t unused_2[INTEL_PT_BLK_ITEM_ID_CNT - 4];
    198			};
    199			uint64_t lbr_0[INTEL_PT_BLK_ITEM_ID_CNT];
    200			uint64_t lbr_1[INTEL_PT_BLK_ITEM_ID_CNT];
    201			uint64_t lbr_2[INTEL_PT_BLK_ITEM_ID_CNT];
    202			uint64_t xmm[INTEL_PT_BLK_ITEM_ID_CNT];
    203		};
    204	};
    205	bool is_32_bit;
    206};
    207
    208struct intel_pt_vmcs_info {
    209	struct rb_node rb_node;
    210	uint64_t vmcs;
    211	uint64_t tsc_offset;
    212	bool reliable;
    213	bool error_printed;
    214};
    215
    216/*
    217 * Maximum number of event trace data in one go, assuming at most 1 per type
    218 * and 6-bits of type in the EVD packet.
    219 */
    220#define INTEL_PT_MAX_EVDS 64
    221
    222/* Event trace data from EVD packet */
    223struct intel_pt_evd {
    224	int type;
    225	uint64_t payload;
    226};
    227
    228struct intel_pt_state {
    229	enum intel_pt_sample_type type;
    230	bool from_nr;
    231	bool to_nr;
    232	bool from_iflag;
    233	bool to_iflag;
    234	int err;
    235	uint64_t from_ip;
    236	uint64_t to_ip;
    237	uint64_t tot_insn_cnt;
    238	uint64_t tot_cyc_cnt;
    239	uint64_t cycles;
    240	uint64_t timestamp;
    241	uint64_t est_timestamp;
    242	uint64_t trace_nr;
    243	uint64_t ptw_payload;
    244	uint64_t mwait_payload;
    245	uint64_t pwre_payload;
    246	uint64_t pwrx_payload;
    247	uint64_t cbr_payload;
    248	uint64_t psb_offset;
    249	uint32_t cbr;
    250	uint32_t flags;
    251	enum intel_pt_insn_op insn_op;
    252	int insn_len;
    253	char insn[INTEL_PT_INSN_BUF_SZ];
    254	struct intel_pt_blk_items items;
    255	int cfe_type;
    256	int cfe_vector;
    257	int evd_cnt;
    258	struct intel_pt_evd *evd;
    259};
    260
    261struct intel_pt_insn;
    262
    263struct intel_pt_buffer {
    264	const unsigned char *buf;
    265	size_t len;
    266	bool consecutive;
    267	uint64_t ref_timestamp;
    268	uint64_t trace_nr;
    269};
    270
    271typedef int (*intel_pt_lookahead_cb_t)(struct intel_pt_buffer *, void *);
    272
    273struct intel_pt_params {
    274	int (*get_trace)(struct intel_pt_buffer *buffer, void *data);
    275	int (*walk_insn)(struct intel_pt_insn *intel_pt_insn,
    276			 uint64_t *insn_cnt_ptr, uint64_t *ip, uint64_t to_ip,
    277			 uint64_t max_insn_cnt, void *data);
    278	bool (*pgd_ip)(uint64_t ip, void *data);
    279	int (*lookahead)(void *data, intel_pt_lookahead_cb_t cb, void *cb_data);
    280	struct intel_pt_vmcs_info *(*findnew_vmcs_info)(void *data, uint64_t vmcs);
    281	void *data;
    282	bool return_compression;
    283	bool branch_enable;
    284	bool vm_time_correlation;
    285	bool vm_tm_corr_dry_run;
    286	uint64_t first_timestamp;
    287	uint64_t ctl;
    288	uint64_t period;
    289	enum intel_pt_period_type period_type;
    290	unsigned max_non_turbo_ratio;
    291	unsigned int mtc_period;
    292	uint32_t tsc_ctc_ratio_n;
    293	uint32_t tsc_ctc_ratio_d;
    294	enum intel_pt_param_flags flags;
    295	unsigned int quick;
    296	int max_loops;
    297};
    298
    299struct intel_pt_decoder;
    300
    301struct intel_pt_decoder *intel_pt_decoder_new(struct intel_pt_params *params);
    302void intel_pt_decoder_free(struct intel_pt_decoder *decoder);
    303
    304const struct intel_pt_state *intel_pt_decode(struct intel_pt_decoder *decoder);
    305
    306int intel_pt_fast_forward(struct intel_pt_decoder *decoder, uint64_t timestamp);
    307
    308unsigned char *intel_pt_find_overlap(unsigned char *buf_a, size_t len_a,
    309				     unsigned char *buf_b, size_t len_b,
    310				     bool have_tsc, bool *consecutive,
    311				     bool ooo_tsc);
    312
    313int intel_pt__strerror(int code, char *buf, size_t buflen);
    314
    315void intel_pt_set_first_timestamp(struct intel_pt_decoder *decoder,
    316				  uint64_t first_timestamp);
    317
    318#endif