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