174fe6c29SRuslan Bukin/* 2*85f87cf4SRuslan Bukin * Copyright (c) 2013-2019, Intel Corporation 374fe6c29SRuslan Bukin * 474fe6c29SRuslan Bukin * Redistribution and use in source and binary forms, with or without 574fe6c29SRuslan Bukin * modification, are permitted provided that the following conditions are met: 674fe6c29SRuslan Bukin * 774fe6c29SRuslan Bukin * * Redistributions of source code must retain the above copyright notice, 874fe6c29SRuslan Bukin * this list of conditions and the following disclaimer. 974fe6c29SRuslan Bukin * * Redistributions in binary form must reproduce the above copyright notice, 1074fe6c29SRuslan Bukin * this list of conditions and the following disclaimer in the documentation 1174fe6c29SRuslan Bukin * and/or other materials provided with the distribution. 1274fe6c29SRuslan Bukin * * Neither the name of Intel Corporation nor the names of its contributors 1374fe6c29SRuslan Bukin * may be used to endorse or promote products derived from this software 1474fe6c29SRuslan Bukin * without specific prior written permission. 1574fe6c29SRuslan Bukin * 1674fe6c29SRuslan Bukin * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 1774fe6c29SRuslan Bukin * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1874fe6c29SRuslan Bukin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1974fe6c29SRuslan Bukin * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 2074fe6c29SRuslan Bukin * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2174fe6c29SRuslan Bukin * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2274fe6c29SRuslan Bukin * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2374fe6c29SRuslan Bukin * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2474fe6c29SRuslan Bukin * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2574fe6c29SRuslan Bukin * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2674fe6c29SRuslan Bukin * POSSIBILITY OF SUCH DAMAGE. 2774fe6c29SRuslan Bukin */ 2874fe6c29SRuslan Bukin 2974fe6c29SRuslan Bukin#ifndef INTEL_PT_H 3074fe6c29SRuslan Bukin#define INTEL_PT_H 3174fe6c29SRuslan Bukin 3274fe6c29SRuslan Bukin#include <stdint.h> 3374fe6c29SRuslan Bukin#include <string.h> 3474fe6c29SRuslan Bukin 3574fe6c29SRuslan Bukin#ifdef __cplusplus 3674fe6c29SRuslan Bukinextern "C" { 3774fe6c29SRuslan Bukin#endif 3874fe6c29SRuslan Bukin 3974fe6c29SRuslan Bukin 4074fe6c29SRuslan Bukin/* Intel(R) Processor Trace (Intel PT) decoder library. 4174fe6c29SRuslan Bukin * 4274fe6c29SRuslan Bukin * This file is logically structured into the following sections: 4374fe6c29SRuslan Bukin * 4474fe6c29SRuslan Bukin * - Version 4574fe6c29SRuslan Bukin * - Errors 4674fe6c29SRuslan Bukin * - Configuration 4774fe6c29SRuslan Bukin * - Packet encoder / decoder 4874fe6c29SRuslan Bukin * - Query decoder 4974fe6c29SRuslan Bukin * - Traced image 5074fe6c29SRuslan Bukin * - Instruction flow decoder 5174fe6c29SRuslan Bukin * - Block decoder 5274fe6c29SRuslan Bukin */ 5374fe6c29SRuslan Bukin 5474fe6c29SRuslan Bukin 5574fe6c29SRuslan Bukin 5674fe6c29SRuslan Bukinstruct pt_encoder; 5774fe6c29SRuslan Bukinstruct pt_packet_decoder; 5874fe6c29SRuslan Bukinstruct pt_query_decoder; 5974fe6c29SRuslan Bukinstruct pt_insn_decoder; 6074fe6c29SRuslan Bukinstruct pt_block_decoder; 6174fe6c29SRuslan Bukin 6274fe6c29SRuslan Bukin 6374fe6c29SRuslan Bukin 6474fe6c29SRuslan Bukin/* A macro to mark functions as exported. */ 6574fe6c29SRuslan Bukin#ifndef pt_export 6674fe6c29SRuslan Bukin# if defined(__GNUC__) 6774fe6c29SRuslan Bukin# define pt_export __attribute__((visibility("default"))) 6874fe6c29SRuslan Bukin# elif defined(_MSC_VER) 6974fe6c29SRuslan Bukin# define pt_export __declspec(dllimport) 7074fe6c29SRuslan Bukin# else 7174fe6c29SRuslan Bukin# error "unknown compiler" 7274fe6c29SRuslan Bukin# endif 7374fe6c29SRuslan Bukin#endif 7474fe6c29SRuslan Bukin 7574fe6c29SRuslan Bukin 7674fe6c29SRuslan Bukin 7774fe6c29SRuslan Bukin/* Version. */ 7874fe6c29SRuslan Bukin 7974fe6c29SRuslan Bukin 8074fe6c29SRuslan Bukin/** The header version. */ 8174fe6c29SRuslan Bukin#define LIBIPT_VERSION_MAJOR ${PT_VERSION_MAJOR} 8274fe6c29SRuslan Bukin#define LIBIPT_VERSION_MINOR ${PT_VERSION_MINOR} 83*85f87cf4SRuslan Bukin#define LIBIPT_VERSION_PATCH ${PT_VERSION_PATCH} 8474fe6c29SRuslan Bukin 8574fe6c29SRuslan Bukin#define LIBIPT_VERSION ((LIBIPT_VERSION_MAJOR << 8) + LIBIPT_VERSION_MINOR) 8674fe6c29SRuslan Bukin 8774fe6c29SRuslan Bukin 8874fe6c29SRuslan Bukin/** The library version. */ 8974fe6c29SRuslan Bukinstruct pt_version { 9074fe6c29SRuslan Bukin /** Major version number. */ 9174fe6c29SRuslan Bukin uint8_t major; 9274fe6c29SRuslan Bukin 9374fe6c29SRuslan Bukin /** Minor version number. */ 9474fe6c29SRuslan Bukin uint8_t minor; 9574fe6c29SRuslan Bukin 96*85f87cf4SRuslan Bukin /** Patch level. */ 97*85f87cf4SRuslan Bukin uint16_t patch; 9874fe6c29SRuslan Bukin 9974fe6c29SRuslan Bukin /** Build number. */ 10074fe6c29SRuslan Bukin uint32_t build; 10174fe6c29SRuslan Bukin 10274fe6c29SRuslan Bukin /** Version extension. */ 10374fe6c29SRuslan Bukin const char *ext; 10474fe6c29SRuslan Bukin}; 10574fe6c29SRuslan Bukin 10674fe6c29SRuslan Bukin 10774fe6c29SRuslan Bukin/** Return the library version. */ 10874fe6c29SRuslan Bukinextern pt_export struct pt_version pt_library_version(void); 10974fe6c29SRuslan Bukin 11074fe6c29SRuslan Bukin 11174fe6c29SRuslan Bukin 11274fe6c29SRuslan Bukin/* Errors. */ 11374fe6c29SRuslan Bukin 11474fe6c29SRuslan Bukin 11574fe6c29SRuslan Bukin 11674fe6c29SRuslan Bukin/** Error codes. */ 11774fe6c29SRuslan Bukinenum pt_error_code { 11874fe6c29SRuslan Bukin /* No error. Everything is OK. */ 11974fe6c29SRuslan Bukin pte_ok, 12074fe6c29SRuslan Bukin 12174fe6c29SRuslan Bukin /* Internal decoder error. */ 12274fe6c29SRuslan Bukin pte_internal, 12374fe6c29SRuslan Bukin 12474fe6c29SRuslan Bukin /* Invalid argument. */ 12574fe6c29SRuslan Bukin pte_invalid, 12674fe6c29SRuslan Bukin 12774fe6c29SRuslan Bukin /* Decoder out of sync. */ 12874fe6c29SRuslan Bukin pte_nosync, 12974fe6c29SRuslan Bukin 13074fe6c29SRuslan Bukin /* Unknown opcode. */ 13174fe6c29SRuslan Bukin pte_bad_opc, 13274fe6c29SRuslan Bukin 13374fe6c29SRuslan Bukin /* Unknown payload. */ 13474fe6c29SRuslan Bukin pte_bad_packet, 13574fe6c29SRuslan Bukin 13674fe6c29SRuslan Bukin /* Unexpected packet context. */ 13774fe6c29SRuslan Bukin pte_bad_context, 13874fe6c29SRuslan Bukin 13974fe6c29SRuslan Bukin /* Decoder reached end of trace stream. */ 14074fe6c29SRuslan Bukin pte_eos, 14174fe6c29SRuslan Bukin 14274fe6c29SRuslan Bukin /* No packet matching the query to be found. */ 14374fe6c29SRuslan Bukin pte_bad_query, 14474fe6c29SRuslan Bukin 14574fe6c29SRuslan Bukin /* Decoder out of memory. */ 14674fe6c29SRuslan Bukin pte_nomem, 14774fe6c29SRuslan Bukin 14874fe6c29SRuslan Bukin /* Bad configuration. */ 14974fe6c29SRuslan Bukin pte_bad_config, 15074fe6c29SRuslan Bukin 15174fe6c29SRuslan Bukin /* There is no IP. */ 15274fe6c29SRuslan Bukin pte_noip, 15374fe6c29SRuslan Bukin 15474fe6c29SRuslan Bukin /* The IP has been suppressed. */ 15574fe6c29SRuslan Bukin pte_ip_suppressed, 15674fe6c29SRuslan Bukin 15774fe6c29SRuslan Bukin /* There is no memory mapped at the requested address. */ 15874fe6c29SRuslan Bukin pte_nomap, 15974fe6c29SRuslan Bukin 16074fe6c29SRuslan Bukin /* An instruction could not be decoded. */ 16174fe6c29SRuslan Bukin pte_bad_insn, 16274fe6c29SRuslan Bukin 16374fe6c29SRuslan Bukin /* No wall-clock time is available. */ 16474fe6c29SRuslan Bukin pte_no_time, 16574fe6c29SRuslan Bukin 16674fe6c29SRuslan Bukin /* No core:bus ratio available. */ 16774fe6c29SRuslan Bukin pte_no_cbr, 16874fe6c29SRuslan Bukin 16974fe6c29SRuslan Bukin /* Bad traced image. */ 17074fe6c29SRuslan Bukin pte_bad_image, 17174fe6c29SRuslan Bukin 17274fe6c29SRuslan Bukin /* A locking error. */ 17374fe6c29SRuslan Bukin pte_bad_lock, 17474fe6c29SRuslan Bukin 17574fe6c29SRuslan Bukin /* The requested feature is not supported. */ 17674fe6c29SRuslan Bukin pte_not_supported, 17774fe6c29SRuslan Bukin 17874fe6c29SRuslan Bukin /* The return address stack is empty. */ 17974fe6c29SRuslan Bukin pte_retstack_empty, 18074fe6c29SRuslan Bukin 18174fe6c29SRuslan Bukin /* A compressed return is not indicated correctly by a taken branch. */ 18274fe6c29SRuslan Bukin pte_bad_retcomp, 18374fe6c29SRuslan Bukin 18474fe6c29SRuslan Bukin /* The current decoder state does not match the state in the trace. */ 18574fe6c29SRuslan Bukin pte_bad_status_update, 18674fe6c29SRuslan Bukin 18774fe6c29SRuslan Bukin /* The trace did not contain an expected enabled event. */ 18874fe6c29SRuslan Bukin pte_no_enable, 18974fe6c29SRuslan Bukin 19074fe6c29SRuslan Bukin /* An event was ignored. */ 19174fe6c29SRuslan Bukin pte_event_ignored, 19274fe6c29SRuslan Bukin 19374fe6c29SRuslan Bukin /* Something overflowed. */ 19474fe6c29SRuslan Bukin pte_overflow, 19574fe6c29SRuslan Bukin 19674fe6c29SRuslan Bukin /* A file handling error. */ 19774fe6c29SRuslan Bukin pte_bad_file, 19874fe6c29SRuslan Bukin 19974fe6c29SRuslan Bukin /* Unknown cpu. */ 20074fe6c29SRuslan Bukin pte_bad_cpu 20174fe6c29SRuslan Bukin}; 20274fe6c29SRuslan Bukin 20374fe6c29SRuslan Bukin 20474fe6c29SRuslan Bukin/** Decode a function return value into an pt_error_code. */ 20574fe6c29SRuslan Bukinstatic inline enum pt_error_code pt_errcode(int status) 20674fe6c29SRuslan Bukin{ 20774fe6c29SRuslan Bukin return (status >= 0) ? pte_ok : (enum pt_error_code) -status; 20874fe6c29SRuslan Bukin} 20974fe6c29SRuslan Bukin 21074fe6c29SRuslan Bukin/** Return a human readable error string. */ 21174fe6c29SRuslan Bukinextern pt_export const char *pt_errstr(enum pt_error_code); 21274fe6c29SRuslan Bukin 21374fe6c29SRuslan Bukin 21474fe6c29SRuslan Bukin 21574fe6c29SRuslan Bukin/* Configuration. */ 21674fe6c29SRuslan Bukin 21774fe6c29SRuslan Bukin 21874fe6c29SRuslan Bukin 21974fe6c29SRuslan Bukin/** A cpu vendor. */ 22074fe6c29SRuslan Bukinenum pt_cpu_vendor { 22174fe6c29SRuslan Bukin pcv_unknown, 22274fe6c29SRuslan Bukin pcv_intel 22374fe6c29SRuslan Bukin}; 22474fe6c29SRuslan Bukin 22574fe6c29SRuslan Bukin/** A cpu identifier. */ 22674fe6c29SRuslan Bukinstruct pt_cpu { 22774fe6c29SRuslan Bukin /** The cpu vendor. */ 22874fe6c29SRuslan Bukin enum pt_cpu_vendor vendor; 22974fe6c29SRuslan Bukin 23074fe6c29SRuslan Bukin /** The cpu family. */ 23174fe6c29SRuslan Bukin uint16_t family; 23274fe6c29SRuslan Bukin 23374fe6c29SRuslan Bukin /** The cpu model. */ 23474fe6c29SRuslan Bukin uint8_t model; 23574fe6c29SRuslan Bukin 23674fe6c29SRuslan Bukin /** The stepping. */ 23774fe6c29SRuslan Bukin uint8_t stepping; 23874fe6c29SRuslan Bukin}; 23974fe6c29SRuslan Bukin 24074fe6c29SRuslan Bukin/** A collection of Intel PT errata. */ 24174fe6c29SRuslan Bukinstruct pt_errata { 24274fe6c29SRuslan Bukin /** BDM70: Intel(R) Processor Trace PSB+ Packets May Contain 24374fe6c29SRuslan Bukin * Unexpected Packets. 24474fe6c29SRuslan Bukin * 24574fe6c29SRuslan Bukin * Same as: SKD024, SKL021, KBL021. 24674fe6c29SRuslan Bukin * 24774fe6c29SRuslan Bukin * Some Intel Processor Trace packets should be issued only between 24874fe6c29SRuslan Bukin * TIP.PGE and TIP.PGD packets. Due to this erratum, when a TIP.PGE 24974fe6c29SRuslan Bukin * packet is generated it may be preceded by a PSB+ that incorrectly 25074fe6c29SRuslan Bukin * includes FUP and MODE.Exec packets. 25174fe6c29SRuslan Bukin */ 25274fe6c29SRuslan Bukin uint32_t bdm70:1; 25374fe6c29SRuslan Bukin 25474fe6c29SRuslan Bukin /** BDM64: An Incorrect LBR or Intel(R) Processor Trace Packet May Be 25574fe6c29SRuslan Bukin * Recorded Following a Transactional Abort. 25674fe6c29SRuslan Bukin * 25774fe6c29SRuslan Bukin * Use of Intel(R) Transactional Synchronization Extensions (Intel(R) 25874fe6c29SRuslan Bukin * TSX) may result in a transactional abort. If an abort occurs 25974fe6c29SRuslan Bukin * immediately following a branch instruction, an incorrect branch 26074fe6c29SRuslan Bukin * target may be logged in an LBR (Last Branch Record) or in an Intel(R) 26174fe6c29SRuslan Bukin * Processor Trace (Intel(R) PT) packet before the LBR or Intel PT 26274fe6c29SRuslan Bukin * packet produced by the abort. 26374fe6c29SRuslan Bukin */ 26474fe6c29SRuslan Bukin uint32_t bdm64:1; 26574fe6c29SRuslan Bukin 26674fe6c29SRuslan Bukin /** SKD007: Intel(R) PT Buffer Overflow May Result in Incorrect Packets. 26774fe6c29SRuslan Bukin * 26874fe6c29SRuslan Bukin * Same as: SKL049, KBL041. 26974fe6c29SRuslan Bukin * 27074fe6c29SRuslan Bukin * Under complex micro-architectural conditions, an Intel PT (Processor 27174fe6c29SRuslan Bukin * Trace) OVF (Overflow) packet may be issued after the first byte of a 27274fe6c29SRuslan Bukin * multi-byte CYC (Cycle Count) packet, instead of any remaining bytes 27374fe6c29SRuslan Bukin * of the CYC. 27474fe6c29SRuslan Bukin */ 27574fe6c29SRuslan Bukin uint32_t skd007:1; 27674fe6c29SRuslan Bukin 27774fe6c29SRuslan Bukin /** SKD022: VM Entry That Clears TraceEn May Generate a FUP. 27874fe6c29SRuslan Bukin * 27974fe6c29SRuslan Bukin * Same as: SKL024, KBL023. 28074fe6c29SRuslan Bukin * 28174fe6c29SRuslan Bukin * If VM entry clears Intel(R) PT (Intel Processor Trace) 28274fe6c29SRuslan Bukin * IA32_RTIT_CTL.TraceEn (MSR 570H, bit 0) while PacketEn is 1 then a 28374fe6c29SRuslan Bukin * FUP (Flow Update Packet) will precede the TIP.PGD (Target IP Packet, 28474fe6c29SRuslan Bukin * Packet Generation Disable). VM entry can clear TraceEn if the 28574fe6c29SRuslan Bukin * VM-entry MSR-load area includes an entry for the IA32_RTIT_CTL MSR. 28674fe6c29SRuslan Bukin */ 28774fe6c29SRuslan Bukin uint32_t skd022:1; 28874fe6c29SRuslan Bukin 28974fe6c29SRuslan Bukin /** SKD010: Intel(R) PT FUP May be Dropped After OVF. 29074fe6c29SRuslan Bukin * 29174fe6c29SRuslan Bukin * Same as: SKD014, SKL033, KBL030. 29274fe6c29SRuslan Bukin * 29374fe6c29SRuslan Bukin * Some Intel PT (Intel Processor Trace) OVF (Overflow) packets may not 29474fe6c29SRuslan Bukin * be followed by a FUP (Flow Update Packet) or TIP.PGE (Target IP 29574fe6c29SRuslan Bukin * Packet, Packet Generation Enable). 29674fe6c29SRuslan Bukin */ 29774fe6c29SRuslan Bukin uint32_t skd010:1; 29874fe6c29SRuslan Bukin 29974fe6c29SRuslan Bukin /** SKL014: Intel(R) PT TIP.PGD May Not Have Target IP Payload. 30074fe6c29SRuslan Bukin * 30174fe6c29SRuslan Bukin * Same as: KBL014. 30274fe6c29SRuslan Bukin * 30374fe6c29SRuslan Bukin * When Intel PT (Intel Processor Trace) is enabled and a direct 30474fe6c29SRuslan Bukin * unconditional branch clears IA32_RTIT_STATUS.FilterEn (MSR 571H, bit 30574fe6c29SRuslan Bukin * 0), due to this erratum, the resulting TIP.PGD (Target IP Packet, 30674fe6c29SRuslan Bukin * Packet Generation Disable) may not have an IP payload with the target 30774fe6c29SRuslan Bukin * IP. 30874fe6c29SRuslan Bukin */ 30974fe6c29SRuslan Bukin uint32_t skl014:1; 31074fe6c29SRuslan Bukin 31174fe6c29SRuslan Bukin /** APL12: Intel(R) PT OVF May Be Followed By An Unexpected FUP Packet. 31274fe6c29SRuslan Bukin * 31374fe6c29SRuslan Bukin * Certain Intel PT (Processor Trace) packets including FUPs (Flow 31474fe6c29SRuslan Bukin * Update Packets), should be issued only between TIP.PGE (Target IP 31574fe6c29SRuslan Bukin * Packet - Packet Generaton Enable) and TIP.PGD (Target IP Packet - 31674fe6c29SRuslan Bukin * Packet Generation Disable) packets. When outside a TIP.PGE/TIP.PGD 31774fe6c29SRuslan Bukin * pair, as a result of IA32_RTIT_STATUS.FilterEn[0] (MSR 571H) being 31874fe6c29SRuslan Bukin * cleared, an OVF (Overflow) packet may be unexpectedly followed by a 31974fe6c29SRuslan Bukin * FUP. 32074fe6c29SRuslan Bukin */ 32174fe6c29SRuslan Bukin uint32_t apl12:1; 32274fe6c29SRuslan Bukin 32374fe6c29SRuslan Bukin /** APL11: Intel(R) PT OVF Pakcet May Be Followed by TIP.PGD Packet 32474fe6c29SRuslan Bukin * 32574fe6c29SRuslan Bukin * If Intel PT (Processor Trace) encounters an internal buffer overflow 32674fe6c29SRuslan Bukin * and generates an OVF (Overflow) packet just as IA32_RTIT_CTL (MSR 32774fe6c29SRuslan Bukin * 570H) bit 0 (TraceEn) is cleared, or during a far transfer that 32874fe6c29SRuslan Bukin * causes IA32_RTIT_STATUS.ContextEn[1] (MSR 571H) to be cleared, the 32974fe6c29SRuslan Bukin * OVF may be followed by a TIP.PGD (Target Instruction Pointer - Packet 33074fe6c29SRuslan Bukin * Generation Disable) packet. 33174fe6c29SRuslan Bukin */ 33274fe6c29SRuslan Bukin uint32_t apl11:1; 33374fe6c29SRuslan Bukin 334*85f87cf4SRuslan Bukin /** SKL168: Intel(R) PT CYC Packets Can be Dropped When Immediately 335*85f87cf4SRuslan Bukin * Preceding PSB 336*85f87cf4SRuslan Bukin * 337*85f87cf4SRuslan Bukin * Due to a rare microarchitectural condition, generation of an Intel 338*85f87cf4SRuslan Bukin * PT (Processor Trace) PSB (Packet Stream Boundary) packet can cause a 339*85f87cf4SRuslan Bukin * single CYC (Cycle Count) packet, possibly along with an associated 340*85f87cf4SRuslan Bukin * MTC (Mini Time Counter) packet, to be dropped. 341*85f87cf4SRuslan Bukin */ 342*85f87cf4SRuslan Bukin uint32_t skl168:1; 343*85f87cf4SRuslan Bukin 34474fe6c29SRuslan Bukin /* Reserve a few bytes for the future. */ 34574fe6c29SRuslan Bukin uint32_t reserved[15]; 34674fe6c29SRuslan Bukin}; 34774fe6c29SRuslan Bukin 34874fe6c29SRuslan Bukin/** A collection of decoder-specific configuration flags. */ 34974fe6c29SRuslan Bukinstruct pt_conf_flags { 35074fe6c29SRuslan Bukin /** The decoder variant. */ 35174fe6c29SRuslan Bukin union { 35274fe6c29SRuslan Bukin /** Flags for the block decoder. */ 35374fe6c29SRuslan Bukin struct { 35474fe6c29SRuslan Bukin /** End a block after a call instruction. */ 35574fe6c29SRuslan Bukin uint32_t end_on_call:1; 35674fe6c29SRuslan Bukin 35774fe6c29SRuslan Bukin /** Enable tick events for timing updates. */ 35874fe6c29SRuslan Bukin uint32_t enable_tick_events:1; 35974fe6c29SRuslan Bukin 36074fe6c29SRuslan Bukin /** End a block after a jump instruction. */ 36174fe6c29SRuslan Bukin uint32_t end_on_jump:1; 362*85f87cf4SRuslan Bukin 363*85f87cf4SRuslan Bukin /** Preserve timing calibration on overflow. */ 364*85f87cf4SRuslan Bukin uint32_t keep_tcal_on_ovf:1; 36574fe6c29SRuslan Bukin } block; 36674fe6c29SRuslan Bukin 36774fe6c29SRuslan Bukin /** Flags for the instruction flow decoder. */ 36874fe6c29SRuslan Bukin struct { 36974fe6c29SRuslan Bukin /** Enable tick events for timing updates. */ 37074fe6c29SRuslan Bukin uint32_t enable_tick_events:1; 371*85f87cf4SRuslan Bukin 372*85f87cf4SRuslan Bukin /** Preserve timing calibration on overflow. */ 373*85f87cf4SRuslan Bukin uint32_t keep_tcal_on_ovf:1; 37474fe6c29SRuslan Bukin } insn; 37574fe6c29SRuslan Bukin 376*85f87cf4SRuslan Bukin /** Flags for the query decoder. */ 377*85f87cf4SRuslan Bukin struct { 378*85f87cf4SRuslan Bukin /** Preserve timing calibration on overflow. */ 379*85f87cf4SRuslan Bukin uint32_t keep_tcal_on_ovf:1; 380*85f87cf4SRuslan Bukin } query; 381*85f87cf4SRuslan Bukin 38274fe6c29SRuslan Bukin /* Reserve a few bytes for future extensions. */ 38374fe6c29SRuslan Bukin uint32_t reserved[4]; 38474fe6c29SRuslan Bukin } variant; 38574fe6c29SRuslan Bukin}; 38674fe6c29SRuslan Bukin 38774fe6c29SRuslan Bukin/** The address filter configuration. */ 38874fe6c29SRuslan Bukinstruct pt_conf_addr_filter { 38974fe6c29SRuslan Bukin /** The address filter configuration. 39074fe6c29SRuslan Bukin * 39174fe6c29SRuslan Bukin * This corresponds to the respective fields in IA32_RTIT_CTL MSR. 39274fe6c29SRuslan Bukin */ 39374fe6c29SRuslan Bukin union { 39474fe6c29SRuslan Bukin uint64_t addr_cfg; 39574fe6c29SRuslan Bukin 39674fe6c29SRuslan Bukin struct { 39774fe6c29SRuslan Bukin uint32_t addr0_cfg:4; 39874fe6c29SRuslan Bukin uint32_t addr1_cfg:4; 39974fe6c29SRuslan Bukin uint32_t addr2_cfg:4; 40074fe6c29SRuslan Bukin uint32_t addr3_cfg:4; 40174fe6c29SRuslan Bukin } ctl; 40274fe6c29SRuslan Bukin } config; 40374fe6c29SRuslan Bukin 40474fe6c29SRuslan Bukin /** The address ranges configuration. 40574fe6c29SRuslan Bukin * 40674fe6c29SRuslan Bukin * This corresponds to the IA32_RTIT_ADDRn_A/B MSRs. 40774fe6c29SRuslan Bukin */ 40874fe6c29SRuslan Bukin uint64_t addr0_a; 40974fe6c29SRuslan Bukin uint64_t addr0_b; 41074fe6c29SRuslan Bukin uint64_t addr1_a; 41174fe6c29SRuslan Bukin uint64_t addr1_b; 41274fe6c29SRuslan Bukin uint64_t addr2_a; 41374fe6c29SRuslan Bukin uint64_t addr2_b; 41474fe6c29SRuslan Bukin uint64_t addr3_a; 41574fe6c29SRuslan Bukin uint64_t addr3_b; 41674fe6c29SRuslan Bukin 41774fe6c29SRuslan Bukin /* Reserve some space. */ 41874fe6c29SRuslan Bukin uint64_t reserved[8]; 41974fe6c29SRuslan Bukin}; 42074fe6c29SRuslan Bukin 42174fe6c29SRuslan Bukin/** An unknown packet. */ 42274fe6c29SRuslan Bukinstruct pt_packet_unknown; 42374fe6c29SRuslan Bukin 42474fe6c29SRuslan Bukin/** An Intel PT decoder configuration. 42574fe6c29SRuslan Bukin */ 42674fe6c29SRuslan Bukinstruct pt_config { 42774fe6c29SRuslan Bukin /** The size of the config structure in bytes. */ 42874fe6c29SRuslan Bukin size_t size; 42974fe6c29SRuslan Bukin 43074fe6c29SRuslan Bukin /** The trace buffer begin address. */ 43174fe6c29SRuslan Bukin uint8_t *begin; 43274fe6c29SRuslan Bukin 43374fe6c29SRuslan Bukin /** The trace buffer end address. */ 43474fe6c29SRuslan Bukin uint8_t *end; 43574fe6c29SRuslan Bukin 43674fe6c29SRuslan Bukin /** An optional callback for handling unknown packets. 43774fe6c29SRuslan Bukin * 43874fe6c29SRuslan Bukin * If \@callback is not NULL, it is called for any unknown opcode. 43974fe6c29SRuslan Bukin */ 44074fe6c29SRuslan Bukin struct { 44174fe6c29SRuslan Bukin /** The callback function. 44274fe6c29SRuslan Bukin * 44374fe6c29SRuslan Bukin * It shall decode the packet at \@pos into \@unknown. 44474fe6c29SRuslan Bukin * It shall return the number of bytes read upon success. 44574fe6c29SRuslan Bukin * It shall return a negative pt_error_code otherwise. 44674fe6c29SRuslan Bukin * The below context is passed as \@context. 44774fe6c29SRuslan Bukin */ 44874fe6c29SRuslan Bukin int (*callback)(struct pt_packet_unknown *unknown, 44974fe6c29SRuslan Bukin const struct pt_config *config, 45074fe6c29SRuslan Bukin const uint8_t *pos, void *context); 45174fe6c29SRuslan Bukin 45274fe6c29SRuslan Bukin /** The user-defined context for this configuration. */ 45374fe6c29SRuslan Bukin void *context; 45474fe6c29SRuslan Bukin } decode; 45574fe6c29SRuslan Bukin 45674fe6c29SRuslan Bukin /** The cpu on which Intel PT has been recorded. */ 45774fe6c29SRuslan Bukin struct pt_cpu cpu; 45874fe6c29SRuslan Bukin 45974fe6c29SRuslan Bukin /** The errata to apply when encoding or decoding Intel PT. */ 46074fe6c29SRuslan Bukin struct pt_errata errata; 46174fe6c29SRuslan Bukin 46274fe6c29SRuslan Bukin /* The CTC frequency. 46374fe6c29SRuslan Bukin * 46474fe6c29SRuslan Bukin * This is only required if MTC packets have been enabled in 46574fe6c29SRuslan Bukin * IA32_RTIT_CTRL.MTCEn. 46674fe6c29SRuslan Bukin */ 46774fe6c29SRuslan Bukin uint32_t cpuid_0x15_eax, cpuid_0x15_ebx; 46874fe6c29SRuslan Bukin 46974fe6c29SRuslan Bukin /* The MTC frequency as defined in IA32_RTIT_CTL.MTCFreq. 47074fe6c29SRuslan Bukin * 47174fe6c29SRuslan Bukin * This is only required if MTC packets have been enabled in 47274fe6c29SRuslan Bukin * IA32_RTIT_CTRL.MTCEn. 47374fe6c29SRuslan Bukin */ 47474fe6c29SRuslan Bukin uint8_t mtc_freq; 47574fe6c29SRuslan Bukin 47674fe6c29SRuslan Bukin /* The nominal frequency as defined in MSR_PLATFORM_INFO[15:8]. 47774fe6c29SRuslan Bukin * 47874fe6c29SRuslan Bukin * This is only required if CYC packets have been enabled in 47974fe6c29SRuslan Bukin * IA32_RTIT_CTRL.CYCEn. 48074fe6c29SRuslan Bukin * 48174fe6c29SRuslan Bukin * If zero, timing calibration will only be able to use MTC and CYC 48274fe6c29SRuslan Bukin * packets. 48374fe6c29SRuslan Bukin * 48474fe6c29SRuslan Bukin * If not zero, timing calibration will also be able to use CBR 48574fe6c29SRuslan Bukin * packets. 48674fe6c29SRuslan Bukin */ 48774fe6c29SRuslan Bukin uint8_t nom_freq; 48874fe6c29SRuslan Bukin 48974fe6c29SRuslan Bukin /** A collection of decoder-specific flags. */ 49074fe6c29SRuslan Bukin struct pt_conf_flags flags; 49174fe6c29SRuslan Bukin 49274fe6c29SRuslan Bukin /** The address filter configuration. */ 49374fe6c29SRuslan Bukin struct pt_conf_addr_filter addr_filter; 49474fe6c29SRuslan Bukin}; 49574fe6c29SRuslan Bukin 49674fe6c29SRuslan Bukin 49774fe6c29SRuslan Bukin/** Zero-initialize an Intel PT configuration. */ 49874fe6c29SRuslan Bukinstatic inline void pt_config_init(struct pt_config *config) 49974fe6c29SRuslan Bukin{ 50074fe6c29SRuslan Bukin memset(config, 0, sizeof(*config)); 50174fe6c29SRuslan Bukin 50274fe6c29SRuslan Bukin config->size = sizeof(*config); 50374fe6c29SRuslan Bukin} 50474fe6c29SRuslan Bukin 50574fe6c29SRuslan Bukin/** Determine errata for a given cpu. 50674fe6c29SRuslan Bukin * 50774fe6c29SRuslan Bukin * Updates \@errata based on \@cpu. 50874fe6c29SRuslan Bukin * 50974fe6c29SRuslan Bukin * Returns 0 on success, a negative error code otherwise. 51074fe6c29SRuslan Bukin * Returns -pte_invalid if \@errata or \@cpu is NULL. 51174fe6c29SRuslan Bukin * Returns -pte_bad_cpu if \@cpu is not known. 51274fe6c29SRuslan Bukin */ 51374fe6c29SRuslan Bukinextern pt_export int pt_cpu_errata(struct pt_errata *errata, 51474fe6c29SRuslan Bukin const struct pt_cpu *cpu); 51574fe6c29SRuslan Bukin 51674fe6c29SRuslan Bukin 51774fe6c29SRuslan Bukin 51874fe6c29SRuslan Bukin/* Packet encoder / decoder. */ 51974fe6c29SRuslan Bukin 52074fe6c29SRuslan Bukin 52174fe6c29SRuslan Bukin 52274fe6c29SRuslan Bukin/** Intel PT packet types. */ 52374fe6c29SRuslan Bukinenum pt_packet_type { 52474fe6c29SRuslan Bukin /* An invalid packet. */ 52574fe6c29SRuslan Bukin ppt_invalid, 52674fe6c29SRuslan Bukin 52774fe6c29SRuslan Bukin /* A packet decodable by the optional decoder callback. */ 52874fe6c29SRuslan Bukin ppt_unknown, 52974fe6c29SRuslan Bukin 53074fe6c29SRuslan Bukin /* Actual packets supported by this library. */ 53174fe6c29SRuslan Bukin ppt_pad, 53274fe6c29SRuslan Bukin ppt_psb, 53374fe6c29SRuslan Bukin ppt_psbend, 53474fe6c29SRuslan Bukin ppt_fup, 53574fe6c29SRuslan Bukin ppt_tip, 53674fe6c29SRuslan Bukin ppt_tip_pge, 53774fe6c29SRuslan Bukin ppt_tip_pgd, 53874fe6c29SRuslan Bukin ppt_tnt_8, 53974fe6c29SRuslan Bukin ppt_tnt_64, 54074fe6c29SRuslan Bukin ppt_mode, 54174fe6c29SRuslan Bukin ppt_pip, 54274fe6c29SRuslan Bukin ppt_vmcs, 54374fe6c29SRuslan Bukin ppt_cbr, 54474fe6c29SRuslan Bukin ppt_tsc, 54574fe6c29SRuslan Bukin ppt_tma, 54674fe6c29SRuslan Bukin ppt_mtc, 54774fe6c29SRuslan Bukin ppt_cyc, 54874fe6c29SRuslan Bukin ppt_stop, 54974fe6c29SRuslan Bukin ppt_ovf, 55074fe6c29SRuslan Bukin ppt_mnt, 55174fe6c29SRuslan Bukin ppt_exstop, 55274fe6c29SRuslan Bukin ppt_mwait, 55374fe6c29SRuslan Bukin ppt_pwre, 55474fe6c29SRuslan Bukin ppt_pwrx, 55574fe6c29SRuslan Bukin ppt_ptw 55674fe6c29SRuslan Bukin}; 55774fe6c29SRuslan Bukin 55874fe6c29SRuslan Bukin/** The IP compression. */ 55974fe6c29SRuslan Bukinenum pt_ip_compression { 56074fe6c29SRuslan Bukin /* The bits encode the payload size and the encoding scheme. 56174fe6c29SRuslan Bukin * 56274fe6c29SRuslan Bukin * No payload. The IP has been suppressed. 56374fe6c29SRuslan Bukin */ 56474fe6c29SRuslan Bukin pt_ipc_suppressed = 0x0, 56574fe6c29SRuslan Bukin 56674fe6c29SRuslan Bukin /* Payload: 16 bits. Update last IP. */ 56774fe6c29SRuslan Bukin pt_ipc_update_16 = 0x01, 56874fe6c29SRuslan Bukin 56974fe6c29SRuslan Bukin /* Payload: 32 bits. Update last IP. */ 57074fe6c29SRuslan Bukin pt_ipc_update_32 = 0x02, 57174fe6c29SRuslan Bukin 57274fe6c29SRuslan Bukin /* Payload: 48 bits. Sign extend to full address. */ 57374fe6c29SRuslan Bukin pt_ipc_sext_48 = 0x03, 57474fe6c29SRuslan Bukin 57574fe6c29SRuslan Bukin /* Payload: 48 bits. Update last IP. */ 57674fe6c29SRuslan Bukin pt_ipc_update_48 = 0x04, 57774fe6c29SRuslan Bukin 57874fe6c29SRuslan Bukin /* Payload: 64 bits. Full address. */ 57974fe6c29SRuslan Bukin pt_ipc_full = 0x06 58074fe6c29SRuslan Bukin}; 58174fe6c29SRuslan Bukin 58274fe6c29SRuslan Bukin/** An execution mode. */ 58374fe6c29SRuslan Bukinenum pt_exec_mode { 58474fe6c29SRuslan Bukin ptem_unknown, 58574fe6c29SRuslan Bukin ptem_16bit, 58674fe6c29SRuslan Bukin ptem_32bit, 58774fe6c29SRuslan Bukin ptem_64bit 58874fe6c29SRuslan Bukin}; 58974fe6c29SRuslan Bukin 59074fe6c29SRuslan Bukin/** Mode packet leaves. */ 59174fe6c29SRuslan Bukinenum pt_mode_leaf { 59274fe6c29SRuslan Bukin pt_mol_exec = 0x00, 59374fe6c29SRuslan Bukin pt_mol_tsx = 0x20 59474fe6c29SRuslan Bukin}; 59574fe6c29SRuslan Bukin 59674fe6c29SRuslan Bukin/** A TNT-8 or TNT-64 packet. */ 59774fe6c29SRuslan Bukinstruct pt_packet_tnt { 59874fe6c29SRuslan Bukin /** TNT payload bit size. */ 59974fe6c29SRuslan Bukin uint8_t bit_size; 60074fe6c29SRuslan Bukin 60174fe6c29SRuslan Bukin /** TNT payload excluding stop bit. */ 60274fe6c29SRuslan Bukin uint64_t payload; 60374fe6c29SRuslan Bukin}; 60474fe6c29SRuslan Bukin 60574fe6c29SRuslan Bukin/** A packet with IP payload. */ 60674fe6c29SRuslan Bukinstruct pt_packet_ip { 60774fe6c29SRuslan Bukin /** IP compression. */ 60874fe6c29SRuslan Bukin enum pt_ip_compression ipc; 60974fe6c29SRuslan Bukin 61074fe6c29SRuslan Bukin /** Zero-extended payload ip. */ 61174fe6c29SRuslan Bukin uint64_t ip; 61274fe6c29SRuslan Bukin}; 61374fe6c29SRuslan Bukin 61474fe6c29SRuslan Bukin/** A mode.exec packet. */ 61574fe6c29SRuslan Bukinstruct pt_packet_mode_exec { 61674fe6c29SRuslan Bukin /** The mode.exec csl bit. */ 61774fe6c29SRuslan Bukin uint32_t csl:1; 61874fe6c29SRuslan Bukin 61974fe6c29SRuslan Bukin /** The mode.exec csd bit. */ 62074fe6c29SRuslan Bukin uint32_t csd:1; 62174fe6c29SRuslan Bukin}; 62274fe6c29SRuslan Bukin 62374fe6c29SRuslan Bukinstatic inline enum pt_exec_mode 62474fe6c29SRuslan Bukinpt_get_exec_mode(const struct pt_packet_mode_exec *packet) 62574fe6c29SRuslan Bukin{ 62674fe6c29SRuslan Bukin if (packet->csl) 62774fe6c29SRuslan Bukin return packet->csd ? ptem_unknown : ptem_64bit; 62874fe6c29SRuslan Bukin else 62974fe6c29SRuslan Bukin return packet->csd ? ptem_32bit : ptem_16bit; 63074fe6c29SRuslan Bukin} 63174fe6c29SRuslan Bukin 63274fe6c29SRuslan Bukinstatic inline struct pt_packet_mode_exec 63374fe6c29SRuslan Bukinpt_set_exec_mode(enum pt_exec_mode mode) 63474fe6c29SRuslan Bukin{ 63574fe6c29SRuslan Bukin struct pt_packet_mode_exec packet; 63674fe6c29SRuslan Bukin 63774fe6c29SRuslan Bukin switch (mode) { 63874fe6c29SRuslan Bukin default: 63974fe6c29SRuslan Bukin packet.csl = 1; 64074fe6c29SRuslan Bukin packet.csd = 1; 64174fe6c29SRuslan Bukin break; 64274fe6c29SRuslan Bukin 64374fe6c29SRuslan Bukin case ptem_64bit: 64474fe6c29SRuslan Bukin packet.csl = 1; 64574fe6c29SRuslan Bukin packet.csd = 0; 64674fe6c29SRuslan Bukin break; 64774fe6c29SRuslan Bukin 64874fe6c29SRuslan Bukin case ptem_32bit: 64974fe6c29SRuslan Bukin packet.csl = 0; 65074fe6c29SRuslan Bukin packet.csd = 1; 65174fe6c29SRuslan Bukin break; 65274fe6c29SRuslan Bukin 65374fe6c29SRuslan Bukin case ptem_16bit: 65474fe6c29SRuslan Bukin packet.csl = 0; 65574fe6c29SRuslan Bukin packet.csd = 0; 65674fe6c29SRuslan Bukin break; 65774fe6c29SRuslan Bukin } 65874fe6c29SRuslan Bukin 65974fe6c29SRuslan Bukin return packet; 66074fe6c29SRuslan Bukin} 66174fe6c29SRuslan Bukin 66274fe6c29SRuslan Bukin/** A mode.tsx packet. */ 66374fe6c29SRuslan Bukinstruct pt_packet_mode_tsx { 66474fe6c29SRuslan Bukin /** The mode.tsx intx bit. */ 66574fe6c29SRuslan Bukin uint32_t intx:1; 66674fe6c29SRuslan Bukin 66774fe6c29SRuslan Bukin /** The mode.tsx abrt bit. */ 66874fe6c29SRuslan Bukin uint32_t abrt:1; 66974fe6c29SRuslan Bukin}; 67074fe6c29SRuslan Bukin 67174fe6c29SRuslan Bukin/** A mode packet. */ 67274fe6c29SRuslan Bukinstruct pt_packet_mode { 67374fe6c29SRuslan Bukin /** Mode leaf. */ 67474fe6c29SRuslan Bukin enum pt_mode_leaf leaf; 67574fe6c29SRuslan Bukin 67674fe6c29SRuslan Bukin /** Mode bits. */ 67774fe6c29SRuslan Bukin union { 67874fe6c29SRuslan Bukin /** Packet: mode.exec. */ 67974fe6c29SRuslan Bukin struct pt_packet_mode_exec exec; 68074fe6c29SRuslan Bukin 68174fe6c29SRuslan Bukin /** Packet: mode.tsx. */ 68274fe6c29SRuslan Bukin struct pt_packet_mode_tsx tsx; 68374fe6c29SRuslan Bukin } bits; 68474fe6c29SRuslan Bukin}; 68574fe6c29SRuslan Bukin 68674fe6c29SRuslan Bukin/** A PIP packet. */ 68774fe6c29SRuslan Bukinstruct pt_packet_pip { 68874fe6c29SRuslan Bukin /** The CR3 value. */ 68974fe6c29SRuslan Bukin uint64_t cr3; 69074fe6c29SRuslan Bukin 69174fe6c29SRuslan Bukin /** The non-root bit. */ 69274fe6c29SRuslan Bukin uint32_t nr:1; 69374fe6c29SRuslan Bukin}; 69474fe6c29SRuslan Bukin 69574fe6c29SRuslan Bukin/** A TSC packet. */ 69674fe6c29SRuslan Bukinstruct pt_packet_tsc { 69774fe6c29SRuslan Bukin /** The TSC value. */ 69874fe6c29SRuslan Bukin uint64_t tsc; 69974fe6c29SRuslan Bukin}; 70074fe6c29SRuslan Bukin 70174fe6c29SRuslan Bukin/** A CBR packet. */ 70274fe6c29SRuslan Bukinstruct pt_packet_cbr { 70374fe6c29SRuslan Bukin /** The core/bus cycle ratio. */ 70474fe6c29SRuslan Bukin uint8_t ratio; 70574fe6c29SRuslan Bukin}; 70674fe6c29SRuslan Bukin 70774fe6c29SRuslan Bukin/** A TMA packet. */ 70874fe6c29SRuslan Bukinstruct pt_packet_tma { 70974fe6c29SRuslan Bukin /** The crystal clock tick counter value. */ 71074fe6c29SRuslan Bukin uint16_t ctc; 71174fe6c29SRuslan Bukin 71274fe6c29SRuslan Bukin /** The fast counter value. */ 71374fe6c29SRuslan Bukin uint16_t fc; 71474fe6c29SRuslan Bukin}; 71574fe6c29SRuslan Bukin 71674fe6c29SRuslan Bukin/** A MTC packet. */ 71774fe6c29SRuslan Bukinstruct pt_packet_mtc { 71874fe6c29SRuslan Bukin /** The crystal clock tick counter value. */ 71974fe6c29SRuslan Bukin uint8_t ctc; 72074fe6c29SRuslan Bukin}; 72174fe6c29SRuslan Bukin 72274fe6c29SRuslan Bukin/** A CYC packet. */ 72374fe6c29SRuslan Bukinstruct pt_packet_cyc { 72474fe6c29SRuslan Bukin /** The cycle counter value. */ 72574fe6c29SRuslan Bukin uint64_t value; 72674fe6c29SRuslan Bukin}; 72774fe6c29SRuslan Bukin 72874fe6c29SRuslan Bukin/** A VMCS packet. */ 72974fe6c29SRuslan Bukinstruct pt_packet_vmcs { 73074fe6c29SRuslan Bukin /* The VMCS Base Address (i.e. the shifted payload). */ 73174fe6c29SRuslan Bukin uint64_t base; 73274fe6c29SRuslan Bukin}; 73374fe6c29SRuslan Bukin 73474fe6c29SRuslan Bukin/** A MNT packet. */ 73574fe6c29SRuslan Bukinstruct pt_packet_mnt { 73674fe6c29SRuslan Bukin /** The raw payload. */ 73774fe6c29SRuslan Bukin uint64_t payload; 73874fe6c29SRuslan Bukin}; 73974fe6c29SRuslan Bukin 74074fe6c29SRuslan Bukin/** A EXSTOP packet. */ 74174fe6c29SRuslan Bukinstruct pt_packet_exstop { 74274fe6c29SRuslan Bukin /** A flag specifying the binding of the packet: 74374fe6c29SRuslan Bukin * 74474fe6c29SRuslan Bukin * set: binds to the next FUP. 74574fe6c29SRuslan Bukin * clear: standalone. 74674fe6c29SRuslan Bukin */ 74774fe6c29SRuslan Bukin uint32_t ip:1; 74874fe6c29SRuslan Bukin}; 74974fe6c29SRuslan Bukin 75074fe6c29SRuslan Bukin/** A MWAIT packet. */ 75174fe6c29SRuslan Bukinstruct pt_packet_mwait { 75274fe6c29SRuslan Bukin /** The MWAIT hints (EAX). */ 75374fe6c29SRuslan Bukin uint32_t hints; 75474fe6c29SRuslan Bukin 75574fe6c29SRuslan Bukin /** The MWAIT extensions (ECX). */ 75674fe6c29SRuslan Bukin uint32_t ext; 75774fe6c29SRuslan Bukin}; 75874fe6c29SRuslan Bukin 75974fe6c29SRuslan Bukin/** A PWRE packet. */ 76074fe6c29SRuslan Bukinstruct pt_packet_pwre { 76174fe6c29SRuslan Bukin /** The resolved thread C-state. */ 76274fe6c29SRuslan Bukin uint8_t state; 76374fe6c29SRuslan Bukin 76474fe6c29SRuslan Bukin /** The resolved thread sub C-state. */ 76574fe6c29SRuslan Bukin uint8_t sub_state; 76674fe6c29SRuslan Bukin 76774fe6c29SRuslan Bukin /** A flag indicating whether the C-state entry was initiated by h/w. */ 76874fe6c29SRuslan Bukin uint32_t hw:1; 76974fe6c29SRuslan Bukin}; 77074fe6c29SRuslan Bukin 77174fe6c29SRuslan Bukin/** A PWRX packet. */ 77274fe6c29SRuslan Bukinstruct pt_packet_pwrx { 77374fe6c29SRuslan Bukin /** The core C-state at the time of the wake. */ 77474fe6c29SRuslan Bukin uint8_t last; 77574fe6c29SRuslan Bukin 77674fe6c29SRuslan Bukin /** The deepest core C-state achieved during sleep. */ 77774fe6c29SRuslan Bukin uint8_t deepest; 77874fe6c29SRuslan Bukin 77974fe6c29SRuslan Bukin /** The wake reason: 78074fe6c29SRuslan Bukin * 78174fe6c29SRuslan Bukin * - due to external interrupt received. 78274fe6c29SRuslan Bukin */ 78374fe6c29SRuslan Bukin uint32_t interrupt:1; 78474fe6c29SRuslan Bukin 78574fe6c29SRuslan Bukin /** - due to store to monitored address. */ 78674fe6c29SRuslan Bukin uint32_t store:1; 78774fe6c29SRuslan Bukin 78874fe6c29SRuslan Bukin /** - due to h/w autonomous condition such as HDC. */ 78974fe6c29SRuslan Bukin uint32_t autonomous:1; 79074fe6c29SRuslan Bukin}; 79174fe6c29SRuslan Bukin 79274fe6c29SRuslan Bukin/** A PTW packet. */ 79374fe6c29SRuslan Bukinstruct pt_packet_ptw { 79474fe6c29SRuslan Bukin /** The raw payload. */ 79574fe6c29SRuslan Bukin uint64_t payload; 79674fe6c29SRuslan Bukin 79774fe6c29SRuslan Bukin /** The payload size as encoded in the packet. */ 79874fe6c29SRuslan Bukin uint8_t plc; 79974fe6c29SRuslan Bukin 80074fe6c29SRuslan Bukin /** A flag saying whether a FUP is following PTW that provides 80174fe6c29SRuslan Bukin * the IP of the corresponding PTWRITE instruction. 80274fe6c29SRuslan Bukin */ 80374fe6c29SRuslan Bukin uint32_t ip:1; 80474fe6c29SRuslan Bukin}; 80574fe6c29SRuslan Bukin 80674fe6c29SRuslan Bukinstatic inline int pt_ptw_size(uint8_t plc) 80774fe6c29SRuslan Bukin{ 80874fe6c29SRuslan Bukin switch (plc) { 80974fe6c29SRuslan Bukin case 0: 81074fe6c29SRuslan Bukin return 4; 81174fe6c29SRuslan Bukin 81274fe6c29SRuslan Bukin case 1: 81374fe6c29SRuslan Bukin return 8; 81474fe6c29SRuslan Bukin 81574fe6c29SRuslan Bukin case 2: 81674fe6c29SRuslan Bukin case 3: 81774fe6c29SRuslan Bukin return -pte_bad_packet; 81874fe6c29SRuslan Bukin } 81974fe6c29SRuslan Bukin 82074fe6c29SRuslan Bukin return -pte_internal; 82174fe6c29SRuslan Bukin} 82274fe6c29SRuslan Bukin 82374fe6c29SRuslan Bukin/** An unknown packet decodable by the optional decoder callback. */ 82474fe6c29SRuslan Bukinstruct pt_packet_unknown { 82574fe6c29SRuslan Bukin /** Pointer to the raw packet bytes. */ 82674fe6c29SRuslan Bukin const uint8_t *packet; 82774fe6c29SRuslan Bukin 82874fe6c29SRuslan Bukin /** Optional pointer to a user-defined structure. */ 82974fe6c29SRuslan Bukin void *priv; 83074fe6c29SRuslan Bukin}; 83174fe6c29SRuslan Bukin 83274fe6c29SRuslan Bukin/** An Intel PT packet. */ 83374fe6c29SRuslan Bukinstruct pt_packet { 83474fe6c29SRuslan Bukin /** The type of the packet. 83574fe6c29SRuslan Bukin * 83674fe6c29SRuslan Bukin * This also determines the \@payload field. 83774fe6c29SRuslan Bukin */ 83874fe6c29SRuslan Bukin enum pt_packet_type type; 83974fe6c29SRuslan Bukin 84074fe6c29SRuslan Bukin /** The size of the packet including opcode and payload. */ 84174fe6c29SRuslan Bukin uint8_t size; 84274fe6c29SRuslan Bukin 84374fe6c29SRuslan Bukin /** Packet specific data. */ 84474fe6c29SRuslan Bukin union { 84574fe6c29SRuslan Bukin /** Packets: pad, ovf, psb, psbend, stop - no payload. */ 84674fe6c29SRuslan Bukin 84774fe6c29SRuslan Bukin /** Packet: tnt-8, tnt-64. */ 84874fe6c29SRuslan Bukin struct pt_packet_tnt tnt; 84974fe6c29SRuslan Bukin 85074fe6c29SRuslan Bukin /** Packet: tip, fup, tip.pge, tip.pgd. */ 85174fe6c29SRuslan Bukin struct pt_packet_ip ip; 85274fe6c29SRuslan Bukin 85374fe6c29SRuslan Bukin /** Packet: mode. */ 85474fe6c29SRuslan Bukin struct pt_packet_mode mode; 85574fe6c29SRuslan Bukin 85674fe6c29SRuslan Bukin /** Packet: pip. */ 85774fe6c29SRuslan Bukin struct pt_packet_pip pip; 85874fe6c29SRuslan Bukin 85974fe6c29SRuslan Bukin /** Packet: tsc. */ 86074fe6c29SRuslan Bukin struct pt_packet_tsc tsc; 86174fe6c29SRuslan Bukin 86274fe6c29SRuslan Bukin /** Packet: cbr. */ 86374fe6c29SRuslan Bukin struct pt_packet_cbr cbr; 86474fe6c29SRuslan Bukin 86574fe6c29SRuslan Bukin /** Packet: tma. */ 86674fe6c29SRuslan Bukin struct pt_packet_tma tma; 86774fe6c29SRuslan Bukin 86874fe6c29SRuslan Bukin /** Packet: mtc. */ 86974fe6c29SRuslan Bukin struct pt_packet_mtc mtc; 87074fe6c29SRuslan Bukin 87174fe6c29SRuslan Bukin /** Packet: cyc. */ 87274fe6c29SRuslan Bukin struct pt_packet_cyc cyc; 87374fe6c29SRuslan Bukin 87474fe6c29SRuslan Bukin /** Packet: vmcs. */ 87574fe6c29SRuslan Bukin struct pt_packet_vmcs vmcs; 87674fe6c29SRuslan Bukin 87774fe6c29SRuslan Bukin /** Packet: mnt. */ 87874fe6c29SRuslan Bukin struct pt_packet_mnt mnt; 87974fe6c29SRuslan Bukin 88074fe6c29SRuslan Bukin /** Packet: exstop. */ 88174fe6c29SRuslan Bukin struct pt_packet_exstop exstop; 88274fe6c29SRuslan Bukin 88374fe6c29SRuslan Bukin /** Packet: mwait. */ 88474fe6c29SRuslan Bukin struct pt_packet_mwait mwait; 88574fe6c29SRuslan Bukin 88674fe6c29SRuslan Bukin /** Packet: pwre. */ 88774fe6c29SRuslan Bukin struct pt_packet_pwre pwre; 88874fe6c29SRuslan Bukin 88974fe6c29SRuslan Bukin /** Packet: pwrx. */ 89074fe6c29SRuslan Bukin struct pt_packet_pwrx pwrx; 89174fe6c29SRuslan Bukin 89274fe6c29SRuslan Bukin /** Packet: ptw. */ 89374fe6c29SRuslan Bukin struct pt_packet_ptw ptw; 89474fe6c29SRuslan Bukin 89574fe6c29SRuslan Bukin /** Packet: unknown. */ 89674fe6c29SRuslan Bukin struct pt_packet_unknown unknown; 89774fe6c29SRuslan Bukin } payload; 89874fe6c29SRuslan Bukin}; 89974fe6c29SRuslan Bukin 90074fe6c29SRuslan Bukin 90174fe6c29SRuslan Bukin 90274fe6c29SRuslan Bukin/* Packet encoder. */ 90374fe6c29SRuslan Bukin 90474fe6c29SRuslan Bukin 90574fe6c29SRuslan Bukin 90674fe6c29SRuslan Bukin/** Allocate an Intel PT packet encoder. 90774fe6c29SRuslan Bukin * 90874fe6c29SRuslan Bukin * The encoder will work on the buffer defined in \@config, it shall contain 90974fe6c29SRuslan Bukin * raw trace data and remain valid for the lifetime of the encoder. 91074fe6c29SRuslan Bukin * 91174fe6c29SRuslan Bukin * The encoder starts at the beginning of the trace buffer. 91274fe6c29SRuslan Bukin */ 91374fe6c29SRuslan Bukinextern pt_export struct pt_encoder * 91474fe6c29SRuslan Bukinpt_alloc_encoder(const struct pt_config *config); 91574fe6c29SRuslan Bukin 91674fe6c29SRuslan Bukin/** Free an Intel PT packet encoder. 91774fe6c29SRuslan Bukin * 91874fe6c29SRuslan Bukin * The \@encoder must not be used after a successful return. 91974fe6c29SRuslan Bukin */ 92074fe6c29SRuslan Bukinextern pt_export void pt_free_encoder(struct pt_encoder *encoder); 92174fe6c29SRuslan Bukin 92274fe6c29SRuslan Bukin/** Hard set synchronization point of an Intel PT packet encoder. 92374fe6c29SRuslan Bukin * 92474fe6c29SRuslan Bukin * Synchronize \@encoder to \@offset within the trace buffer. 92574fe6c29SRuslan Bukin * 92674fe6c29SRuslan Bukin * Returns zero on success, a negative error code otherwise. 92774fe6c29SRuslan Bukin * 92874fe6c29SRuslan Bukin * Returns -pte_eos if the given offset is behind the end of the trace buffer. 92974fe6c29SRuslan Bukin * Returns -pte_invalid if \@encoder is NULL. 93074fe6c29SRuslan Bukin */ 93174fe6c29SRuslan Bukinextern pt_export int pt_enc_sync_set(struct pt_encoder *encoder, 93274fe6c29SRuslan Bukin uint64_t offset); 93374fe6c29SRuslan Bukin 93474fe6c29SRuslan Bukin/** Get the current packet encoder position. 93574fe6c29SRuslan Bukin * 93674fe6c29SRuslan Bukin * Fills the current \@encoder position into \@offset. 93774fe6c29SRuslan Bukin * 93874fe6c29SRuslan Bukin * This is useful for reporting errors. 93974fe6c29SRuslan Bukin * 94074fe6c29SRuslan Bukin * Returns zero on success, a negative error code otherwise. 94174fe6c29SRuslan Bukin * 94274fe6c29SRuslan Bukin * Returns -pte_invalid if \@encoder or \@offset is NULL. 94374fe6c29SRuslan Bukin */ 94474fe6c29SRuslan Bukinextern pt_export int pt_enc_get_offset(const struct pt_encoder *encoder, 94574fe6c29SRuslan Bukin uint64_t *offset); 94674fe6c29SRuslan Bukin 94774fe6c29SRuslan Bukin/* Return a pointer to \@encoder's configuration. 94874fe6c29SRuslan Bukin * 94974fe6c29SRuslan Bukin * Returns a non-null pointer on success, NULL if \@encoder is NULL. 95074fe6c29SRuslan Bukin */ 95174fe6c29SRuslan Bukinextern pt_export const struct pt_config * 95274fe6c29SRuslan Bukinpt_enc_get_config(const struct pt_encoder *encoder); 95374fe6c29SRuslan Bukin 95474fe6c29SRuslan Bukin/** Encode an Intel PT packet. 95574fe6c29SRuslan Bukin * 95674fe6c29SRuslan Bukin * Writes \@packet at \@encoder's current position in the Intel PT buffer and 95774fe6c29SRuslan Bukin * advances the \@encoder beyond the written packet. 95874fe6c29SRuslan Bukin * 95974fe6c29SRuslan Bukin * The \@packet.size field is ignored. 96074fe6c29SRuslan Bukin * 96174fe6c29SRuslan Bukin * In case of errors, the \@encoder is not advanced and nothing is written 96274fe6c29SRuslan Bukin * into the Intel PT buffer. 96374fe6c29SRuslan Bukin * 96474fe6c29SRuslan Bukin * Returns the number of bytes written on success, a negative error code 96574fe6c29SRuslan Bukin * otherwise. 96674fe6c29SRuslan Bukin * 96774fe6c29SRuslan Bukin * Returns -pte_bad_opc if \@packet.type is not known. 96874fe6c29SRuslan Bukin * Returns -pte_bad_packet if \@packet's payload is invalid. 96974fe6c29SRuslan Bukin * Returns -pte_eos if \@encoder reached the end of the Intel PT buffer. 97074fe6c29SRuslan Bukin * Returns -pte_invalid if \@encoder or \@packet is NULL. 97174fe6c29SRuslan Bukin */ 97274fe6c29SRuslan Bukinextern pt_export int pt_enc_next(struct pt_encoder *encoder, 97374fe6c29SRuslan Bukin const struct pt_packet *packet); 97474fe6c29SRuslan Bukin 97574fe6c29SRuslan Bukin 97674fe6c29SRuslan Bukin 97774fe6c29SRuslan Bukin/* Packet decoder. */ 97874fe6c29SRuslan Bukin 97974fe6c29SRuslan Bukin 98074fe6c29SRuslan Bukin 98174fe6c29SRuslan Bukin/** Allocate an Intel PT packet decoder. 98274fe6c29SRuslan Bukin * 98374fe6c29SRuslan Bukin * The decoder will work on the buffer defined in \@config, it shall contain 98474fe6c29SRuslan Bukin * raw trace data and remain valid for the lifetime of the decoder. 98574fe6c29SRuslan Bukin * 98674fe6c29SRuslan Bukin * The decoder needs to be synchronized before it can be used. 98774fe6c29SRuslan Bukin */ 98874fe6c29SRuslan Bukinextern pt_export struct pt_packet_decoder * 98974fe6c29SRuslan Bukinpt_pkt_alloc_decoder(const struct pt_config *config); 99074fe6c29SRuslan Bukin 99174fe6c29SRuslan Bukin/** Free an Intel PT packet decoder. 99274fe6c29SRuslan Bukin * 99374fe6c29SRuslan Bukin * The \@decoder must not be used after a successful return. 99474fe6c29SRuslan Bukin */ 99574fe6c29SRuslan Bukinextern pt_export void pt_pkt_free_decoder(struct pt_packet_decoder *decoder); 99674fe6c29SRuslan Bukin 99774fe6c29SRuslan Bukin/** Synchronize an Intel PT packet decoder. 99874fe6c29SRuslan Bukin * 99974fe6c29SRuslan Bukin * Search for the next synchronization point in forward or backward direction. 100074fe6c29SRuslan Bukin * 100174fe6c29SRuslan Bukin * If \@decoder has not been synchronized, yet, the search is started at the 100274fe6c29SRuslan Bukin * beginning of the trace buffer in case of forward synchronization and at the 100374fe6c29SRuslan Bukin * end of the trace buffer in case of backward synchronization. 100474fe6c29SRuslan Bukin * 100574fe6c29SRuslan Bukin * Returns zero or a positive value on success, a negative error code otherwise. 100674fe6c29SRuslan Bukin * 100774fe6c29SRuslan Bukin * Returns -pte_eos if no further synchronization point is found. 100874fe6c29SRuslan Bukin * Returns -pte_invalid if \@decoder is NULL. 100974fe6c29SRuslan Bukin */ 101074fe6c29SRuslan Bukinextern pt_export int pt_pkt_sync_forward(struct pt_packet_decoder *decoder); 101174fe6c29SRuslan Bukinextern pt_export int pt_pkt_sync_backward(struct pt_packet_decoder *decoder); 101274fe6c29SRuslan Bukin 101374fe6c29SRuslan Bukin/** Hard set synchronization point of an Intel PT decoder. 101474fe6c29SRuslan Bukin * 101574fe6c29SRuslan Bukin * Synchronize \@decoder to \@offset within the trace buffer. 101674fe6c29SRuslan Bukin * 101774fe6c29SRuslan Bukin * Returns zero on success, a negative error code otherwise. 101874fe6c29SRuslan Bukin * 101974fe6c29SRuslan Bukin * Returns -pte_eos if the given offset is behind the end of the trace buffer. 102074fe6c29SRuslan Bukin * Returns -pte_invalid if \@decoder is NULL. 102174fe6c29SRuslan Bukin */ 102274fe6c29SRuslan Bukinextern pt_export int pt_pkt_sync_set(struct pt_packet_decoder *decoder, 102374fe6c29SRuslan Bukin uint64_t offset); 102474fe6c29SRuslan Bukin 102574fe6c29SRuslan Bukin/** Get the current decoder position. 102674fe6c29SRuslan Bukin * 102774fe6c29SRuslan Bukin * Fills the current \@decoder position into \@offset. 102874fe6c29SRuslan Bukin * 102974fe6c29SRuslan Bukin * This is useful for reporting errors. 103074fe6c29SRuslan Bukin * 103174fe6c29SRuslan Bukin * Returns zero on success, a negative error code otherwise. 103274fe6c29SRuslan Bukin * 103374fe6c29SRuslan Bukin * Returns -pte_invalid if \@decoder or \@offset is NULL. 103474fe6c29SRuslan Bukin * Returns -pte_nosync if \@decoder is out of sync. 103574fe6c29SRuslan Bukin */ 103674fe6c29SRuslan Bukinextern pt_export int pt_pkt_get_offset(const struct pt_packet_decoder *decoder, 103774fe6c29SRuslan Bukin uint64_t *offset); 103874fe6c29SRuslan Bukin 103974fe6c29SRuslan Bukin/** Get the position of the last synchronization point. 104074fe6c29SRuslan Bukin * 104174fe6c29SRuslan Bukin * Fills the last synchronization position into \@offset. 104274fe6c29SRuslan Bukin * 104374fe6c29SRuslan Bukin * This is useful when splitting a trace stream for parallel decoding. 104474fe6c29SRuslan Bukin * 104574fe6c29SRuslan Bukin * Returns zero on success, a negative error code otherwise. 104674fe6c29SRuslan Bukin * 104774fe6c29SRuslan Bukin * Returns -pte_invalid if \@decoder or \@offset is NULL. 104874fe6c29SRuslan Bukin * Returns -pte_nosync if \@decoder is out of sync. 104974fe6c29SRuslan Bukin */ 105074fe6c29SRuslan Bukinextern pt_export int 105174fe6c29SRuslan Bukinpt_pkt_get_sync_offset(const struct pt_packet_decoder *decoder, 105274fe6c29SRuslan Bukin uint64_t *offset); 105374fe6c29SRuslan Bukin 105474fe6c29SRuslan Bukin/* Return a pointer to \@decoder's configuration. 105574fe6c29SRuslan Bukin * 105674fe6c29SRuslan Bukin * Returns a non-null pointer on success, NULL if \@decoder is NULL. 105774fe6c29SRuslan Bukin */ 105874fe6c29SRuslan Bukinextern pt_export const struct pt_config * 105974fe6c29SRuslan Bukinpt_pkt_get_config(const struct pt_packet_decoder *decoder); 106074fe6c29SRuslan Bukin 106174fe6c29SRuslan Bukin/** Decode the next packet and advance the decoder. 106274fe6c29SRuslan Bukin * 106374fe6c29SRuslan Bukin * Decodes the packet at \@decoder's current position into \@packet and 106474fe6c29SRuslan Bukin * adjusts the \@decoder's position by the number of bytes the packet had 106574fe6c29SRuslan Bukin * consumed. 106674fe6c29SRuslan Bukin * 106774fe6c29SRuslan Bukin * The \@size argument must be set to sizeof(struct pt_packet). 106874fe6c29SRuslan Bukin * 106974fe6c29SRuslan Bukin * Returns the number of bytes consumed on success, a negative error code 107074fe6c29SRuslan Bukin * otherwise. 107174fe6c29SRuslan Bukin * 107274fe6c29SRuslan Bukin * Returns -pte_bad_opc if the packet is unknown. 107374fe6c29SRuslan Bukin * Returns -pte_bad_packet if an unknown packet payload is encountered. 107474fe6c29SRuslan Bukin * Returns -pte_eos if \@decoder reached the end of the Intel PT buffer. 107574fe6c29SRuslan Bukin * Returns -pte_invalid if \@decoder or \@packet is NULL. 107674fe6c29SRuslan Bukin * Returns -pte_nosync if \@decoder is out of sync. 107774fe6c29SRuslan Bukin */ 107874fe6c29SRuslan Bukinextern pt_export int pt_pkt_next(struct pt_packet_decoder *decoder, 107974fe6c29SRuslan Bukin struct pt_packet *packet, size_t size); 108074fe6c29SRuslan Bukin 108174fe6c29SRuslan Bukin 108274fe6c29SRuslan Bukin 108374fe6c29SRuslan Bukin/* Query decoder. */ 108474fe6c29SRuslan Bukin 108574fe6c29SRuslan Bukin 108674fe6c29SRuslan Bukin 108774fe6c29SRuslan Bukin/** Decoder status flags. */ 108874fe6c29SRuslan Bukinenum pt_status_flag { 108974fe6c29SRuslan Bukin /** There is an event pending. */ 109074fe6c29SRuslan Bukin pts_event_pending = 1 << 0, 109174fe6c29SRuslan Bukin 109274fe6c29SRuslan Bukin /** The address has been suppressed. */ 109374fe6c29SRuslan Bukin pts_ip_suppressed = 1 << 1, 109474fe6c29SRuslan Bukin 109574fe6c29SRuslan Bukin /** There is no more trace data available. */ 109674fe6c29SRuslan Bukin pts_eos = 1 << 2 109774fe6c29SRuslan Bukin}; 109874fe6c29SRuslan Bukin 109974fe6c29SRuslan Bukin/** Event types. */ 110074fe6c29SRuslan Bukinenum pt_event_type { 110174fe6c29SRuslan Bukin /* Tracing has been enabled/disabled. */ 110274fe6c29SRuslan Bukin ptev_enabled, 110374fe6c29SRuslan Bukin ptev_disabled, 110474fe6c29SRuslan Bukin 110574fe6c29SRuslan Bukin /* Tracing has been disabled asynchronously. */ 110674fe6c29SRuslan Bukin ptev_async_disabled, 110774fe6c29SRuslan Bukin 110874fe6c29SRuslan Bukin /* An asynchronous branch, e.g. interrupt. */ 110974fe6c29SRuslan Bukin ptev_async_branch, 111074fe6c29SRuslan Bukin 111174fe6c29SRuslan Bukin /* A synchronous paging event. */ 111274fe6c29SRuslan Bukin ptev_paging, 111374fe6c29SRuslan Bukin 111474fe6c29SRuslan Bukin /* An asynchronous paging event. */ 111574fe6c29SRuslan Bukin ptev_async_paging, 111674fe6c29SRuslan Bukin 111774fe6c29SRuslan Bukin /* Trace overflow. */ 111874fe6c29SRuslan Bukin ptev_overflow, 111974fe6c29SRuslan Bukin 112074fe6c29SRuslan Bukin /* An execution mode change. */ 112174fe6c29SRuslan Bukin ptev_exec_mode, 112274fe6c29SRuslan Bukin 112374fe6c29SRuslan Bukin /* A transactional execution state change. */ 112474fe6c29SRuslan Bukin ptev_tsx, 112574fe6c29SRuslan Bukin 112674fe6c29SRuslan Bukin /* Trace Stop. */ 112774fe6c29SRuslan Bukin ptev_stop, 112874fe6c29SRuslan Bukin 112974fe6c29SRuslan Bukin /* A synchronous vmcs event. */ 113074fe6c29SRuslan Bukin ptev_vmcs, 113174fe6c29SRuslan Bukin 113274fe6c29SRuslan Bukin /* An asynchronous vmcs event. */ 113374fe6c29SRuslan Bukin ptev_async_vmcs, 113474fe6c29SRuslan Bukin 113574fe6c29SRuslan Bukin /* Execution has stopped. */ 113674fe6c29SRuslan Bukin ptev_exstop, 113774fe6c29SRuslan Bukin 113874fe6c29SRuslan Bukin /* An MWAIT operation completed. */ 113974fe6c29SRuslan Bukin ptev_mwait, 114074fe6c29SRuslan Bukin 114174fe6c29SRuslan Bukin /* A power state was entered. */ 114274fe6c29SRuslan Bukin ptev_pwre, 114374fe6c29SRuslan Bukin 114474fe6c29SRuslan Bukin /* A power state was exited. */ 114574fe6c29SRuslan Bukin ptev_pwrx, 114674fe6c29SRuslan Bukin 114774fe6c29SRuslan Bukin /* A PTWRITE event. */ 114874fe6c29SRuslan Bukin ptev_ptwrite, 114974fe6c29SRuslan Bukin 115074fe6c29SRuslan Bukin /* A timing event. */ 115174fe6c29SRuslan Bukin ptev_tick, 115274fe6c29SRuslan Bukin 115374fe6c29SRuslan Bukin /* A core:bus ratio event. */ 115474fe6c29SRuslan Bukin ptev_cbr, 115574fe6c29SRuslan Bukin 115674fe6c29SRuslan Bukin /* A maintenance event. */ 115774fe6c29SRuslan Bukin ptev_mnt 115874fe6c29SRuslan Bukin}; 115974fe6c29SRuslan Bukin 116074fe6c29SRuslan Bukin/** An event. */ 116174fe6c29SRuslan Bukinstruct pt_event { 116274fe6c29SRuslan Bukin /** The type of the event. */ 116374fe6c29SRuslan Bukin enum pt_event_type type; 116474fe6c29SRuslan Bukin 116574fe6c29SRuslan Bukin /** A flag indicating that the event IP has been suppressed. */ 116674fe6c29SRuslan Bukin uint32_t ip_suppressed:1; 116774fe6c29SRuslan Bukin 116874fe6c29SRuslan Bukin /** A flag indicating that the event is for status update. */ 116974fe6c29SRuslan Bukin uint32_t status_update:1; 117074fe6c29SRuslan Bukin 117174fe6c29SRuslan Bukin /** A flag indicating that the event has timing information. */ 117274fe6c29SRuslan Bukin uint32_t has_tsc:1; 117374fe6c29SRuslan Bukin 117474fe6c29SRuslan Bukin /** The time stamp count of the event. 117574fe6c29SRuslan Bukin * 117674fe6c29SRuslan Bukin * This field is only valid if \@has_tsc is set. 117774fe6c29SRuslan Bukin */ 117874fe6c29SRuslan Bukin uint64_t tsc; 117974fe6c29SRuslan Bukin 118074fe6c29SRuslan Bukin /** The number of lost mtc and cyc packets. 118174fe6c29SRuslan Bukin * 118274fe6c29SRuslan Bukin * This gives an idea about the quality of the \@tsc. The more packets 118374fe6c29SRuslan Bukin * were dropped, the less precise timing is. 118474fe6c29SRuslan Bukin */ 118574fe6c29SRuslan Bukin uint32_t lost_mtc; 118674fe6c29SRuslan Bukin uint32_t lost_cyc; 118774fe6c29SRuslan Bukin 118874fe6c29SRuslan Bukin /* Reserved space for future extensions. */ 118974fe6c29SRuslan Bukin uint64_t reserved[2]; 119074fe6c29SRuslan Bukin 119174fe6c29SRuslan Bukin /** Event specific data. */ 119274fe6c29SRuslan Bukin union { 119374fe6c29SRuslan Bukin /** Event: enabled. */ 119474fe6c29SRuslan Bukin struct { 119574fe6c29SRuslan Bukin /** The address at which tracing resumes. */ 119674fe6c29SRuslan Bukin uint64_t ip; 119774fe6c29SRuslan Bukin 119874fe6c29SRuslan Bukin /** A flag indicating that tracing resumes from the IP 119974fe6c29SRuslan Bukin * at which tracing had been disabled before. 120074fe6c29SRuslan Bukin */ 120174fe6c29SRuslan Bukin uint32_t resumed:1; 120274fe6c29SRuslan Bukin } enabled; 120374fe6c29SRuslan Bukin 120474fe6c29SRuslan Bukin /** Event: disabled. */ 120574fe6c29SRuslan Bukin struct { 120674fe6c29SRuslan Bukin /** The destination of the first branch inside a 120774fe6c29SRuslan Bukin * filtered area. 120874fe6c29SRuslan Bukin * 120974fe6c29SRuslan Bukin * This field is not valid if \@ip_suppressed is set. 121074fe6c29SRuslan Bukin */ 121174fe6c29SRuslan Bukin uint64_t ip; 121274fe6c29SRuslan Bukin 121374fe6c29SRuslan Bukin /* The exact source ip needs to be determined using 121474fe6c29SRuslan Bukin * disassembly and the filter configuration. 121574fe6c29SRuslan Bukin */ 121674fe6c29SRuslan Bukin } disabled; 121774fe6c29SRuslan Bukin 121874fe6c29SRuslan Bukin /** Event: async disabled. */ 121974fe6c29SRuslan Bukin struct { 122074fe6c29SRuslan Bukin /** The source address of the asynchronous branch that 122174fe6c29SRuslan Bukin * disabled tracing. 122274fe6c29SRuslan Bukin */ 122374fe6c29SRuslan Bukin uint64_t at; 122474fe6c29SRuslan Bukin 122574fe6c29SRuslan Bukin /** The destination of the first branch inside a 122674fe6c29SRuslan Bukin * filtered area. 122774fe6c29SRuslan Bukin * 122874fe6c29SRuslan Bukin * This field is not valid if \@ip_suppressed is set. 122974fe6c29SRuslan Bukin */ 123074fe6c29SRuslan Bukin uint64_t ip; 123174fe6c29SRuslan Bukin } async_disabled; 123274fe6c29SRuslan Bukin 123374fe6c29SRuslan Bukin /** Event: async branch. */ 123474fe6c29SRuslan Bukin struct { 123574fe6c29SRuslan Bukin /** The branch source address. */ 123674fe6c29SRuslan Bukin uint64_t from; 123774fe6c29SRuslan Bukin 123874fe6c29SRuslan Bukin /** The branch destination address. 123974fe6c29SRuslan Bukin * 124074fe6c29SRuslan Bukin * This field is not valid if \@ip_suppressed is set. 124174fe6c29SRuslan Bukin */ 124274fe6c29SRuslan Bukin uint64_t to; 124374fe6c29SRuslan Bukin } async_branch; 124474fe6c29SRuslan Bukin 124574fe6c29SRuslan Bukin /** Event: paging. */ 124674fe6c29SRuslan Bukin struct { 124774fe6c29SRuslan Bukin /** The updated CR3 value. 124874fe6c29SRuslan Bukin * 124974fe6c29SRuslan Bukin * The lower 5 bit have been zeroed out. 125074fe6c29SRuslan Bukin * The upper bits have been zeroed out depending on the 125174fe6c29SRuslan Bukin * maximum possible address. 125274fe6c29SRuslan Bukin */ 125374fe6c29SRuslan Bukin uint64_t cr3; 125474fe6c29SRuslan Bukin 125574fe6c29SRuslan Bukin /** A flag indicating whether the cpu is operating in 125674fe6c29SRuslan Bukin * vmx non-root (guest) mode. 125774fe6c29SRuslan Bukin */ 125874fe6c29SRuslan Bukin uint32_t non_root:1; 125974fe6c29SRuslan Bukin 126074fe6c29SRuslan Bukin /* The address at which the event is effective is 126174fe6c29SRuslan Bukin * obvious from the disassembly. 126274fe6c29SRuslan Bukin */ 126374fe6c29SRuslan Bukin } paging; 126474fe6c29SRuslan Bukin 126574fe6c29SRuslan Bukin /** Event: async paging. */ 126674fe6c29SRuslan Bukin struct { 126774fe6c29SRuslan Bukin /** The updated CR3 value. 126874fe6c29SRuslan Bukin * 126974fe6c29SRuslan Bukin * The lower 5 bit have been zeroed out. 127074fe6c29SRuslan Bukin * The upper bits have been zeroed out depending on the 127174fe6c29SRuslan Bukin * maximum possible address. 127274fe6c29SRuslan Bukin */ 127374fe6c29SRuslan Bukin uint64_t cr3; 127474fe6c29SRuslan Bukin 127574fe6c29SRuslan Bukin /** A flag indicating whether the cpu is operating in 127674fe6c29SRuslan Bukin * vmx non-root (guest) mode. 127774fe6c29SRuslan Bukin */ 127874fe6c29SRuslan Bukin uint32_t non_root:1; 127974fe6c29SRuslan Bukin 128074fe6c29SRuslan Bukin /** The address at which the event is effective. */ 128174fe6c29SRuslan Bukin uint64_t ip; 128274fe6c29SRuslan Bukin } async_paging; 128374fe6c29SRuslan Bukin 128474fe6c29SRuslan Bukin /** Event: overflow. */ 128574fe6c29SRuslan Bukin struct { 128674fe6c29SRuslan Bukin /** The address at which tracing resumes after overflow. 128774fe6c29SRuslan Bukin * 128874fe6c29SRuslan Bukin * This field is not valid, if ip_suppressed is set. 128974fe6c29SRuslan Bukin * In this case, the overflow resolved while tracing 129074fe6c29SRuslan Bukin * was disabled. 129174fe6c29SRuslan Bukin */ 129274fe6c29SRuslan Bukin uint64_t ip; 129374fe6c29SRuslan Bukin } overflow; 129474fe6c29SRuslan Bukin 129574fe6c29SRuslan Bukin /** Event: exec mode. */ 129674fe6c29SRuslan Bukin struct { 129774fe6c29SRuslan Bukin /** The execution mode. */ 129874fe6c29SRuslan Bukin enum pt_exec_mode mode; 129974fe6c29SRuslan Bukin 130074fe6c29SRuslan Bukin /** The address at which the event is effective. */ 130174fe6c29SRuslan Bukin uint64_t ip; 130274fe6c29SRuslan Bukin } exec_mode; 130374fe6c29SRuslan Bukin 130474fe6c29SRuslan Bukin /** Event: tsx. */ 130574fe6c29SRuslan Bukin struct { 130674fe6c29SRuslan Bukin /** The address at which the event is effective. 130774fe6c29SRuslan Bukin * 130874fe6c29SRuslan Bukin * This field is not valid if \@ip_suppressed is set. 130974fe6c29SRuslan Bukin */ 131074fe6c29SRuslan Bukin uint64_t ip; 131174fe6c29SRuslan Bukin 131274fe6c29SRuslan Bukin /** A flag indicating speculative execution mode. */ 131374fe6c29SRuslan Bukin uint32_t speculative:1; 131474fe6c29SRuslan Bukin 131574fe6c29SRuslan Bukin /** A flag indicating speculative execution aborts. */ 131674fe6c29SRuslan Bukin uint32_t aborted:1; 131774fe6c29SRuslan Bukin } tsx; 131874fe6c29SRuslan Bukin 131974fe6c29SRuslan Bukin /** Event: vmcs. */ 132074fe6c29SRuslan Bukin struct { 132174fe6c29SRuslan Bukin /** The VMCS base address. 132274fe6c29SRuslan Bukin * 132374fe6c29SRuslan Bukin * The address is zero-extended with the lower 12 bits 132474fe6c29SRuslan Bukin * all zero. 132574fe6c29SRuslan Bukin */ 132674fe6c29SRuslan Bukin uint64_t base; 132774fe6c29SRuslan Bukin 132874fe6c29SRuslan Bukin /* The new VMCS base address should be stored and 132974fe6c29SRuslan Bukin * applied on subsequent VM entries. 133074fe6c29SRuslan Bukin */ 133174fe6c29SRuslan Bukin } vmcs; 133274fe6c29SRuslan Bukin 133374fe6c29SRuslan Bukin /** Event: async vmcs. */ 133474fe6c29SRuslan Bukin struct { 133574fe6c29SRuslan Bukin /** The VMCS base address. 133674fe6c29SRuslan Bukin * 133774fe6c29SRuslan Bukin * The address is zero-extended with the lower 12 bits 133874fe6c29SRuslan Bukin * all zero. 133974fe6c29SRuslan Bukin */ 134074fe6c29SRuslan Bukin uint64_t base; 134174fe6c29SRuslan Bukin 134274fe6c29SRuslan Bukin /** The address at which the event is effective. */ 134374fe6c29SRuslan Bukin uint64_t ip; 134474fe6c29SRuslan Bukin 134574fe6c29SRuslan Bukin /* An async paging event that binds to the same IP 134674fe6c29SRuslan Bukin * will always succeed this async vmcs event. 134774fe6c29SRuslan Bukin */ 134874fe6c29SRuslan Bukin } async_vmcs; 134974fe6c29SRuslan Bukin 135074fe6c29SRuslan Bukin /** Event: execution stopped. */ 135174fe6c29SRuslan Bukin struct { 135274fe6c29SRuslan Bukin /** The address at which execution has stopped. This is 135374fe6c29SRuslan Bukin * the last instruction that did not complete. 135474fe6c29SRuslan Bukin * 135574fe6c29SRuslan Bukin * This field is not valid, if \@ip_suppressed is set. 135674fe6c29SRuslan Bukin */ 135774fe6c29SRuslan Bukin uint64_t ip; 135874fe6c29SRuslan Bukin } exstop; 135974fe6c29SRuslan Bukin 136074fe6c29SRuslan Bukin /** Event: mwait. */ 136174fe6c29SRuslan Bukin struct { 136274fe6c29SRuslan Bukin /** The address of the instruction causing the mwait. 136374fe6c29SRuslan Bukin * 136474fe6c29SRuslan Bukin * This field is not valid, if \@ip_suppressed is set. 136574fe6c29SRuslan Bukin */ 136674fe6c29SRuslan Bukin uint64_t ip; 136774fe6c29SRuslan Bukin 136874fe6c29SRuslan Bukin /** The mwait hints (eax). 136974fe6c29SRuslan Bukin * 137074fe6c29SRuslan Bukin * Reserved bits are undefined. 137174fe6c29SRuslan Bukin */ 137274fe6c29SRuslan Bukin uint32_t hints; 137374fe6c29SRuslan Bukin 137474fe6c29SRuslan Bukin /** The mwait extensions (ecx). 137574fe6c29SRuslan Bukin * 137674fe6c29SRuslan Bukin * Reserved bits are undefined. 137774fe6c29SRuslan Bukin */ 137874fe6c29SRuslan Bukin uint32_t ext; 137974fe6c29SRuslan Bukin } mwait; 138074fe6c29SRuslan Bukin 138174fe6c29SRuslan Bukin /** Event: power state entry. */ 138274fe6c29SRuslan Bukin struct { 138374fe6c29SRuslan Bukin /** The resolved thread C-state. */ 138474fe6c29SRuslan Bukin uint8_t state; 138574fe6c29SRuslan Bukin 138674fe6c29SRuslan Bukin /** The resolved thread sub C-state. */ 138774fe6c29SRuslan Bukin uint8_t sub_state; 138874fe6c29SRuslan Bukin 138974fe6c29SRuslan Bukin /** A flag indicating whether the C-state entry was 139074fe6c29SRuslan Bukin * initiated by h/w. 139174fe6c29SRuslan Bukin */ 139274fe6c29SRuslan Bukin uint32_t hw:1; 139374fe6c29SRuslan Bukin } pwre; 139474fe6c29SRuslan Bukin 139574fe6c29SRuslan Bukin /** Event: power state exit. */ 139674fe6c29SRuslan Bukin struct { 139774fe6c29SRuslan Bukin /** The core C-state at the time of the wake. */ 139874fe6c29SRuslan Bukin uint8_t last; 139974fe6c29SRuslan Bukin 140074fe6c29SRuslan Bukin /** The deepest core C-state achieved during sleep. */ 140174fe6c29SRuslan Bukin uint8_t deepest; 140274fe6c29SRuslan Bukin 140374fe6c29SRuslan Bukin /** The wake reason: 140474fe6c29SRuslan Bukin * 140574fe6c29SRuslan Bukin * - due to external interrupt received. 140674fe6c29SRuslan Bukin */ 140774fe6c29SRuslan Bukin uint32_t interrupt:1; 140874fe6c29SRuslan Bukin 140974fe6c29SRuslan Bukin /** - due to store to monitored address. */ 141074fe6c29SRuslan Bukin uint32_t store:1; 141174fe6c29SRuslan Bukin 141274fe6c29SRuslan Bukin /** - due to h/w autonomous condition such as HDC. */ 141374fe6c29SRuslan Bukin uint32_t autonomous:1; 141474fe6c29SRuslan Bukin } pwrx; 141574fe6c29SRuslan Bukin 141674fe6c29SRuslan Bukin /** Event: ptwrite. */ 141774fe6c29SRuslan Bukin struct { 141874fe6c29SRuslan Bukin /** The address of the ptwrite instruction. 141974fe6c29SRuslan Bukin * 142074fe6c29SRuslan Bukin * This field is not valid, if \@ip_suppressed is set. 142174fe6c29SRuslan Bukin * 142274fe6c29SRuslan Bukin * In this case, the address is obvious from the 142374fe6c29SRuslan Bukin * disassembly. 142474fe6c29SRuslan Bukin */ 142574fe6c29SRuslan Bukin uint64_t ip; 142674fe6c29SRuslan Bukin 142774fe6c29SRuslan Bukin /** The size of the below \@payload in bytes. */ 142874fe6c29SRuslan Bukin uint8_t size; 142974fe6c29SRuslan Bukin 143074fe6c29SRuslan Bukin /** The ptwrite payload. */ 143174fe6c29SRuslan Bukin uint64_t payload; 143274fe6c29SRuslan Bukin } ptwrite; 143374fe6c29SRuslan Bukin 143474fe6c29SRuslan Bukin /** Event: tick. */ 143574fe6c29SRuslan Bukin struct { 143674fe6c29SRuslan Bukin /** The instruction address near which the tick occured. 143774fe6c29SRuslan Bukin * 143874fe6c29SRuslan Bukin * A timestamp can sometimes be attributed directly to 143974fe6c29SRuslan Bukin * an instruction (e.g. to an indirect branch that 144074fe6c29SRuslan Bukin * receives CYC + TIP) and sometimes not (e.g. MTC). 144174fe6c29SRuslan Bukin * 144274fe6c29SRuslan Bukin * This field is not valid, if \@ip_suppressed is set. 144374fe6c29SRuslan Bukin */ 144474fe6c29SRuslan Bukin uint64_t ip; 144574fe6c29SRuslan Bukin } tick; 144674fe6c29SRuslan Bukin 144774fe6c29SRuslan Bukin /** Event: cbr. */ 144874fe6c29SRuslan Bukin struct { 144974fe6c29SRuslan Bukin /** The core:bus ratio. */ 145074fe6c29SRuslan Bukin uint16_t ratio; 145174fe6c29SRuslan Bukin } cbr; 145274fe6c29SRuslan Bukin 145374fe6c29SRuslan Bukin /** Event: mnt. */ 145474fe6c29SRuslan Bukin struct { 145574fe6c29SRuslan Bukin /** The raw payload. */ 145674fe6c29SRuslan Bukin uint64_t payload; 145774fe6c29SRuslan Bukin } mnt; 145874fe6c29SRuslan Bukin } variant; 145974fe6c29SRuslan Bukin}; 146074fe6c29SRuslan Bukin 146174fe6c29SRuslan Bukin 146274fe6c29SRuslan Bukin/** Allocate an Intel PT query decoder. 146374fe6c29SRuslan Bukin * 146474fe6c29SRuslan Bukin * The decoder will work on the buffer defined in \@config, it shall contain 146574fe6c29SRuslan Bukin * raw trace data and remain valid for the lifetime of the decoder. 146674fe6c29SRuslan Bukin * 146774fe6c29SRuslan Bukin * The decoder needs to be synchronized before it can be used. 146874fe6c29SRuslan Bukin */ 146974fe6c29SRuslan Bukinextern pt_export struct pt_query_decoder * 147074fe6c29SRuslan Bukinpt_qry_alloc_decoder(const struct pt_config *config); 147174fe6c29SRuslan Bukin 147274fe6c29SRuslan Bukin/** Free an Intel PT query decoder. 147374fe6c29SRuslan Bukin * 147474fe6c29SRuslan Bukin * The \@decoder must not be used after a successful return. 147574fe6c29SRuslan Bukin */ 147674fe6c29SRuslan Bukinextern pt_export void pt_qry_free_decoder(struct pt_query_decoder *decoder); 147774fe6c29SRuslan Bukin 147874fe6c29SRuslan Bukin/** Synchronize an Intel PT query decoder. 147974fe6c29SRuslan Bukin * 148074fe6c29SRuslan Bukin * Search for the next synchronization point in forward or backward direction. 148174fe6c29SRuslan Bukin * 148274fe6c29SRuslan Bukin * If \@decoder has not been synchronized, yet, the search is started at the 148374fe6c29SRuslan Bukin * beginning of the trace buffer in case of forward synchronization and at the 148474fe6c29SRuslan Bukin * end of the trace buffer in case of backward synchronization. 148574fe6c29SRuslan Bukin * 148674fe6c29SRuslan Bukin * If \@ip is not NULL, set it to last ip. 148774fe6c29SRuslan Bukin * 148874fe6c29SRuslan Bukin * Returns a non-negative pt_status_flag bit-vector on success, a negative error 148974fe6c29SRuslan Bukin * code otherwise. 149074fe6c29SRuslan Bukin * 149174fe6c29SRuslan Bukin * Returns -pte_bad_opc if an unknown packet is encountered. 149274fe6c29SRuslan Bukin * Returns -pte_bad_packet if an unknown packet payload is encountered. 149374fe6c29SRuslan Bukin * Returns -pte_eos if no further synchronization point is found. 149474fe6c29SRuslan Bukin * Returns -pte_invalid if \@decoder is NULL. 149574fe6c29SRuslan Bukin */ 149674fe6c29SRuslan Bukinextern pt_export int pt_qry_sync_forward(struct pt_query_decoder *decoder, 149774fe6c29SRuslan Bukin uint64_t *ip); 149874fe6c29SRuslan Bukinextern pt_export int pt_qry_sync_backward(struct pt_query_decoder *decoder, 149974fe6c29SRuslan Bukin uint64_t *ip); 150074fe6c29SRuslan Bukin 150174fe6c29SRuslan Bukin/** Manually synchronize an Intel PT query decoder. 150274fe6c29SRuslan Bukin * 150374fe6c29SRuslan Bukin * Synchronize \@decoder on the syncpoint at \@offset. There must be a PSB 150474fe6c29SRuslan Bukin * packet at \@offset. 150574fe6c29SRuslan Bukin * 150674fe6c29SRuslan Bukin * If \@ip is not NULL, set it to last ip. 150774fe6c29SRuslan Bukin * 150874fe6c29SRuslan Bukin * Returns a non-negative pt_status_flag bit-vector on success, a negative error 150974fe6c29SRuslan Bukin * code otherwise. 151074fe6c29SRuslan Bukin * 151174fe6c29SRuslan Bukin * Returns -pte_bad_opc if an unknown packet is encountered. 151274fe6c29SRuslan Bukin * Returns -pte_bad_packet if an unknown packet payload is encountered. 151374fe6c29SRuslan Bukin * Returns -pte_eos if \@offset lies outside of \@decoder's trace buffer. 151474fe6c29SRuslan Bukin * Returns -pte_eos if \@decoder reaches the end of its trace buffer. 151574fe6c29SRuslan Bukin * Returns -pte_invalid if \@decoder is NULL. 151674fe6c29SRuslan Bukin * Returns -pte_nosync if there is no syncpoint at \@offset. 151774fe6c29SRuslan Bukin */ 151874fe6c29SRuslan Bukinextern pt_export int pt_qry_sync_set(struct pt_query_decoder *decoder, 151974fe6c29SRuslan Bukin uint64_t *ip, uint64_t offset); 152074fe6c29SRuslan Bukin 152174fe6c29SRuslan Bukin/** Get the current decoder position. 152274fe6c29SRuslan Bukin * 152374fe6c29SRuslan Bukin * Fills the current \@decoder position into \@offset. 152474fe6c29SRuslan Bukin * 152574fe6c29SRuslan Bukin * This is useful for reporting errors. 152674fe6c29SRuslan Bukin * 152774fe6c29SRuslan Bukin * Returns zero on success, a negative error code otherwise. 152874fe6c29SRuslan Bukin * 152974fe6c29SRuslan Bukin * Returns -pte_invalid if \@decoder or \@offset is NULL. 153074fe6c29SRuslan Bukin * Returns -pte_nosync if \@decoder is out of sync. 153174fe6c29SRuslan Bukin */ 153274fe6c29SRuslan Bukinextern pt_export int pt_qry_get_offset(const struct pt_query_decoder *decoder, 153374fe6c29SRuslan Bukin uint64_t *offset); 153474fe6c29SRuslan Bukin 153574fe6c29SRuslan Bukin/** Get the position of the last synchronization point. 153674fe6c29SRuslan Bukin * 153774fe6c29SRuslan Bukin * Fills the last synchronization position into \@offset. 153874fe6c29SRuslan Bukin * 153974fe6c29SRuslan Bukin * This is useful for splitting a trace stream for parallel decoding. 154074fe6c29SRuslan Bukin * 154174fe6c29SRuslan Bukin * Returns zero on success, a negative error code otherwise. 154274fe6c29SRuslan Bukin * 154374fe6c29SRuslan Bukin * Returns -pte_invalid if \@decoder or \@offset is NULL. 154474fe6c29SRuslan Bukin * Returns -pte_nosync if \@decoder is out of sync. 154574fe6c29SRuslan Bukin */ 154674fe6c29SRuslan Bukinextern pt_export int 154774fe6c29SRuslan Bukinpt_qry_get_sync_offset(const struct pt_query_decoder *decoder, 154874fe6c29SRuslan Bukin uint64_t *offset); 154974fe6c29SRuslan Bukin 155074fe6c29SRuslan Bukin/* Return a pointer to \@decoder's configuration. 155174fe6c29SRuslan Bukin * 155274fe6c29SRuslan Bukin * Returns a non-null pointer on success, NULL if \@decoder is NULL. 155374fe6c29SRuslan Bukin */ 155474fe6c29SRuslan Bukinextern pt_export const struct pt_config * 155574fe6c29SRuslan Bukinpt_qry_get_config(const struct pt_query_decoder *decoder); 155674fe6c29SRuslan Bukin 155774fe6c29SRuslan Bukin/** Query whether the next unconditional branch has been taken. 155874fe6c29SRuslan Bukin * 155974fe6c29SRuslan Bukin * On success, provides 1 (taken) or 0 (not taken) in \@taken for the next 156074fe6c29SRuslan Bukin * conditional branch and updates \@decoder. 156174fe6c29SRuslan Bukin * 156274fe6c29SRuslan Bukin * Returns a non-negative pt_status_flag bit-vector on success, a negative error 156374fe6c29SRuslan Bukin * code otherwise. 156474fe6c29SRuslan Bukin * 156574fe6c29SRuslan Bukin * Returns -pte_bad_opc if an unknown packet is encountered. 156674fe6c29SRuslan Bukin * Returns -pte_bad_packet if an unknown packet payload is encountered. 156774fe6c29SRuslan Bukin * Returns -pte_bad_query if no conditional branch is found. 156874fe6c29SRuslan Bukin * Returns -pte_eos if decoding reached the end of the Intel PT buffer. 156974fe6c29SRuslan Bukin * Returns -pte_invalid if \@decoder or \@taken is NULL. 157074fe6c29SRuslan Bukin * Returns -pte_nosync if \@decoder is out of sync. 157174fe6c29SRuslan Bukin */ 157274fe6c29SRuslan Bukinextern pt_export int pt_qry_cond_branch(struct pt_query_decoder *decoder, 157374fe6c29SRuslan Bukin int *taken); 157474fe6c29SRuslan Bukin 157574fe6c29SRuslan Bukin/** Get the next indirect branch destination. 157674fe6c29SRuslan Bukin * 157774fe6c29SRuslan Bukin * On success, provides the linear destination address of the next indirect 157874fe6c29SRuslan Bukin * branch in \@ip and updates \@decoder. 157974fe6c29SRuslan Bukin * 158074fe6c29SRuslan Bukin * Returns a non-negative pt_status_flag bit-vector on success, a negative error 158174fe6c29SRuslan Bukin * code otherwise. 158274fe6c29SRuslan Bukin * 158374fe6c29SRuslan Bukin * Returns -pte_bad_opc if an unknown packet is encountered. 158474fe6c29SRuslan Bukin * Returns -pte_bad_packet if an unknown packet payload is encountered. 158574fe6c29SRuslan Bukin * Returns -pte_bad_query if no indirect branch is found. 158674fe6c29SRuslan Bukin * Returns -pte_eos if decoding reached the end of the Intel PT buffer. 158774fe6c29SRuslan Bukin * Returns -pte_invalid if \@decoder or \@ip is NULL. 158874fe6c29SRuslan Bukin * Returns -pte_nosync if \@decoder is out of sync. 158974fe6c29SRuslan Bukin */ 159074fe6c29SRuslan Bukinextern pt_export int pt_qry_indirect_branch(struct pt_query_decoder *decoder, 159174fe6c29SRuslan Bukin uint64_t *ip); 159274fe6c29SRuslan Bukin 159374fe6c29SRuslan Bukin/** Query the next pending event. 159474fe6c29SRuslan Bukin * 159574fe6c29SRuslan Bukin * On success, provides the next event \@event and updates \@decoder. 159674fe6c29SRuslan Bukin * 159774fe6c29SRuslan Bukin * The \@size argument must be set to sizeof(struct pt_event). 159874fe6c29SRuslan Bukin * 159974fe6c29SRuslan Bukin * Returns a non-negative pt_status_flag bit-vector on success, a negative error 160074fe6c29SRuslan Bukin * code otherwise. 160174fe6c29SRuslan Bukin * 160274fe6c29SRuslan Bukin * Returns -pte_bad_opc if an unknown packet is encountered. 160374fe6c29SRuslan Bukin * Returns -pte_bad_packet if an unknown packet payload is encountered. 160474fe6c29SRuslan Bukin * Returns -pte_bad_query if no event is found. 160574fe6c29SRuslan Bukin * Returns -pte_eos if decoding reached the end of the Intel PT buffer. 160674fe6c29SRuslan Bukin * Returns -pte_invalid if \@decoder or \@event is NULL. 160774fe6c29SRuslan Bukin * Returns -pte_invalid if \@size is too small. 160874fe6c29SRuslan Bukin * Returns -pte_nosync if \@decoder is out of sync. 160974fe6c29SRuslan Bukin */ 161074fe6c29SRuslan Bukinextern pt_export int pt_qry_event(struct pt_query_decoder *decoder, 161174fe6c29SRuslan Bukin struct pt_event *event, size_t size); 161274fe6c29SRuslan Bukin 161374fe6c29SRuslan Bukin/** Query the current time. 161474fe6c29SRuslan Bukin * 161574fe6c29SRuslan Bukin * On success, provides the time at the last query in \@time. 161674fe6c29SRuslan Bukin * 161774fe6c29SRuslan Bukin * The time is similar to what a rdtsc instruction would return. Depending 161874fe6c29SRuslan Bukin * on the configuration, the time may not be fully accurate. If TSC is not 161974fe6c29SRuslan Bukin * enabled, the time is relative to the last synchronization and can't be used 162074fe6c29SRuslan Bukin * to correlate with other TSC-based time sources. In this case, -pte_no_time 162174fe6c29SRuslan Bukin * is returned and the relative time is provided in \@time. 162274fe6c29SRuslan Bukin * 162374fe6c29SRuslan Bukin * Some timing-related packets may need to be dropped (mostly due to missing 162474fe6c29SRuslan Bukin * calibration or incomplete configuration). To get an idea about the quality 162574fe6c29SRuslan Bukin * of the estimated time, we record the number of dropped MTC and CYC packets. 162674fe6c29SRuslan Bukin * 162774fe6c29SRuslan Bukin * If \@lost_mtc is not NULL, set it to the number of lost MTC packets. 162874fe6c29SRuslan Bukin * If \@lost_cyc is not NULL, set it to the number of lost CYC packets. 162974fe6c29SRuslan Bukin * 163074fe6c29SRuslan Bukin * Returns zero on success, a negative error code otherwise. 163174fe6c29SRuslan Bukin * 163274fe6c29SRuslan Bukin * Returns -pte_invalid if \@decoder or \@time is NULL. 163374fe6c29SRuslan Bukin * Returns -pte_no_time if there has not been a TSC packet. 163474fe6c29SRuslan Bukin */ 163574fe6c29SRuslan Bukinextern pt_export int pt_qry_time(struct pt_query_decoder *decoder, 163674fe6c29SRuslan Bukin uint64_t *time, uint32_t *lost_mtc, 163774fe6c29SRuslan Bukin uint32_t *lost_cyc); 163874fe6c29SRuslan Bukin 163974fe6c29SRuslan Bukin/** Return the current core bus ratio. 164074fe6c29SRuslan Bukin * 164174fe6c29SRuslan Bukin * On success, provides the current core:bus ratio in \@cbr. The ratio is 164274fe6c29SRuslan Bukin * defined as core cycles per bus clock cycle. 164374fe6c29SRuslan Bukin * 164474fe6c29SRuslan Bukin * Returns zero on success, a negative error code otherwise. 164574fe6c29SRuslan Bukin * 164674fe6c29SRuslan Bukin * Returns -pte_invalid if \@decoder or \@cbr is NULL. 164774fe6c29SRuslan Bukin * Returns -pte_no_cbr if there has not been a CBR packet. 164874fe6c29SRuslan Bukin */ 164974fe6c29SRuslan Bukinextern pt_export int pt_qry_core_bus_ratio(struct pt_query_decoder *decoder, 165074fe6c29SRuslan Bukin uint32_t *cbr); 165174fe6c29SRuslan Bukin 165274fe6c29SRuslan Bukin 165374fe6c29SRuslan Bukin 165474fe6c29SRuslan Bukin/* Traced image. */ 165574fe6c29SRuslan Bukin 165674fe6c29SRuslan Bukin 165774fe6c29SRuslan Bukin 165874fe6c29SRuslan Bukin/** An Intel PT address space identifier. 165974fe6c29SRuslan Bukin * 166074fe6c29SRuslan Bukin * This identifies a particular address space when adding file sections or 166174fe6c29SRuslan Bukin * when reading memory. 166274fe6c29SRuslan Bukin */ 166374fe6c29SRuslan Bukinstruct pt_asid { 166474fe6c29SRuslan Bukin /** The size of this object - set to sizeof(struct pt_asid). */ 166574fe6c29SRuslan Bukin size_t size; 166674fe6c29SRuslan Bukin 166774fe6c29SRuslan Bukin /** The CR3 value. */ 166874fe6c29SRuslan Bukin uint64_t cr3; 166974fe6c29SRuslan Bukin 167074fe6c29SRuslan Bukin /** The VMCS Base address. */ 167174fe6c29SRuslan Bukin uint64_t vmcs; 167274fe6c29SRuslan Bukin}; 167374fe6c29SRuslan Bukin 167474fe6c29SRuslan Bukin/** An unknown CR3 value to be used for pt_asid objects. */ 167574fe6c29SRuslan Bukinstatic const uint64_t pt_asid_no_cr3 = 0xffffffffffffffffull; 167674fe6c29SRuslan Bukin 167774fe6c29SRuslan Bukin/** An unknown VMCS Base value to be used for pt_asid objects. */ 167874fe6c29SRuslan Bukinstatic const uint64_t pt_asid_no_vmcs = 0xffffffffffffffffull; 167974fe6c29SRuslan Bukin 168074fe6c29SRuslan Bukin/** Initialize an address space identifier. */ 168174fe6c29SRuslan Bukinstatic inline void pt_asid_init(struct pt_asid *asid) 168274fe6c29SRuslan Bukin{ 168374fe6c29SRuslan Bukin asid->size = sizeof(*asid); 168474fe6c29SRuslan Bukin asid->cr3 = pt_asid_no_cr3; 168574fe6c29SRuslan Bukin asid->vmcs = pt_asid_no_vmcs; 168674fe6c29SRuslan Bukin} 168774fe6c29SRuslan Bukin 168874fe6c29SRuslan Bukin 168974fe6c29SRuslan Bukin/** A cache of traced image sections. */ 169074fe6c29SRuslan Bukinstruct pt_image_section_cache; 169174fe6c29SRuslan Bukin 169274fe6c29SRuslan Bukin/** Allocate a traced memory image section cache. 169374fe6c29SRuslan Bukin * 169474fe6c29SRuslan Bukin * An optional \@name may be given to the cache. The name string is copied. 169574fe6c29SRuslan Bukin * 169674fe6c29SRuslan Bukin * Returns a new traced memory image section cache on success, NULL otherwise. 169774fe6c29SRuslan Bukin */ 169874fe6c29SRuslan Bukinextern pt_export struct pt_image_section_cache * 169974fe6c29SRuslan Bukinpt_iscache_alloc(const char *name); 170074fe6c29SRuslan Bukin 170174fe6c29SRuslan Bukin/** Free a traced memory image section cache. 170274fe6c29SRuslan Bukin * 170374fe6c29SRuslan Bukin * The \@iscache must have been allocated with pt_iscache_alloc(). 170474fe6c29SRuslan Bukin * The \@iscache must not be used after a successful return. 170574fe6c29SRuslan Bukin */ 170674fe6c29SRuslan Bukinextern pt_export void pt_iscache_free(struct pt_image_section_cache *iscache); 170774fe6c29SRuslan Bukin 170874fe6c29SRuslan Bukin/** Set the image section cache limit. 170974fe6c29SRuslan Bukin * 171074fe6c29SRuslan Bukin * Set the limit for a section cache in bytes. A non-zero limit will keep the 171174fe6c29SRuslan Bukin * least recently used sections mapped until the limit is reached. A limit of 171274fe6c29SRuslan Bukin * zero disables caching. 171374fe6c29SRuslan Bukin * 171474fe6c29SRuslan Bukin * Returns zero on success, a negative pt_error_code otherwise. 171574fe6c29SRuslan Bukin * Returns -pte_invalid if \@iscache is NULL. 171674fe6c29SRuslan Bukin */ 171774fe6c29SRuslan Bukinextern pt_export int 171874fe6c29SRuslan Bukinpt_iscache_set_limit(struct pt_image_section_cache *iscache, uint64_t limit); 171974fe6c29SRuslan Bukin 172074fe6c29SRuslan Bukin/** Get the image section cache name. 172174fe6c29SRuslan Bukin * 172274fe6c29SRuslan Bukin * Returns a pointer to \@iscache's name or NULL if there is no name. 172374fe6c29SRuslan Bukin */ 172474fe6c29SRuslan Bukinextern pt_export const char * 172574fe6c29SRuslan Bukinpt_iscache_name(const struct pt_image_section_cache *iscache); 172674fe6c29SRuslan Bukin 172774fe6c29SRuslan Bukin/** Add a new file section to the traced memory image section cache. 172874fe6c29SRuslan Bukin * 172974fe6c29SRuslan Bukin * Adds a new section consisting of \@size bytes starting at \@offset in 173074fe6c29SRuslan Bukin * \@filename loaded at the virtual address \@vaddr if \@iscache does not 173174fe6c29SRuslan Bukin * already contain such a section. 173274fe6c29SRuslan Bukin * 173374fe6c29SRuslan Bukin * Returns an image section identifier (isid) uniquely identifying that section 173474fe6c29SRuslan Bukin * in \@iscache. 173574fe6c29SRuslan Bukin * 173674fe6c29SRuslan Bukin * The section is silently truncated to match the size of \@filename. 173774fe6c29SRuslan Bukin * 173874fe6c29SRuslan Bukin * Returns a positive isid on success, a negative error code otherwise. 173974fe6c29SRuslan Bukin * 174074fe6c29SRuslan Bukin * Returns -pte_invalid if \@iscache or \@filename is NULL. 174174fe6c29SRuslan Bukin * Returns -pte_invalid if \@offset is too big. 174274fe6c29SRuslan Bukin */ 174374fe6c29SRuslan Bukinextern pt_export int pt_iscache_add_file(struct pt_image_section_cache *iscache, 174474fe6c29SRuslan Bukin const char *filename, uint64_t offset, 174574fe6c29SRuslan Bukin uint64_t size, uint64_t vaddr); 174674fe6c29SRuslan Bukin 174774fe6c29SRuslan Bukin/** Read memory from a cached file section 174874fe6c29SRuslan Bukin * 174974fe6c29SRuslan Bukin * Reads \@size bytes of memory starting at virtual address \@vaddr in the 175074fe6c29SRuslan Bukin * section identified by \@isid in \@iscache into \@buffer. 175174fe6c29SRuslan Bukin * 175274fe6c29SRuslan Bukin * The caller is responsible for allocating a \@buffer of at least \@size bytes. 175374fe6c29SRuslan Bukin * 175474fe6c29SRuslan Bukin * The read request may be truncated if it crosses section boundaries or if 175574fe6c29SRuslan Bukin * \@size is getting too big. We support reading at least 4Kbyte in one chunk 175674fe6c29SRuslan Bukin * unless the read would cross a section boundary. 175774fe6c29SRuslan Bukin * 175874fe6c29SRuslan Bukin * Returns the number of bytes read on success, a negative error code otherwise. 175974fe6c29SRuslan Bukin * 176074fe6c29SRuslan Bukin * Returns -pte_invalid if \@iscache or \@buffer is NULL. 176174fe6c29SRuslan Bukin * Returns -pte_invalid if \@size is zero. 176274fe6c29SRuslan Bukin * Returns -pte_nomap if \@vaddr is not contained in section \@isid. 176374fe6c29SRuslan Bukin * Returns -pte_bad_image if \@iscache does not contain \@isid. 176474fe6c29SRuslan Bukin */ 176574fe6c29SRuslan Bukinextern pt_export int pt_iscache_read(struct pt_image_section_cache *iscache, 176674fe6c29SRuslan Bukin uint8_t *buffer, uint64_t size, int isid, 176774fe6c29SRuslan Bukin uint64_t vaddr); 176874fe6c29SRuslan Bukin 176974fe6c29SRuslan Bukin/** The traced memory image. */ 177074fe6c29SRuslan Bukinstruct pt_image; 177174fe6c29SRuslan Bukin 177274fe6c29SRuslan Bukin 177374fe6c29SRuslan Bukin/** Allocate a traced memory image. 177474fe6c29SRuslan Bukin * 177574fe6c29SRuslan Bukin * An optional \@name may be given to the image. The name string is copied. 177674fe6c29SRuslan Bukin * 177774fe6c29SRuslan Bukin * Returns a new traced memory image on success, NULL otherwise. 177874fe6c29SRuslan Bukin */ 177974fe6c29SRuslan Bukinextern pt_export struct pt_image *pt_image_alloc(const char *name); 178074fe6c29SRuslan Bukin 178174fe6c29SRuslan Bukin/** Free a traced memory image. 178274fe6c29SRuslan Bukin * 178374fe6c29SRuslan Bukin * The \@image must have been allocated with pt_image_alloc(). 178474fe6c29SRuslan Bukin * The \@image must not be used after a successful return. 178574fe6c29SRuslan Bukin */ 178674fe6c29SRuslan Bukinextern pt_export void pt_image_free(struct pt_image *image); 178774fe6c29SRuslan Bukin 178874fe6c29SRuslan Bukin/** Get the image name. 178974fe6c29SRuslan Bukin * 179074fe6c29SRuslan Bukin * Returns a pointer to \@image's name or NULL if there is no name. 179174fe6c29SRuslan Bukin */ 179274fe6c29SRuslan Bukinextern pt_export const char *pt_image_name(const struct pt_image *image); 179374fe6c29SRuslan Bukin 179474fe6c29SRuslan Bukin/** Add a new file section to the traced memory image. 179574fe6c29SRuslan Bukin * 179674fe6c29SRuslan Bukin * Adds \@size bytes starting at \@offset in \@filename. The section is 179774fe6c29SRuslan Bukin * loaded at the virtual address \@vaddr in the address space \@asid. 179874fe6c29SRuslan Bukin * 179974fe6c29SRuslan Bukin * The \@asid may be NULL or (partially) invalid. In that case only the valid 180074fe6c29SRuslan Bukin * fields are considered when comparing with other address-spaces. Use this 180174fe6c29SRuslan Bukin * when tracing a single process or when adding sections to all processes. 180274fe6c29SRuslan Bukin * 180374fe6c29SRuslan Bukin * The section is silently truncated to match the size of \@filename. 180474fe6c29SRuslan Bukin * 180574fe6c29SRuslan Bukin * Existing sections that would overlap with the new section will be shrunk 180674fe6c29SRuslan Bukin * or split. 180774fe6c29SRuslan Bukin * 180874fe6c29SRuslan Bukin * Returns zero on success, a negative error code otherwise. 180974fe6c29SRuslan Bukin * 181074fe6c29SRuslan Bukin * Returns -pte_invalid if \@image or \@filename is NULL. 181174fe6c29SRuslan Bukin * Returns -pte_invalid if \@offset is too big. 181274fe6c29SRuslan Bukin */ 181374fe6c29SRuslan Bukinextern pt_export int pt_image_add_file(struct pt_image *image, 181474fe6c29SRuslan Bukin const char *filename, uint64_t offset, 181574fe6c29SRuslan Bukin uint64_t size, 181674fe6c29SRuslan Bukin const struct pt_asid *asid, 181774fe6c29SRuslan Bukin uint64_t vaddr); 181874fe6c29SRuslan Bukin 181974fe6c29SRuslan Bukin/** Add a section from an image section cache. 182074fe6c29SRuslan Bukin * 182174fe6c29SRuslan Bukin * Add the section from \@iscache identified by \@isid in address space \@asid. 182274fe6c29SRuslan Bukin * 182374fe6c29SRuslan Bukin * Existing sections that would overlap with the new section will be shrunk 182474fe6c29SRuslan Bukin * or split. 182574fe6c29SRuslan Bukin * 182674fe6c29SRuslan Bukin * Returns zero on success, a negative error code otherwise. 182774fe6c29SRuslan Bukin * Returns -pte_invalid if \@image or \@iscache is NULL. 182874fe6c29SRuslan Bukin * Returns -pte_bad_image if \@iscache does not contain \@isid. 182974fe6c29SRuslan Bukin */ 183074fe6c29SRuslan Bukinextern pt_export int pt_image_add_cached(struct pt_image *image, 183174fe6c29SRuslan Bukin struct pt_image_section_cache *iscache, 183274fe6c29SRuslan Bukin int isid, const struct pt_asid *asid); 183374fe6c29SRuslan Bukin 183474fe6c29SRuslan Bukin/** Copy an image. 183574fe6c29SRuslan Bukin * 183674fe6c29SRuslan Bukin * Adds all sections from \@src to \@image. Sections that could not be added 183774fe6c29SRuslan Bukin * will be ignored. 183874fe6c29SRuslan Bukin * 183974fe6c29SRuslan Bukin * Returns the number of ignored sections on success, a negative error code 184074fe6c29SRuslan Bukin * otherwise. 184174fe6c29SRuslan Bukin * 184274fe6c29SRuslan Bukin * Returns -pte_invalid if \@image or \@src is NULL. 184374fe6c29SRuslan Bukin */ 184474fe6c29SRuslan Bukinextern pt_export int pt_image_copy(struct pt_image *image, 184574fe6c29SRuslan Bukin const struct pt_image *src); 184674fe6c29SRuslan Bukin 184774fe6c29SRuslan Bukin/** Remove all sections loaded from a file. 184874fe6c29SRuslan Bukin * 184974fe6c29SRuslan Bukin * Removes all sections loaded from \@filename from the address space \@asid. 185074fe6c29SRuslan Bukin * Specify the same \@asid that was used for adding sections from \@filename. 185174fe6c29SRuslan Bukin * 185274fe6c29SRuslan Bukin * Returns the number of removed sections on success, a negative error code 185374fe6c29SRuslan Bukin * otherwise. 185474fe6c29SRuslan Bukin * 185574fe6c29SRuslan Bukin * Returns -pte_invalid if \@image or \@filename is NULL. 185674fe6c29SRuslan Bukin */ 185774fe6c29SRuslan Bukinextern pt_export int pt_image_remove_by_filename(struct pt_image *image, 185874fe6c29SRuslan Bukin const char *filename, 185974fe6c29SRuslan Bukin const struct pt_asid *asid); 186074fe6c29SRuslan Bukin 186174fe6c29SRuslan Bukin/** Remove all sections loaded into an address space. 186274fe6c29SRuslan Bukin * 186374fe6c29SRuslan Bukin * Removes all sections loaded into \@asid. Specify the same \@asid that was 186474fe6c29SRuslan Bukin * used for adding sections. 186574fe6c29SRuslan Bukin * 186674fe6c29SRuslan Bukin * Returns the number of removed sections on success, a negative error code 186774fe6c29SRuslan Bukin * otherwise. 186874fe6c29SRuslan Bukin * 186974fe6c29SRuslan Bukin * Returns -pte_invalid if \@image is NULL. 187074fe6c29SRuslan Bukin */ 187174fe6c29SRuslan Bukinextern pt_export int pt_image_remove_by_asid(struct pt_image *image, 187274fe6c29SRuslan Bukin const struct pt_asid *asid); 187374fe6c29SRuslan Bukin 187474fe6c29SRuslan Bukin/** A read memory callback function. 187574fe6c29SRuslan Bukin * 187674fe6c29SRuslan Bukin * It shall read \@size bytes of memory from address space \@asid starting 187774fe6c29SRuslan Bukin * at \@ip into \@buffer. 187874fe6c29SRuslan Bukin * 187974fe6c29SRuslan Bukin * It shall return the number of bytes read on success. 188074fe6c29SRuslan Bukin * It shall return a negative pt_error_code otherwise. 188174fe6c29SRuslan Bukin */ 188274fe6c29SRuslan Bukintypedef int (read_memory_callback_t)(uint8_t *buffer, size_t size, 188374fe6c29SRuslan Bukin const struct pt_asid *asid, 188474fe6c29SRuslan Bukin uint64_t ip, void *context); 188574fe6c29SRuslan Bukin 188674fe6c29SRuslan Bukin/** Set the memory callback for the traced memory image. 188774fe6c29SRuslan Bukin * 188874fe6c29SRuslan Bukin * Sets \@callback for reading memory. The callback is used for addresses 188974fe6c29SRuslan Bukin * that are not found in file sections. The \@context argument is passed 189074fe6c29SRuslan Bukin * to \@callback on each use. 189174fe6c29SRuslan Bukin * 189274fe6c29SRuslan Bukin * There can only be one callback at any time. A subsequent call will replace 189374fe6c29SRuslan Bukin * the previous callback. If \@callback is NULL, the callback is removed. 189474fe6c29SRuslan Bukin * 189574fe6c29SRuslan Bukin * Returns -pte_invalid if \@image is NULL. 189674fe6c29SRuslan Bukin */ 189774fe6c29SRuslan Bukinextern pt_export int pt_image_set_callback(struct pt_image *image, 189874fe6c29SRuslan Bukin read_memory_callback_t *callback, 189974fe6c29SRuslan Bukin void *context); 190074fe6c29SRuslan Bukin 190174fe6c29SRuslan Bukin 190274fe6c29SRuslan Bukin 190374fe6c29SRuslan Bukin/* Instruction flow decoder. */ 190474fe6c29SRuslan Bukin 190574fe6c29SRuslan Bukin 190674fe6c29SRuslan Bukin 190774fe6c29SRuslan Bukin/** The instruction class. 190874fe6c29SRuslan Bukin * 190974fe6c29SRuslan Bukin * We provide only a very coarse classification suitable for reconstructing 191074fe6c29SRuslan Bukin * the execution flow. 191174fe6c29SRuslan Bukin */ 191274fe6c29SRuslan Bukinenum pt_insn_class { 191374fe6c29SRuslan Bukin /* The instruction could not be classified. */ 191474fe6c29SRuslan Bukin ptic_error, 191574fe6c29SRuslan Bukin 191674fe6c29SRuslan Bukin /* The instruction is something not listed below. */ 191774fe6c29SRuslan Bukin ptic_other, 191874fe6c29SRuslan Bukin 191974fe6c29SRuslan Bukin /* The instruction is a near (function) call. */ 192074fe6c29SRuslan Bukin ptic_call, 192174fe6c29SRuslan Bukin 192274fe6c29SRuslan Bukin /* The instruction is a near (function) return. */ 192374fe6c29SRuslan Bukin ptic_return, 192474fe6c29SRuslan Bukin 192574fe6c29SRuslan Bukin /* The instruction is a near unconditional jump. */ 192674fe6c29SRuslan Bukin ptic_jump, 192774fe6c29SRuslan Bukin 192874fe6c29SRuslan Bukin /* The instruction is a near conditional jump. */ 192974fe6c29SRuslan Bukin ptic_cond_jump, 193074fe6c29SRuslan Bukin 193174fe6c29SRuslan Bukin /* The instruction is a call-like far transfer. 193274fe6c29SRuslan Bukin * E.g. SYSCALL, SYSENTER, or FAR CALL. 193374fe6c29SRuslan Bukin */ 193474fe6c29SRuslan Bukin ptic_far_call, 193574fe6c29SRuslan Bukin 193674fe6c29SRuslan Bukin /* The instruction is a return-like far transfer. 193774fe6c29SRuslan Bukin * E.g. SYSRET, SYSEXIT, IRET, or FAR RET. 193874fe6c29SRuslan Bukin */ 193974fe6c29SRuslan Bukin ptic_far_return, 194074fe6c29SRuslan Bukin 194174fe6c29SRuslan Bukin /* The instruction is a jump-like far transfer. 194274fe6c29SRuslan Bukin * E.g. FAR JMP. 194374fe6c29SRuslan Bukin */ 194474fe6c29SRuslan Bukin ptic_far_jump, 194574fe6c29SRuslan Bukin 194674fe6c29SRuslan Bukin /* The instruction is a PTWRITE. */ 194774fe6c29SRuslan Bukin ptic_ptwrite 194874fe6c29SRuslan Bukin}; 194974fe6c29SRuslan Bukin 195074fe6c29SRuslan Bukin/** The maximal size of an instruction. */ 195174fe6c29SRuslan Bukinenum { 195274fe6c29SRuslan Bukin pt_max_insn_size = 15 195374fe6c29SRuslan Bukin}; 195474fe6c29SRuslan Bukin 195574fe6c29SRuslan Bukin/** A single traced instruction. */ 195674fe6c29SRuslan Bukinstruct pt_insn { 195774fe6c29SRuslan Bukin /** The virtual address in its process. */ 195874fe6c29SRuslan Bukin uint64_t ip; 195974fe6c29SRuslan Bukin 196074fe6c29SRuslan Bukin /** The image section identifier for the section containing this 196174fe6c29SRuslan Bukin * instruction. 196274fe6c29SRuslan Bukin * 196374fe6c29SRuslan Bukin * A value of zero means that the section did not have an identifier. 196474fe6c29SRuslan Bukin * The section was not added via an image section cache or the memory 196574fe6c29SRuslan Bukin * was read via the read memory callback. 196674fe6c29SRuslan Bukin */ 196774fe6c29SRuslan Bukin int isid; 196874fe6c29SRuslan Bukin 196974fe6c29SRuslan Bukin /** The execution mode. */ 197074fe6c29SRuslan Bukin enum pt_exec_mode mode; 197174fe6c29SRuslan Bukin 197274fe6c29SRuslan Bukin /** A coarse classification. */ 197374fe6c29SRuslan Bukin enum pt_insn_class iclass; 197474fe6c29SRuslan Bukin 197574fe6c29SRuslan Bukin /** The raw bytes. */ 197674fe6c29SRuslan Bukin uint8_t raw[pt_max_insn_size]; 197774fe6c29SRuslan Bukin 197874fe6c29SRuslan Bukin /** The size in bytes. */ 197974fe6c29SRuslan Bukin uint8_t size; 198074fe6c29SRuslan Bukin 198174fe6c29SRuslan Bukin /** A collection of flags giving additional information: 198274fe6c29SRuslan Bukin * 198374fe6c29SRuslan Bukin * - the instruction was executed speculatively. 198474fe6c29SRuslan Bukin */ 198574fe6c29SRuslan Bukin uint32_t speculative:1; 198674fe6c29SRuslan Bukin 198774fe6c29SRuslan Bukin /** - this instruction is truncated in its image section. 198874fe6c29SRuslan Bukin * 198974fe6c29SRuslan Bukin * It starts in the image section identified by \@isid and continues 199074fe6c29SRuslan Bukin * in one or more other sections. 199174fe6c29SRuslan Bukin */ 199274fe6c29SRuslan Bukin uint32_t truncated:1; 199374fe6c29SRuslan Bukin}; 199474fe6c29SRuslan Bukin 199574fe6c29SRuslan Bukin 199674fe6c29SRuslan Bukin/** Allocate an Intel PT instruction flow decoder. 199774fe6c29SRuslan Bukin * 199874fe6c29SRuslan Bukin * The decoder will work on the buffer defined in \@config, it shall contain 199974fe6c29SRuslan Bukin * raw trace data and remain valid for the lifetime of the decoder. 200074fe6c29SRuslan Bukin * 200174fe6c29SRuslan Bukin * The decoder needs to be synchronized before it can be used. 200274fe6c29SRuslan Bukin */ 200374fe6c29SRuslan Bukinextern pt_export struct pt_insn_decoder * 200474fe6c29SRuslan Bukinpt_insn_alloc_decoder(const struct pt_config *config); 200574fe6c29SRuslan Bukin 200674fe6c29SRuslan Bukin/** Free an Intel PT instruction flow decoder. 200774fe6c29SRuslan Bukin * 200874fe6c29SRuslan Bukin * This will destroy the decoder's default image. 200974fe6c29SRuslan Bukin * 201074fe6c29SRuslan Bukin * The \@decoder must not be used after a successful return. 201174fe6c29SRuslan Bukin */ 201274fe6c29SRuslan Bukinextern pt_export void pt_insn_free_decoder(struct pt_insn_decoder *decoder); 201374fe6c29SRuslan Bukin 201474fe6c29SRuslan Bukin/** Synchronize an Intel PT instruction flow decoder. 201574fe6c29SRuslan Bukin * 201674fe6c29SRuslan Bukin * Search for the next synchronization point in forward or backward direction. 201774fe6c29SRuslan Bukin * 201874fe6c29SRuslan Bukin * If \@decoder has not been synchronized, yet, the search is started at the 201974fe6c29SRuslan Bukin * beginning of the trace buffer in case of forward synchronization and at the 202074fe6c29SRuslan Bukin * end of the trace buffer in case of backward synchronization. 202174fe6c29SRuslan Bukin * 202274fe6c29SRuslan Bukin * Returns zero or a positive value on success, a negative error code otherwise. 202374fe6c29SRuslan Bukin * 202474fe6c29SRuslan Bukin * Returns -pte_bad_opc if an unknown packet is encountered. 202574fe6c29SRuslan Bukin * Returns -pte_bad_packet if an unknown packet payload is encountered. 202674fe6c29SRuslan Bukin * Returns -pte_eos if no further synchronization point is found. 202774fe6c29SRuslan Bukin * Returns -pte_invalid if \@decoder is NULL. 202874fe6c29SRuslan Bukin */ 202974fe6c29SRuslan Bukinextern pt_export int pt_insn_sync_forward(struct pt_insn_decoder *decoder); 203074fe6c29SRuslan Bukinextern pt_export int pt_insn_sync_backward(struct pt_insn_decoder *decoder); 203174fe6c29SRuslan Bukin 203274fe6c29SRuslan Bukin/** Manually synchronize an Intel PT instruction flow decoder. 203374fe6c29SRuslan Bukin * 203474fe6c29SRuslan Bukin * Synchronize \@decoder on the syncpoint at \@offset. There must be a PSB 203574fe6c29SRuslan Bukin * packet at \@offset. 203674fe6c29SRuslan Bukin * 203774fe6c29SRuslan Bukin * Returns zero or a positive value on success, a negative error code otherwise. 203874fe6c29SRuslan Bukin * 203974fe6c29SRuslan Bukin * Returns -pte_bad_opc if an unknown packet is encountered. 204074fe6c29SRuslan Bukin * Returns -pte_bad_packet if an unknown packet payload is encountered. 204174fe6c29SRuslan Bukin * Returns -pte_eos if \@offset lies outside of \@decoder's trace buffer. 204274fe6c29SRuslan Bukin * Returns -pte_eos if \@decoder reaches the end of its trace buffer. 204374fe6c29SRuslan Bukin * Returns -pte_invalid if \@decoder is NULL. 204474fe6c29SRuslan Bukin * Returns -pte_nosync if there is no syncpoint at \@offset. 204574fe6c29SRuslan Bukin */ 204674fe6c29SRuslan Bukinextern pt_export int pt_insn_sync_set(struct pt_insn_decoder *decoder, 204774fe6c29SRuslan Bukin uint64_t offset); 204874fe6c29SRuslan Bukin 204974fe6c29SRuslan Bukin/** Get the current decoder position. 205074fe6c29SRuslan Bukin * 205174fe6c29SRuslan Bukin * Fills the current \@decoder position into \@offset. 205274fe6c29SRuslan Bukin * 205374fe6c29SRuslan Bukin * This is useful for reporting errors. 205474fe6c29SRuslan Bukin * 205574fe6c29SRuslan Bukin * Returns zero on success, a negative error code otherwise. 205674fe6c29SRuslan Bukin * 205774fe6c29SRuslan Bukin * Returns -pte_invalid if \@decoder or \@offset is NULL. 205874fe6c29SRuslan Bukin * Returns -pte_nosync if \@decoder is out of sync. 205974fe6c29SRuslan Bukin */ 206074fe6c29SRuslan Bukinextern pt_export int pt_insn_get_offset(const struct pt_insn_decoder *decoder, 206174fe6c29SRuslan Bukin uint64_t *offset); 206274fe6c29SRuslan Bukin 206374fe6c29SRuslan Bukin/** Get the position of the last synchronization point. 206474fe6c29SRuslan Bukin * 206574fe6c29SRuslan Bukin * Fills the last synchronization position into \@offset. 206674fe6c29SRuslan Bukin * 206774fe6c29SRuslan Bukin * Returns zero on success, a negative error code otherwise. 206874fe6c29SRuslan Bukin * 206974fe6c29SRuslan Bukin * Returns -pte_invalid if \@decoder or \@offset is NULL. 207074fe6c29SRuslan Bukin * Returns -pte_nosync if \@decoder is out of sync. 207174fe6c29SRuslan Bukin */ 207274fe6c29SRuslan Bukinextern pt_export int 207374fe6c29SRuslan Bukinpt_insn_get_sync_offset(const struct pt_insn_decoder *decoder, 207474fe6c29SRuslan Bukin uint64_t *offset); 207574fe6c29SRuslan Bukin 207674fe6c29SRuslan Bukin/** Get the traced image. 207774fe6c29SRuslan Bukin * 207874fe6c29SRuslan Bukin * The returned image may be modified as long as no decoder that uses this 207974fe6c29SRuslan Bukin * image is running. 208074fe6c29SRuslan Bukin * 208174fe6c29SRuslan Bukin * Returns a pointer to the traced image the decoder uses for reading memory. 208274fe6c29SRuslan Bukin * Returns NULL if \@decoder is NULL. 208374fe6c29SRuslan Bukin */ 208474fe6c29SRuslan Bukinextern pt_export struct pt_image * 208574fe6c29SRuslan Bukinpt_insn_get_image(struct pt_insn_decoder *decoder); 208674fe6c29SRuslan Bukin 208774fe6c29SRuslan Bukin/** Set the traced image. 208874fe6c29SRuslan Bukin * 208974fe6c29SRuslan Bukin * Sets the image that \@decoder uses for reading memory to \@image. If \@image 209074fe6c29SRuslan Bukin * is NULL, sets the image to \@decoder's default image. 209174fe6c29SRuslan Bukin * 209274fe6c29SRuslan Bukin * Only one image can be active at any time. 209374fe6c29SRuslan Bukin * 209474fe6c29SRuslan Bukin * Returns zero on success, a negative error code otherwise. 209574fe6c29SRuslan Bukin * Return -pte_invalid if \@decoder is NULL. 209674fe6c29SRuslan Bukin */ 209774fe6c29SRuslan Bukinextern pt_export int pt_insn_set_image(struct pt_insn_decoder *decoder, 209874fe6c29SRuslan Bukin struct pt_image *image); 209974fe6c29SRuslan Bukin 210074fe6c29SRuslan Bukin/* Return a pointer to \@decoder's configuration. 210174fe6c29SRuslan Bukin * 210274fe6c29SRuslan Bukin * Returns a non-null pointer on success, NULL if \@decoder is NULL. 210374fe6c29SRuslan Bukin */ 210474fe6c29SRuslan Bukinextern pt_export const struct pt_config * 210574fe6c29SRuslan Bukinpt_insn_get_config(const struct pt_insn_decoder *decoder); 210674fe6c29SRuslan Bukin 210774fe6c29SRuslan Bukin/** Return the current time. 210874fe6c29SRuslan Bukin * 210974fe6c29SRuslan Bukin * On success, provides the time at the last preceding timing packet in \@time. 211074fe6c29SRuslan Bukin * 211174fe6c29SRuslan Bukin * The time is similar to what a rdtsc instruction would return. Depending 211274fe6c29SRuslan Bukin * on the configuration, the time may not be fully accurate. If TSC is not 211374fe6c29SRuslan Bukin * enabled, the time is relative to the last synchronization and can't be used 211474fe6c29SRuslan Bukin * to correlate with other TSC-based time sources. In this case, -pte_no_time 211574fe6c29SRuslan Bukin * is returned and the relative time is provided in \@time. 211674fe6c29SRuslan Bukin * 211774fe6c29SRuslan Bukin * Some timing-related packets may need to be dropped (mostly due to missing 211874fe6c29SRuslan Bukin * calibration or incomplete configuration). To get an idea about the quality 211974fe6c29SRuslan Bukin * of the estimated time, we record the number of dropped MTC and CYC packets. 212074fe6c29SRuslan Bukin * 212174fe6c29SRuslan Bukin * If \@lost_mtc is not NULL, set it to the number of lost MTC packets. 212274fe6c29SRuslan Bukin * If \@lost_cyc is not NULL, set it to the number of lost CYC packets. 212374fe6c29SRuslan Bukin * 212474fe6c29SRuslan Bukin * Returns zero on success, a negative error code otherwise. 212574fe6c29SRuslan Bukin * 212674fe6c29SRuslan Bukin * Returns -pte_invalid if \@decoder or \@time is NULL. 212774fe6c29SRuslan Bukin * Returns -pte_no_time if there has not been a TSC packet. 212874fe6c29SRuslan Bukin */ 212974fe6c29SRuslan Bukinextern pt_export int pt_insn_time(struct pt_insn_decoder *decoder, 213074fe6c29SRuslan Bukin uint64_t *time, uint32_t *lost_mtc, 213174fe6c29SRuslan Bukin uint32_t *lost_cyc); 213274fe6c29SRuslan Bukin 213374fe6c29SRuslan Bukin/** Return the current core bus ratio. 213474fe6c29SRuslan Bukin * 213574fe6c29SRuslan Bukin * On success, provides the current core:bus ratio in \@cbr. The ratio is 213674fe6c29SRuslan Bukin * defined as core cycles per bus clock cycle. 213774fe6c29SRuslan Bukin * 213874fe6c29SRuslan Bukin * Returns zero on success, a negative error code otherwise. 213974fe6c29SRuslan Bukin * 214074fe6c29SRuslan Bukin * Returns -pte_invalid if \@decoder or \@cbr is NULL. 214174fe6c29SRuslan Bukin * Returns -pte_no_cbr if there has not been a CBR packet. 214274fe6c29SRuslan Bukin */ 214374fe6c29SRuslan Bukinextern pt_export int pt_insn_core_bus_ratio(struct pt_insn_decoder *decoder, 214474fe6c29SRuslan Bukin uint32_t *cbr); 214574fe6c29SRuslan Bukin 214674fe6c29SRuslan Bukin/** Return the current address space identifier. 214774fe6c29SRuslan Bukin * 214874fe6c29SRuslan Bukin * On success, provides the current address space identifier in \@asid. 214974fe6c29SRuslan Bukin * 215074fe6c29SRuslan Bukin * The \@size argument must be set to sizeof(struct pt_asid). At most \@size 215174fe6c29SRuslan Bukin * bytes will be copied and \@asid->size will be set to the actual size of the 215274fe6c29SRuslan Bukin * provided address space identifier. 215374fe6c29SRuslan Bukin * 215474fe6c29SRuslan Bukin * Returns zero on success, a negative error code otherwise. 215574fe6c29SRuslan Bukin * 215674fe6c29SRuslan Bukin * Returns -pte_invalid if \@decoder or \@asid is NULL. 215774fe6c29SRuslan Bukin */ 215874fe6c29SRuslan Bukinextern pt_export int pt_insn_asid(const struct pt_insn_decoder *decoder, 215974fe6c29SRuslan Bukin struct pt_asid *asid, size_t size); 216074fe6c29SRuslan Bukin 216174fe6c29SRuslan Bukin/** Determine the next instruction. 216274fe6c29SRuslan Bukin * 216374fe6c29SRuslan Bukin * On success, provides the next instruction in execution order in \@insn. 216474fe6c29SRuslan Bukin * 216574fe6c29SRuslan Bukin * The \@size argument must be set to sizeof(struct pt_insn). 216674fe6c29SRuslan Bukin * 216774fe6c29SRuslan Bukin * Returns a non-negative pt_status_flag bit-vector on success, a negative error 216874fe6c29SRuslan Bukin * code otherwise. 216974fe6c29SRuslan Bukin * 217074fe6c29SRuslan Bukin * Returns pts_eos to indicate the end of the trace stream. Subsequent calls 217174fe6c29SRuslan Bukin * to pt_insn_next() will continue to return pts_eos until trace is required 217274fe6c29SRuslan Bukin * to determine the next instruction. 217374fe6c29SRuslan Bukin * 217474fe6c29SRuslan Bukin * Returns -pte_bad_context if the decoder encountered an unexpected packet. 217574fe6c29SRuslan Bukin * Returns -pte_bad_opc if the decoder encountered unknown packets. 217674fe6c29SRuslan Bukin * Returns -pte_bad_packet if the decoder encountered unknown packet payloads. 217774fe6c29SRuslan Bukin * Returns -pte_bad_query if the decoder got out of sync. 217874fe6c29SRuslan Bukin * Returns -pte_eos if decoding reached the end of the Intel PT buffer. 217974fe6c29SRuslan Bukin * Returns -pte_invalid if \@decoder or \@insn is NULL. 218074fe6c29SRuslan Bukin * Returns -pte_nomap if the memory at the instruction address can't be read. 218174fe6c29SRuslan Bukin * Returns -pte_nosync if \@decoder is out of sync. 218274fe6c29SRuslan Bukin */ 218374fe6c29SRuslan Bukinextern pt_export int pt_insn_next(struct pt_insn_decoder *decoder, 218474fe6c29SRuslan Bukin struct pt_insn *insn, size_t size); 218574fe6c29SRuslan Bukin 218674fe6c29SRuslan Bukin/** Get the next pending event. 218774fe6c29SRuslan Bukin * 218874fe6c29SRuslan Bukin * On success, provides the next event in \@event and updates \@decoder. 218974fe6c29SRuslan Bukin * 219074fe6c29SRuslan Bukin * The \@size argument must be set to sizeof(struct pt_event). 219174fe6c29SRuslan Bukin * 219274fe6c29SRuslan Bukin * Returns a non-negative pt_status_flag bit-vector on success, a negative error 219374fe6c29SRuslan Bukin * code otherwise. 219474fe6c29SRuslan Bukin * 219574fe6c29SRuslan Bukin * Returns -pte_bad_query if there is no event. 219674fe6c29SRuslan Bukin * Returns -pte_invalid if \@decoder or \@event is NULL. 219774fe6c29SRuslan Bukin * Returns -pte_invalid if \@size is too small. 219874fe6c29SRuslan Bukin */ 219974fe6c29SRuslan Bukinextern pt_export int pt_insn_event(struct pt_insn_decoder *decoder, 220074fe6c29SRuslan Bukin struct pt_event *event, size_t size); 220174fe6c29SRuslan Bukin 220274fe6c29SRuslan Bukin 220374fe6c29SRuslan Bukin 220474fe6c29SRuslan Bukin/* Block decoder. */ 220574fe6c29SRuslan Bukin 220674fe6c29SRuslan Bukin 220774fe6c29SRuslan Bukin 220874fe6c29SRuslan Bukin/** A block of instructions. 220974fe6c29SRuslan Bukin * 221074fe6c29SRuslan Bukin * Instructions in this block are executed sequentially but are not necessarily 221174fe6c29SRuslan Bukin * contiguous in memory. Users are expected to follow direct branches. 221274fe6c29SRuslan Bukin */ 221374fe6c29SRuslan Bukinstruct pt_block { 221474fe6c29SRuslan Bukin /** The IP of the first instruction in this block. */ 221574fe6c29SRuslan Bukin uint64_t ip; 221674fe6c29SRuslan Bukin 221774fe6c29SRuslan Bukin /** The IP of the last instruction in this block. 221874fe6c29SRuslan Bukin * 221974fe6c29SRuslan Bukin * This can be used for error-detection. 222074fe6c29SRuslan Bukin */ 222174fe6c29SRuslan Bukin uint64_t end_ip; 222274fe6c29SRuslan Bukin 222374fe6c29SRuslan Bukin /** The image section that contains the instructions in this block. 222474fe6c29SRuslan Bukin * 222574fe6c29SRuslan Bukin * A value of zero means that the section did not have an identifier. 222674fe6c29SRuslan Bukin * The section was not added via an image section cache or the memory 222774fe6c29SRuslan Bukin * was read via the read memory callback. 222874fe6c29SRuslan Bukin */ 222974fe6c29SRuslan Bukin int isid; 223074fe6c29SRuslan Bukin 223174fe6c29SRuslan Bukin /** The execution mode for all instructions in this block. */ 223274fe6c29SRuslan Bukin enum pt_exec_mode mode; 223374fe6c29SRuslan Bukin 223474fe6c29SRuslan Bukin /** The instruction class for the last instruction in this block. 223574fe6c29SRuslan Bukin * 223674fe6c29SRuslan Bukin * This field may be set to ptic_error to indicate that the instruction 223774fe6c29SRuslan Bukin * class is not available. The block decoder may choose to not provide 223874fe6c29SRuslan Bukin * the instruction class in some cases for performance reasons. 223974fe6c29SRuslan Bukin */ 224074fe6c29SRuslan Bukin enum pt_insn_class iclass; 224174fe6c29SRuslan Bukin 224274fe6c29SRuslan Bukin /** The number of instructions in this block. */ 224374fe6c29SRuslan Bukin uint16_t ninsn; 224474fe6c29SRuslan Bukin 224574fe6c29SRuslan Bukin /** The raw bytes of the last instruction in this block in case the 224674fe6c29SRuslan Bukin * instruction does not fit entirely into this block's section. 224774fe6c29SRuslan Bukin * 224874fe6c29SRuslan Bukin * This field is only valid if \@truncated is set. 224974fe6c29SRuslan Bukin */ 225074fe6c29SRuslan Bukin uint8_t raw[pt_max_insn_size]; 225174fe6c29SRuslan Bukin 225274fe6c29SRuslan Bukin /** The size of the last instruction in this block in bytes. 225374fe6c29SRuslan Bukin * 225474fe6c29SRuslan Bukin * This field is only valid if \@truncated is set. 225574fe6c29SRuslan Bukin */ 225674fe6c29SRuslan Bukin uint8_t size; 225774fe6c29SRuslan Bukin 225874fe6c29SRuslan Bukin /** A collection of flags giving additional information about the 225974fe6c29SRuslan Bukin * instructions in this block. 226074fe6c29SRuslan Bukin * 226174fe6c29SRuslan Bukin * - all instructions in this block were executed speculatively. 226274fe6c29SRuslan Bukin */ 226374fe6c29SRuslan Bukin uint32_t speculative:1; 226474fe6c29SRuslan Bukin 226574fe6c29SRuslan Bukin /** - the last instruction in this block is truncated. 226674fe6c29SRuslan Bukin * 226774fe6c29SRuslan Bukin * It starts in this block's section but continues in one or more 226874fe6c29SRuslan Bukin * other sections depending on how fragmented the memory image is. 226974fe6c29SRuslan Bukin * 227074fe6c29SRuslan Bukin * The raw bytes for the last instruction are provided in \@raw and 227174fe6c29SRuslan Bukin * its size in \@size in this case. 227274fe6c29SRuslan Bukin */ 227374fe6c29SRuslan Bukin uint32_t truncated:1; 227474fe6c29SRuslan Bukin}; 227574fe6c29SRuslan Bukin 227674fe6c29SRuslan Bukin/** Allocate an Intel PT block decoder. 227774fe6c29SRuslan Bukin * 227874fe6c29SRuslan Bukin * The decoder will work on the buffer defined in \@config, it shall contain 227974fe6c29SRuslan Bukin * raw trace data and remain valid for the lifetime of the decoder. 228074fe6c29SRuslan Bukin * 228174fe6c29SRuslan Bukin * The decoder needs to be synchronized before it can be used. 228274fe6c29SRuslan Bukin */ 228374fe6c29SRuslan Bukinextern pt_export struct pt_block_decoder * 228474fe6c29SRuslan Bukinpt_blk_alloc_decoder(const struct pt_config *config); 228574fe6c29SRuslan Bukin 228674fe6c29SRuslan Bukin/** Free an Intel PT block decoder. 228774fe6c29SRuslan Bukin * 228874fe6c29SRuslan Bukin * This will destroy the decoder's default image. 228974fe6c29SRuslan Bukin * 229074fe6c29SRuslan Bukin * The \@decoder must not be used after a successful return. 229174fe6c29SRuslan Bukin */ 229274fe6c29SRuslan Bukinextern pt_export void pt_blk_free_decoder(struct pt_block_decoder *decoder); 229374fe6c29SRuslan Bukin 229474fe6c29SRuslan Bukin/** Synchronize an Intel PT block decoder. 229574fe6c29SRuslan Bukin * 229674fe6c29SRuslan Bukin * Search for the next synchronization point in forward or backward direction. 229774fe6c29SRuslan Bukin * 229874fe6c29SRuslan Bukin * If \@decoder has not been synchronized, yet, the search is started at the 229974fe6c29SRuslan Bukin * beginning of the trace buffer in case of forward synchronization and at the 230074fe6c29SRuslan Bukin * end of the trace buffer in case of backward synchronization. 230174fe6c29SRuslan Bukin * 230274fe6c29SRuslan Bukin * Returns zero or a positive value on success, a negative error code otherwise. 230374fe6c29SRuslan Bukin * 230474fe6c29SRuslan Bukin * Returns -pte_bad_opc if an unknown packet is encountered. 230574fe6c29SRuslan Bukin * Returns -pte_bad_packet if an unknown packet payload is encountered. 230674fe6c29SRuslan Bukin * Returns -pte_eos if no further synchronization point is found. 230774fe6c29SRuslan Bukin * Returns -pte_invalid if \@decoder is NULL. 230874fe6c29SRuslan Bukin */ 230974fe6c29SRuslan Bukinextern pt_export int pt_blk_sync_forward(struct pt_block_decoder *decoder); 231074fe6c29SRuslan Bukinextern pt_export int pt_blk_sync_backward(struct pt_block_decoder *decoder); 231174fe6c29SRuslan Bukin 231274fe6c29SRuslan Bukin/** Manually synchronize an Intel PT block decoder. 231374fe6c29SRuslan Bukin * 231474fe6c29SRuslan Bukin * Synchronize \@decoder on the syncpoint at \@offset. There must be a PSB 231574fe6c29SRuslan Bukin * packet at \@offset. 231674fe6c29SRuslan Bukin * 231774fe6c29SRuslan Bukin * Returns zero or a positive value on success, a negative error code otherwise. 231874fe6c29SRuslan Bukin * 231974fe6c29SRuslan Bukin * Returns -pte_bad_opc if an unknown packet is encountered. 232074fe6c29SRuslan Bukin * Returns -pte_bad_packet if an unknown packet payload is encountered. 232174fe6c29SRuslan Bukin * Returns -pte_eos if \@offset lies outside of \@decoder's trace buffer. 232274fe6c29SRuslan Bukin * Returns -pte_eos if \@decoder reaches the end of its trace buffer. 232374fe6c29SRuslan Bukin * Returns -pte_invalid if \@decoder is NULL. 232474fe6c29SRuslan Bukin * Returns -pte_nosync if there is no syncpoint at \@offset. 232574fe6c29SRuslan Bukin */ 232674fe6c29SRuslan Bukinextern pt_export int pt_blk_sync_set(struct pt_block_decoder *decoder, 232774fe6c29SRuslan Bukin uint64_t offset); 232874fe6c29SRuslan Bukin 232974fe6c29SRuslan Bukin/** Get the current decoder position. 233074fe6c29SRuslan Bukin * 233174fe6c29SRuslan Bukin * Fills the current \@decoder position into \@offset. 233274fe6c29SRuslan Bukin * 233374fe6c29SRuslan Bukin * This is useful for reporting errors. 233474fe6c29SRuslan Bukin * 233574fe6c29SRuslan Bukin * Returns zero on success, a negative error code otherwise. 233674fe6c29SRuslan Bukin * 233774fe6c29SRuslan Bukin * Returns -pte_invalid if \@decoder or \@offset is NULL. 233874fe6c29SRuslan Bukin * Returns -pte_nosync if \@decoder is out of sync. 233974fe6c29SRuslan Bukin */ 234074fe6c29SRuslan Bukinextern pt_export int pt_blk_get_offset(const struct pt_block_decoder *decoder, 234174fe6c29SRuslan Bukin uint64_t *offset); 234274fe6c29SRuslan Bukin 234374fe6c29SRuslan Bukin/** Get the position of the last synchronization point. 234474fe6c29SRuslan Bukin * 234574fe6c29SRuslan Bukin * Fills the last synchronization position into \@offset. 234674fe6c29SRuslan Bukin * 234774fe6c29SRuslan Bukin * Returns zero on success, a negative error code otherwise. 234874fe6c29SRuslan Bukin * 234974fe6c29SRuslan Bukin * Returns -pte_invalid if \@decoder or \@offset is NULL. 235074fe6c29SRuslan Bukin * Returns -pte_nosync if \@decoder is out of sync. 235174fe6c29SRuslan Bukin */ 235274fe6c29SRuslan Bukinextern pt_export int 235374fe6c29SRuslan Bukinpt_blk_get_sync_offset(const struct pt_block_decoder *decoder, 235474fe6c29SRuslan Bukin uint64_t *offset); 235574fe6c29SRuslan Bukin 235674fe6c29SRuslan Bukin/** Get the traced image. 235774fe6c29SRuslan Bukin * 235874fe6c29SRuslan Bukin * The returned image may be modified as long as \@decoder is not running. 235974fe6c29SRuslan Bukin * 236074fe6c29SRuslan Bukin * Returns a pointer to the traced image \@decoder uses for reading memory. 236174fe6c29SRuslan Bukin * Returns NULL if \@decoder is NULL. 236274fe6c29SRuslan Bukin */ 236374fe6c29SRuslan Bukinextern pt_export struct pt_image * 236474fe6c29SRuslan Bukinpt_blk_get_image(struct pt_block_decoder *decoder); 236574fe6c29SRuslan Bukin 236674fe6c29SRuslan Bukin/** Set the traced image. 236774fe6c29SRuslan Bukin * 236874fe6c29SRuslan Bukin * Sets the image that \@decoder uses for reading memory to \@image. If \@image 236974fe6c29SRuslan Bukin * is NULL, sets the image to \@decoder's default image. 237074fe6c29SRuslan Bukin * 237174fe6c29SRuslan Bukin * Only one image can be active at any time. 237274fe6c29SRuslan Bukin * 237374fe6c29SRuslan Bukin * Returns zero on success, a negative error code otherwise. 237474fe6c29SRuslan Bukin * Return -pte_invalid if \@decoder is NULL. 237574fe6c29SRuslan Bukin */ 237674fe6c29SRuslan Bukinextern pt_export int pt_blk_set_image(struct pt_block_decoder *decoder, 237774fe6c29SRuslan Bukin struct pt_image *image); 237874fe6c29SRuslan Bukin 237974fe6c29SRuslan Bukin/* Return a pointer to \@decoder's configuration. 238074fe6c29SRuslan Bukin * 238174fe6c29SRuslan Bukin * Returns a non-null pointer on success, NULL if \@decoder is NULL. 238274fe6c29SRuslan Bukin */ 238374fe6c29SRuslan Bukinextern pt_export const struct pt_config * 238474fe6c29SRuslan Bukinpt_blk_get_config(const struct pt_block_decoder *decoder); 238574fe6c29SRuslan Bukin 238674fe6c29SRuslan Bukin/** Return the current time. 238774fe6c29SRuslan Bukin * 238874fe6c29SRuslan Bukin * On success, provides the time at the last preceding timing packet in \@time. 238974fe6c29SRuslan Bukin * 239074fe6c29SRuslan Bukin * The time is similar to what a rdtsc instruction would return. Depending 239174fe6c29SRuslan Bukin * on the configuration, the time may not be fully accurate. If TSC is not 239274fe6c29SRuslan Bukin * enabled, the time is relative to the last synchronization and can't be used 239374fe6c29SRuslan Bukin * to correlate with other TSC-based time sources. In this case, -pte_no_time 239474fe6c29SRuslan Bukin * is returned and the relative time is provided in \@time. 239574fe6c29SRuslan Bukin * 239674fe6c29SRuslan Bukin * Some timing-related packets may need to be dropped (mostly due to missing 239774fe6c29SRuslan Bukin * calibration or incomplete configuration). To get an idea about the quality 239874fe6c29SRuslan Bukin * of the estimated time, we record the number of dropped MTC and CYC packets. 239974fe6c29SRuslan Bukin * 240074fe6c29SRuslan Bukin * If \@lost_mtc is not NULL, set it to the number of lost MTC packets. 240174fe6c29SRuslan Bukin * If \@lost_cyc is not NULL, set it to the number of lost CYC packets. 240274fe6c29SRuslan Bukin * 240374fe6c29SRuslan Bukin * Returns zero on success, a negative error code otherwise. 240474fe6c29SRuslan Bukin * 240574fe6c29SRuslan Bukin * Returns -pte_invalid if \@decoder or \@time is NULL. 240674fe6c29SRuslan Bukin * Returns -pte_no_time if there has not been a TSC packet. 240774fe6c29SRuslan Bukin */ 240874fe6c29SRuslan Bukinextern pt_export int pt_blk_time(struct pt_block_decoder *decoder, 240974fe6c29SRuslan Bukin uint64_t *time, uint32_t *lost_mtc, 241074fe6c29SRuslan Bukin uint32_t *lost_cyc); 241174fe6c29SRuslan Bukin 241274fe6c29SRuslan Bukin/** Return the current core bus ratio. 241374fe6c29SRuslan Bukin * 241474fe6c29SRuslan Bukin * On success, provides the current core:bus ratio in \@cbr. The ratio is 241574fe6c29SRuslan Bukin * defined as core cycles per bus clock cycle. 241674fe6c29SRuslan Bukin * 241774fe6c29SRuslan Bukin * Returns zero on success, a negative error code otherwise. 241874fe6c29SRuslan Bukin * 241974fe6c29SRuslan Bukin * Returns -pte_invalid if \@decoder or \@cbr is NULL. 242074fe6c29SRuslan Bukin * Returns -pte_no_cbr if there has not been a CBR packet. 242174fe6c29SRuslan Bukin */ 242274fe6c29SRuslan Bukinextern pt_export int pt_blk_core_bus_ratio(struct pt_block_decoder *decoder, 242374fe6c29SRuslan Bukin uint32_t *cbr); 242474fe6c29SRuslan Bukin 242574fe6c29SRuslan Bukin/** Return the current address space identifier. 242674fe6c29SRuslan Bukin * 242774fe6c29SRuslan Bukin * On success, provides the current address space identifier in \@asid. 242874fe6c29SRuslan Bukin * 242974fe6c29SRuslan Bukin * The \@size argument must be set to sizeof(struct pt_asid). At most \@size 243074fe6c29SRuslan Bukin * bytes will be copied and \@asid->size will be set to the actual size of the 243174fe6c29SRuslan Bukin * provided address space identifier. 243274fe6c29SRuslan Bukin * 243374fe6c29SRuslan Bukin * Returns zero on success, a negative error code otherwise. 243474fe6c29SRuslan Bukin * 243574fe6c29SRuslan Bukin * Returns -pte_invalid if \@decoder or \@asid is NULL. 243674fe6c29SRuslan Bukin */ 243774fe6c29SRuslan Bukinextern pt_export int pt_blk_asid(const struct pt_block_decoder *decoder, 243874fe6c29SRuslan Bukin struct pt_asid *asid, size_t size); 243974fe6c29SRuslan Bukin 244074fe6c29SRuslan Bukin/** Determine the next block of instructions. 244174fe6c29SRuslan Bukin * 244274fe6c29SRuslan Bukin * On success, provides the next block of instructions in execution order in 244374fe6c29SRuslan Bukin * \@block. 244474fe6c29SRuslan Bukin * 244574fe6c29SRuslan Bukin * The \@size argument must be set to sizeof(struct pt_block). 244674fe6c29SRuslan Bukin * 244774fe6c29SRuslan Bukin * Returns a non-negative pt_status_flag bit-vector on success, a negative error 244874fe6c29SRuslan Bukin * code otherwise. 244974fe6c29SRuslan Bukin * 245074fe6c29SRuslan Bukin * Returns pts_eos to indicate the end of the trace stream. Subsequent calls 245174fe6c29SRuslan Bukin * to pt_block_next() will continue to return pts_eos until trace is required 245274fe6c29SRuslan Bukin * to determine the next instruction. 245374fe6c29SRuslan Bukin * 245474fe6c29SRuslan Bukin * Returns -pte_bad_context if the decoder encountered an unexpected packet. 245574fe6c29SRuslan Bukin * Returns -pte_bad_opc if the decoder encountered unknown packets. 245674fe6c29SRuslan Bukin * Returns -pte_bad_packet if the decoder encountered unknown packet payloads. 245774fe6c29SRuslan Bukin * Returns -pte_bad_query if the decoder got out of sync. 245874fe6c29SRuslan Bukin * Returns -pte_eos if decoding reached the end of the Intel PT buffer. 245974fe6c29SRuslan Bukin * Returns -pte_invalid if \@decoder or \@block is NULL. 246074fe6c29SRuslan Bukin * Returns -pte_nomap if the memory at the instruction address can't be read. 246174fe6c29SRuslan Bukin * Returns -pte_nosync if \@decoder is out of sync. 246274fe6c29SRuslan Bukin */ 246374fe6c29SRuslan Bukinextern pt_export int pt_blk_next(struct pt_block_decoder *decoder, 246474fe6c29SRuslan Bukin struct pt_block *block, size_t size); 246574fe6c29SRuslan Bukin 246674fe6c29SRuslan Bukin/** Get the next pending event. 246774fe6c29SRuslan Bukin * 246874fe6c29SRuslan Bukin * On success, provides the next event in \@event and updates \@decoder. 246974fe6c29SRuslan Bukin * 247074fe6c29SRuslan Bukin * The \@size argument must be set to sizeof(struct pt_event). 247174fe6c29SRuslan Bukin * 247274fe6c29SRuslan Bukin * Returns a non-negative pt_status_flag bit-vector on success, a negative error 247374fe6c29SRuslan Bukin * code otherwise. 247474fe6c29SRuslan Bukin * 247574fe6c29SRuslan Bukin * Returns -pte_bad_query if there is no event. 247674fe6c29SRuslan Bukin * Returns -pte_invalid if \@decoder or \@event is NULL. 247774fe6c29SRuslan Bukin * Returns -pte_invalid if \@size is too small. 247874fe6c29SRuslan Bukin */ 247974fe6c29SRuslan Bukinextern pt_export int pt_blk_event(struct pt_block_decoder *decoder, 248074fe6c29SRuslan Bukin struct pt_event *event, size_t size); 248174fe6c29SRuslan Bukin 248274fe6c29SRuslan Bukin#ifdef __cplusplus 248374fe6c29SRuslan Bukin} 248474fe6c29SRuslan Bukin#endif 248574fe6c29SRuslan Bukin 248674fe6c29SRuslan Bukin#endif /* INTEL_PT_H */ 2487