Projects
Mega:23.09
libipt
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 3
View file
_service:tar_scm:libipt.spec
Changed
@@ -1,6 +1,6 @@ Name: libipt -Version: 2.0.5 -Release: 2 +Version: 2.1 +Release: 1 Summary: Intel(R) Processor Trace Decoder Library License: BSD URL: https://github.com/intel/libipt @@ -51,6 +51,14 @@ %{_libdir}/%{name}.so %changelog +* Thu Jan 25 2024 liuchao <liuchao173@huawei.com> - 2.1-1 +- Upgrade to 2.1: + - a new tool 'ptseg' for finding the PSB segment for a given offset. + - a new layer 'evt' representing the trace as a list of events. + - event tracing (cfe and evd packets). + - C11 threads, if available. + - Bug fixes and support for latest processors. + * Thu Feb 16 2023 Wenlong Zhang<zhangwenlong@loongson.cn> - 2.0.5-2 - Add loongarch64 support
View file
_service
Changed
@@ -2,7 +2,7 @@ <service name="tar_scm"> <param name="url">git@gitee.com:src-openeuler/libipt.git</param> <param name="scm">git</param> - <param name="revision">openEuler-23.09</param> + <param name="revision">master</param> <param name="exclude">*</param> <param name="extract">*</param> </service>
View file
_service:tar_scm:v2.0.5.tar.gz/doc/man/pt_qry_event.3.md
Deleted
@@ -1,291 +0,0 @@ -% PT_QRY_EVENT(3) - -<!--- - ! Copyright (c) 2015-2022, Intel Corporation - ! - ! Redistribution and use in source and binary forms, with or without - ! modification, are permitted provided that the following conditions are met: - ! - ! * Redistributions of source code must retain the above copyright notice, - ! this list of conditions and the following disclaimer. - ! * Redistributions in binary form must reproduce the above copyright notice, - ! this list of conditions and the following disclaimer in the documentation - ! and/or other materials provided with the distribution. - ! * Neither the name of Intel Corporation nor the names of its contributors - ! may be used to endorse or promote products derived from this software - ! without specific prior written permission. - ! - ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - ! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - ! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - ! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - ! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - ! POSSIBILITY OF SUCH DAMAGE. - !--> - -# NAME - -pt_qry_event, pt_insn_event, pt_blk_event - query an Intel(R) Processor Trace -decoder for an asynchronous event - - -# SYNOPSIS - -| **\#include `<intel-pt.h>`** -| -| **int pt_qry_event(struct pt_query_decoder \**decoder*,** -| **struct pt_event \**event*, size_t *size*);** -| -| **int pt_insn_event(struct pt_insn_decoder \**decoder*,** -| **struct pt_event \**event*, size_t *size*);** -| -| **int pt_blk_event(struct pt_block_decoder \**decoder*,** -| **struct pt_event \**event*, size_t *size*);** - -Link with *-lipt*. - - -# DESCRIPTION - -**pt_qry_event**(), **pt_insn_event**(), and **pt_blk_event**() provide the next -pending asynchronous event in *decoder*'s Intel Processor Trace (Intel PT) -decode in the *pt_event* object pointed to by the *event* argument. - -The *size* argument must be set to *sizeof(struct pt_event)*. The function will -provide at most *size* bytes of the *pt_event* structure. A newer decoder -library may provide event types that are not yet defined. Those events may be -truncated. - -On success, detailed information about the event is provided in the *pt_event* -object pointed to by the *event* argument. The *pt_event* structure is declared -as: - -~~~{.c} -/** An event. */ -struct pt_event { - /** The type of the event. */ - enum pt_event_type type; - - /** A flag indicating that the event IP has been - * suppressed. - */ - uint32_t ip_suppressed:1; - - /** A flag indicating that the event is for status update. */ - uint32_t status_update:1; - - /** A flag indicating that the event has timing - * information. - */ - uint32_t has_tsc:1; - - /** The time stamp count of the event. - * - * This field is only valid if \@has_tsc is set. - */ - uint64_t tsc; - - /** The number of lost mtc and cyc packets. - * - * This gives an idea about the quality of the \@tsc. The - * more packets were dropped, the less precise timing is. - */ - uint32_t lost_mtc; - uint32_t lost_cyc; - - /* Reserved space for future extensions. */ - uint64_t reserved2; - - /** Event specific data. */ - union { - /** Event: enabled. */ - struct { - /** The address at which tracing resumes. */ - uint64_t ip; - - /** A flag indicating that tracing resumes from the IP - * at which tracing had been disabled before. - */ - uint32_t resumed:1; - } enabled; - - /** Event: disabled. */ - struct { - /** The destination of the first branch inside a - * filtered area. - * - * This field is not valid if \@ip_suppressed is set. - */ - uint64_t ip; - - /* The exact source ip needs to be determined using - * disassembly and the filter configuration. - */ - } disabled; - - ... - } variant; -}; -~~~ - -See the *intel-pt.h* header file for more detail. The common fields of the -*pt_event* structure are described in more detail below: - -type -: The type of the event as a *pt_event_type* enumeration, which is declared - as: - -~~~{.c} -/** Event types. */ -enum pt_event_type { - /* Tracing has been enabled/disabled. */ - ptev_enabled, - ptev_disabled, - - /* Tracing has been disabled asynchronously. */ - ptev_async_disabled, - - /* An asynchronous branch, e.g. interrupt. */ - ptev_async_branch, - - /* A synchronous paging event. */ - ptev_paging, - - /* An asynchronous paging event. */ - ptev_async_paging, - - /* Trace overflow. */ - ptev_overflow, - - /* An execution mode change. */ - ptev_exec_mode, - - /* A transactional execution state change. */ - ptev_tsx, - - /* Trace Stop. */ - ptev_stop, - - /* A synchronous vmcs event. */ - ptev_vmcs, - - /* An asynchronous vmcs event. */ - ptev_async_vmcs, - - /* Execution has stopped. */ - ptev_exstop, - - /* An MWAIT operation completed. */ - ptev_mwait, - - /* A power state was entered. */ - ptev_pwre, - - /* A power state was exited. */ - ptev_pwrx, - - /* A PTWRITE event. */ - ptev_ptwrite, - - /* A timing event. */ - ptev_tick, - - /* A core:bus ratio event. */ - ptev_cbr, - - /* A maintenance event. */ - ptev_mnt -}; -~~~ - -ip_suppressed -: A flag indicating whether the *ip* field in the event-dependent part is not - valid because the value has been suppressed in the trace. - -status_update -: A flag indicating whether the event is for updating the decoder's status. - Status update events originate from Intel PT packets in PSB+. - -has_tsc -: A flag indicating that the event's timing-related fields *tsc*, *lost_mtc*, - and *lost_cyc* are valid. - -tsc -: The last time stamp count before the event. Depending on the timing - configuration, the timestamp can be more or less precise. For - cycle-accurate tracing, event packets are typically CYC-eligible so the - timestamp should be cycle-accurate. - -lost_mtc, lost_cyc -: The number of lost MTC and CYC updates. An update is lost if the decoder - was not able to process an MTC or CYC packet due to missing information. - This can be either missing calibration or missing configuration information. - The number of lost MTC and CYC updates gives a rough idea about the quality - of the *tsc* field. - -variant -: This field contains event-specific information. See the *intel-pt.h* header - file for details. - - -# RETURN VALUE - -**pt_qry_event**(), **pt_insn_event**(), and **pt_blk_event**() return zero or a -*positive value on success or a negative pt_error_code* enumeration constant in -*case of an error. - -On success, a bit-vector of *pt_status_flag* enumeration constants is returned. -The *pt_status_flag* enumeration is declared as: - -~~~{.c} -/** Decoder status flags. */ -enum pt_status_flag { - /** There is an event pending. */ - pts_event_pending = 1 << 0, - - /** The address has been suppressed. */ - pts_ip_suppressed = 1 << 1, - - /** There is no more trace data available. */ - pts_eos = 1 << 2 -}; -~~~ - - -# ERRORS - -pte_invalid -: The *decoder* or *event* argument is NULL or the *size* argument is too - small. - -pte_eos -: Decode reached the end of the trace stream. - -pte_nosync -: The decoder has not been synchronized onto the trace stream. Use - **pt_qry_sync_forward**(3), **pt_qry_sync_backward**(3), or - **pt_qry_sync_set**(3) to synchronize *decoder*. - -pte_bad_opc -: The decoder encountered an unsupported Intel PT packet opcode. - -pte_bad_packet -: The decoder encountered an unsupported Intel PT packet payload. - -pte_bad_query -: The query does not match the data provided in the Intel PT stream. Based on - the trace, the decoder expected a call to **pt_qry_cond_branch**(3) or - **pt_qry_indirect_branch**(3). This usually means that execution flow - reconstruction and trace got out of sync. - - -# SEE ALSO - -**pt_qry_alloc_decoder**(3), **pt_qry_free_decoder**(3), -**pt_qry_cond_branch**(3), **pt_qry_indirect_branch**(3), **pt_qry_time**(3), -**pt_qry_core_bus_ratio**(3), **pt_insn_next**(3), **pt_blk_next**(3)
View file
_service:tar_scm:v2.0.5.tar.gz/include/posix/threads.h
Deleted
@@ -1,259 +0,0 @@ -/* - * Copyright (c) 2014-2022, Intel Corporation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * - * It looks like there is still no support for C11's threads.h. - * - * We implement the few features we actually need hoping that this file will - * soon go away. - */ - -#ifndef THREADS_H -#define THREADS_H - -#include <pthread.h> - -#ifndef PTHREAD_MUTEX_NORMAL -# define PTHREAD_MUTEX_NORMAL PTHREAD_MUTEX_TIMED_NP -#endif - -#include <stdint.h> -#include <stdlib.h> - -enum { - thrd_success = 1, - thrd_error -}; - -struct pt_thread { - pthread_t thread; -}; -typedef struct pt_thread thrd_t; - -typedef int (*thrd_start_t)(void *); - - -struct thrd_args { - thrd_start_t fun; - void *arg; -}; - -static void *thrd_routine(void *arg) -{ - struct thrd_args *args; - int result; - - args = arg; - if (!args) - return (void *) (intptr_t) -1; - - result = -1; - if (args->fun) - result = args->fun(args->arg); - - free(args); - - return (void *) (intptr_t) result; -} - -static inline int thrd_create(thrd_t *thrd, thrd_start_t fun, void *arg) -{ - struct thrd_args *args; - int errcode; - - if (!thrd || !fun) - return thrd_error; - - args = malloc(sizeof(*args)); - if (!args) - return thrd_error; - - args->fun = fun; - args->arg = arg; - - errcode = pthread_create(&thrd->thread, NULL, thrd_routine, args); - if (errcode) { - free(args); - return thrd_error; - } - - return thrd_success; -} - -static inline int thrd_join(thrd_t *thrd, int *res) -{ - void *result; - int errcode; - - if (!thrd) - return thrd_error; - - errcode = pthread_join(thrd->thread, &result); - if (errcode) - return thrd_error; - - if (res) - *res = (int) (intptr_t) result; - - return thrd_success; -} - - -struct pt_mutex { - pthread_mutex_t mutex; -}; -typedef struct pt_mutex mtx_t; - -enum { - mtx_plain = PTHREAD_MUTEX_NORMAL -}; - -static inline int mtx_init(mtx_t *mtx, int type) -{ - int errcode; - - if (!mtx || type != mtx_plain) - return thrd_error; - - errcode = pthread_mutex_init(&mtx->mutex, NULL); - if (errcode) - return thrd_error; - - return thrd_success; -} - -static inline void mtx_destroy(mtx_t *mtx) -{ - if (mtx) - (void) pthread_mutex_destroy(&mtx->mutex); -} - -static inline int mtx_lock(mtx_t *mtx) -{ - int errcode; - - if (!mtx) - return thrd_error; - - errcode = pthread_mutex_lock(&mtx->mutex); - if (errcode) - return thrd_error; - - return thrd_success; -} - -static inline int mtx_unlock(mtx_t *mtx) -{ - int errcode; - - if (!mtx) - return thrd_error; - - errcode = pthread_mutex_unlock(&mtx->mutex); - if (errcode) - return thrd_error; - - return thrd_success; -} - - -struct pt_cond { - pthread_cond_t cond; -}; -typedef struct pt_cond cnd_t; - -static inline int cnd_init(cnd_t *cnd) -{ - int errcode; - - if (!cnd) - return thrd_error; - - errcode = pthread_cond_init(&cnd->cond, NULL); - if (errcode) - return thrd_error; - - return thrd_success; -} - -static inline int cnd_destroy(cnd_t *cnd) -{ - int errcode; - - if (!cnd) - return thrd_error; - - errcode = pthread_cond_destroy(&cnd->cond); - if (errcode) - return thrd_error; - - return thrd_success; -} - -static inline int cnd_signal(cnd_t *cnd) -{ - int errcode; - - if (!cnd) - return thrd_error; - - errcode = pthread_cond_signal(&cnd->cond); - if (errcode) - return thrd_error; - - return thrd_success; -} - -static inline int cnd_broadcast(cnd_t *cnd) -{ - int errcode; - - if (!cnd) - return thrd_error; - - errcode = pthread_cond_broadcast(&cnd->cond); - if (errcode) - return thrd_error; - - return thrd_success; -} - -static inline int cnd_wait(cnd_t *cnd, mtx_t *mtx) -{ - int errcode; - - if (!cnd || !mtx) - return thrd_error; - - errcode = pthread_cond_wait(&cnd->cond, &mtx->mutex); - if (errcode) - return thrd_error; - - return thrd_success; -} - -#endif /* THREADS_H */
View file
_service:tar_scm:v2.0.5.tar.gz/include/windows/threads.h
Deleted
@@ -1,239 +0,0 @@ -/* - * Copyright (c) 2014-2022, Intel Corporation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * - * It looks like there is still no support for C11's threads.h. - * - * We implement the few features we actually need hoping that this file will - * soon go away. - */ - -#ifndef THREADS_H -#define THREADS_H - -#include "windows.h" - - -enum { - thrd_success = 1, - thrd_error -}; - - -struct pt_thread { - HANDLE handle; -}; -typedef struct pt_thread thrd_t; - -typedef int (*thrd_start_t)(void *); - - -struct thrd_args { - thrd_start_t fun; - void *arg; -}; - -static DWORD WINAPI thrd_routine(void *arg) -{ - struct thrd_args *args; - int result; - - args = (struct thrd_args *) arg; - if (!args) - return (DWORD) -1; - - result = -1; - if (args->fun) - result = args->fun(args->arg); - - free(args); - - return (DWORD) result; -} - -static inline int thrd_create(thrd_t *thrd, thrd_start_t fun, void *arg) -{ - struct thrd_args *args; - HANDLE handle; - - if (!thrd || !fun) - return thrd_error; - - args = malloc(sizeof(*args)); - if (!args) - return thrd_error; - - args->fun = fun; - args->arg = arg; - - handle = CreateThread(NULL, 0, thrd_routine, args, 0, NULL); - if (!handle) { - free(args); - return thrd_error; - } - - thrd->handle = handle; - return thrd_success; -} - -static inline int thrd_join(thrd_t *thrd, int *res) -{ - DWORD status; - BOOL success; - - if (!thrd) - return thrd_error; - - status = WaitForSingleObject(thrd->handle, INFINITE); - if (status) - return thrd_error; - - if (res) { - DWORD result; - - success = GetExitCodeThread(thrd->handle, &result); - if (!success) { - (void) CloseHandle(thrd->handle); - return thrd_error; - } - - *res = (int) result; - } - - success = CloseHandle(thrd->handle); - if (!success) - return thrd_error; - - return thrd_success; -} - -struct pt_mutex { - CRITICAL_SECTION cs; -}; -typedef struct pt_mutex mtx_t; - -enum { - mtx_plain -}; - -static inline int mtx_init(mtx_t *mtx, int type) -{ - if (!mtx || type != mtx_plain) - return thrd_error; - - InitializeCriticalSection(&mtx->cs); - - return thrd_success; -} - -static inline void mtx_destroy(mtx_t *mtx) -{ - if (mtx) - DeleteCriticalSection(&mtx->cs); -} - -static inline int mtx_lock(mtx_t *mtx) -{ - if (!mtx) - return thrd_error; - - EnterCriticalSection(&mtx->cs); - - return thrd_success; -} - -static inline int mtx_unlock(mtx_t *mtx) -{ - if (!mtx) - return thrd_error; - - LeaveCriticalSection(&mtx->cs); - - return thrd_success; -} - - -struct pt_cond { - CONDITION_VARIABLE cond; -}; -typedef struct pt_cond cnd_t; - -static inline int cnd_init(cnd_t *cnd) -{ - if (!cnd) - return thrd_error; - - InitializeConditionVariable(&cnd->cond); - - return thrd_success; -} - -static inline int cnd_destroy(cnd_t *cnd) -{ - if (!cnd) - return thrd_error; - - /* Nothing to do. */ - - return thrd_success; -} - -static inline int cnd_signal(cnd_t *cnd) -{ - if (!cnd) - return thrd_error; - - WakeConditionVariable(&cnd->cond); - - return thrd_success; -} - -static inline int cnd_broadcast(cnd_t *cnd) -{ - if (!cnd) - return thrd_error; - - WakeAllConditionVariable(&cnd->cond); - - return thrd_success; -} - -static inline int cnd_wait(cnd_t *cnd, mtx_t *mtx) -{ - BOOL success; - - if (!cnd || !mtx) - return thrd_error; - - success = SleepConditionVariableCS(&cnd->cond, &mtx->cs, INFINITE); - if (!success) - return thrd_error; - - return thrd_success; -} - -#endif /* THREADS_H */
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/internal/include/pt_cpuid.h
Deleted
@@ -1,40 +0,0 @@ -/* - * Copyright (c) 2013-2022, Intel Corporation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef PT_CPUID_H -#define PT_CPUID_H - -#include <inttypes.h> - -/* Execute cpuid with @leaf set in the eax register. - * The result is stored in @eax, @ebx, @ecx and @edx. - */ -extern void pt_cpuid(uint32_t leaf, uint32_t *eax, uint32_t *ebx, - uint32_t *ecx, uint32_t *edx); - -#endif /* PT_CPUID_H */
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/internal/include/pt_decoder_function.h
Deleted
@@ -1,129 +0,0 @@ -/* - * Copyright (c) 2013-2022, Intel Corporation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef PT_DECODER_FUNCTION_H -#define PT_DECODER_FUNCTION_H - -#include <stdint.h> - -struct pt_query_decoder; -struct pt_packet_decoder; -struct pt_packet; -struct pt_config; - - -/* Intel(R) Processor Trace decoder function flags. */ -enum pt_decoder_function_flag { - /* The decoded packet contains an unconditional branch destination. */ - pdff_tip = 1 << 0, - - /* The decode packet contains unconditional branch destinations. */ - pdff_tnt = 1 << 1, - - /* The decoded packet contains an event. */ - pdff_event = 1 << 2, - - /* The decoded packet marks the end of a PSB header. */ - pdff_psbend = 1 << 3, - - /* The decoded packet contains a non-branch IP update. */ - pdff_fup = 1 << 4, - - /* The decoded packet is unknown to the decoder. */ - pdff_unknown = 1 << 5, - - /* The decoded packet contains timing information. */ - pdff_timing = 1 << 6, - - /* The decoded packet contains padding. */ - pdff_pad = 1 << 7 -}; - -/* An Intel(R) Processor Trace decoder function. */ -struct pt_decoder_function { - /* The function to analyze the next packet. */ - int (*packet)(struct pt_packet_decoder *, struct pt_packet *); - - /* The function to decode the next packet. */ - int (*decode)(struct pt_query_decoder *); - - /* The function to decode the next packet in segment header - * context, i.e. between PSB and ENDPSB. - */ - int (*header)(struct pt_query_decoder *); - - /* Decoder function flags. */ - int flags; -}; - - -/* Fetch the decoder function. - * - * Sets @dfun to the decoder function for decoding the packet at @pos. - * - * Returns 0 on success. - * Returns -pte_internal if @dfun or @config is NULL. - * Returns -pte_nosync if @pos is NULL or outside @config's trace buffer. - * Returns -pte_eos if the opcode is incomplete or missing. - */ -extern int pt_df_fetch(const struct pt_decoder_function **dfun, - const uint8_t *pos, const struct pt_config *config); - - -/* Decoder functions for the various packet types. - * - * Do not call those functions directly! - */ -extern const struct pt_decoder_function pt_decode_unknown; -extern const struct pt_decoder_function pt_decode_pad; -extern const struct pt_decoder_function pt_decode_psb; -extern const struct pt_decoder_function pt_decode_tip; -extern const struct pt_decoder_function pt_decode_tnt_8; -extern const struct pt_decoder_function pt_decode_tnt_64; -extern const struct pt_decoder_function pt_decode_tip_pge; -extern const struct pt_decoder_function pt_decode_tip_pgd; -extern const struct pt_decoder_function pt_decode_fup; -extern const struct pt_decoder_function pt_decode_pip; -extern const struct pt_decoder_function pt_decode_ovf; -extern const struct pt_decoder_function pt_decode_mode; -extern const struct pt_decoder_function pt_decode_psbend; -extern const struct pt_decoder_function pt_decode_tsc; -extern const struct pt_decoder_function pt_decode_cbr; -extern const struct pt_decoder_function pt_decode_tma; -extern const struct pt_decoder_function pt_decode_mtc; -extern const struct pt_decoder_function pt_decode_cyc; -extern const struct pt_decoder_function pt_decode_stop; -extern const struct pt_decoder_function pt_decode_vmcs; -extern const struct pt_decoder_function pt_decode_mnt; -extern const struct pt_decoder_function pt_decode_exstop; -extern const struct pt_decoder_function pt_decode_mwait; -extern const struct pt_decoder_function pt_decode_pwre; -extern const struct pt_decoder_function pt_decode_pwrx; -extern const struct pt_decoder_function pt_decode_ptw; - -#endif /* PT_DECODER_FUNCTION_H */
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/src/posix/pt_cpuid.c
Deleted
@@ -1,37 +0,0 @@ -/* - * Copyright (c) 2013-2022, Intel Corporation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "pt_cpuid.h" - -#include <cpuid.h> - -extern void pt_cpuid(uint32_t leaf, uint32_t *eax, uint32_t *ebx, - uint32_t *ecx, uint32_t *edx) -{ - __get_cpuid(leaf, eax, ebx, ecx, edx); -}
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/src/pt_decoder_function.c
Deleted
@@ -1,379 +0,0 @@ -/* - * Copyright (c) 2013-2022, Intel Corporation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "pt_decoder_function.h" -#include "pt_packet_decoder.h" -#include "pt_query_decoder.h" -#include "pt_opcodes.h" - -#include "intel-pt.h" - - -const struct pt_decoder_function pt_decode_unknown = { - /* .packet = */ pt_pkt_decode_unknown, - /* .decode = */ pt_qry_decode_unknown, - /* .header = */ pt_qry_decode_unknown, - /* .flags = */ pdff_unknown -}; - -const struct pt_decoder_function pt_decode_pad = { - /* .packet = */ pt_pkt_decode_pad, - /* .decode = */ pt_qry_decode_pad, - /* .header = */ pt_qry_decode_pad, - /* .flags = */ pdff_pad -}; - -const struct pt_decoder_function pt_decode_psb = { - /* .packet = */ pt_pkt_decode_psb, - /* .decode = */ pt_qry_decode_psb, - /* .header = */ NULL, - /* .flags = */ 0 -}; - -const struct pt_decoder_function pt_decode_tip = { - /* .packet = */ pt_pkt_decode_tip, - /* .decode = */ pt_qry_decode_tip, - /* .header = */ NULL, - /* .flags = */ pdff_tip -}; - -const struct pt_decoder_function pt_decode_tnt_8 = { - /* .packet = */ pt_pkt_decode_tnt_8, - /* .decode = */ pt_qry_decode_tnt_8, - /* .header = */ NULL, - /* .flags = */ pdff_tnt -}; - -const struct pt_decoder_function pt_decode_tnt_64 = { - /* .packet = */ pt_pkt_decode_tnt_64, - /* .decode = */ pt_qry_decode_tnt_64, - /* .header = */ NULL, - /* .flags = */ pdff_tnt -}; - -const struct pt_decoder_function pt_decode_tip_pge = { - /* .packet = */ pt_pkt_decode_tip_pge, - /* .decode = */ pt_qry_decode_tip_pge, - /* .header = */ NULL, - /* .flags = */ pdff_event -}; - -const struct pt_decoder_function pt_decode_tip_pgd = { - /* .packet = */ pt_pkt_decode_tip_pgd, - /* .decode = */ pt_qry_decode_tip_pgd, - /* .header = */ NULL, - /* .flags = */ pdff_event -}; - -const struct pt_decoder_function pt_decode_fup = { - /* .packet = */ pt_pkt_decode_fup, - /* .decode = */ pt_qry_decode_fup, - /* .header = */ pt_qry_header_fup, - /* .flags = */ pdff_fup -}; - -const struct pt_decoder_function pt_decode_pip = { - /* .packet = */ pt_pkt_decode_pip, - /* .decode = */ pt_qry_decode_pip, - /* .header = */ pt_qry_header_pip, - /* .flags = */ pdff_event -}; - -const struct pt_decoder_function pt_decode_ovf = { - /* .packet = */ pt_pkt_decode_ovf, - /* .decode = */ pt_qry_decode_ovf, - /* .header = */ NULL, - /* .flags = */ pdff_psbend | pdff_event -}; - -const struct pt_decoder_function pt_decode_mode = { - /* .packet = */ pt_pkt_decode_mode, - /* .decode = */ pt_qry_decode_mode, - /* .header = */ pt_qry_header_mode, - /* .flags = */ pdff_event -}; - -const struct pt_decoder_function pt_decode_psbend = { - /* .packet = */ pt_pkt_decode_psbend, - /* .decode = */ pt_qry_decode_psbend, - /* .header = */ NULL, - /* .flags = */ pdff_psbend -}; - -const struct pt_decoder_function pt_decode_tsc = { - /* .packet = */ pt_pkt_decode_tsc, - /* .decode = */ pt_qry_decode_tsc, - /* .header = */ pt_qry_header_tsc, - /* .flags = */ pdff_timing -}; - -const struct pt_decoder_function pt_decode_cbr = { - /* .packet = */ pt_pkt_decode_cbr, - /* .decode = */ pt_qry_decode_cbr, - /* .header = */ pt_qry_header_cbr, - /* .flags = */ pdff_timing | pdff_event -}; - -const struct pt_decoder_function pt_decode_tma = { - /* .packet = */ pt_pkt_decode_tma, - /* .decode = */ pt_qry_decode_tma, - /* .header = */ pt_qry_decode_tma, - /* .flags = */ pdff_timing -}; - -const struct pt_decoder_function pt_decode_mtc = { - /* .packet = */ pt_pkt_decode_mtc, - /* .decode = */ pt_qry_decode_mtc, - /* .header = */ pt_qry_decode_mtc, - /* .flags = */ pdff_timing -}; - -const struct pt_decoder_function pt_decode_cyc = { - /* .packet = */ pt_pkt_decode_cyc, - /* .decode = */ pt_qry_decode_cyc, - /* .header = */ pt_qry_decode_cyc, - /* .flags = */ pdff_timing -}; - -const struct pt_decoder_function pt_decode_stop = { - /* .packet = */ pt_pkt_decode_stop, - /* .decode = */ pt_qry_decode_stop, - /* .header = */ NULL, - /* .flags = */ pdff_event -}; - -const struct pt_decoder_function pt_decode_vmcs = { - /* .packet = */ pt_pkt_decode_vmcs, - /* .decode = */ pt_qry_decode_vmcs, - /* .header = */ pt_qry_header_vmcs, - /* .flags = */ pdff_event -}; - -const struct pt_decoder_function pt_decode_mnt = { - /* .packet = */ pt_pkt_decode_mnt, - /* .decode = */ pt_qry_decode_mnt, - /* .header = */ pt_qry_header_mnt, - /* .flags = */ pdff_event -}; - -const struct pt_decoder_function pt_decode_exstop = { - /* .packet = */ pt_pkt_decode_exstop, - /* .decode = */ pt_qry_decode_exstop, - /* .header = */ NULL, - /* .flags = */ pdff_event -}; - -const struct pt_decoder_function pt_decode_mwait = { - /* .packet = */ pt_pkt_decode_mwait, - /* .decode = */ pt_qry_decode_mwait, - /* .header = */ NULL, - /* .flags = */ pdff_event -}; - -const struct pt_decoder_function pt_decode_pwre = { - /* .packet = */ pt_pkt_decode_pwre, - /* .decode = */ pt_qry_decode_pwre, - /* .header = */ NULL, - /* .flags = */ pdff_event -}; - -const struct pt_decoder_function pt_decode_pwrx = { - /* .packet = */ pt_pkt_decode_pwrx, - /* .decode = */ pt_qry_decode_pwrx, - /* .header = */ NULL, - /* .flags = */ pdff_event -}; - -const struct pt_decoder_function pt_decode_ptw = { - /* .packet = */ pt_pkt_decode_ptw, - /* .decode = */ pt_qry_decode_ptw, - /* .header = */ NULL, - /* .flags = */ pdff_event -}; - - -int pt_df_fetch(const struct pt_decoder_function **dfun, const uint8_t *pos, - const struct pt_config *config) -{ - const uint8_t *begin, *end; - uint8_t opc, ext, ext2; - - if (!dfun || !config) - return -pte_internal; - - /* Clear the decode function in case of errors. */ - *dfun = NULL; - - begin = config->begin; - end = config->end; - - if (!pos || (pos < begin) || (end < pos)) - return -pte_nosync; - - if (pos == end) - return -pte_eos; - - opc = *pos++; - switch (opc) { - default: - /* Check opcodes that require masking. */ - if ((opc & pt_opm_tnt_8) == pt_opc_tnt_8) { - *dfun = &pt_decode_tnt_8; - return 0; - } - - if ((opc & pt_opm_cyc) == pt_opc_cyc) { - *dfun = &pt_decode_cyc; - return 0; - } - - if ((opc & pt_opm_tip) == pt_opc_tip) { - *dfun = &pt_decode_tip; - return 0; - } - - if ((opc & pt_opm_fup) == pt_opc_fup) { - *dfun = &pt_decode_fup; - return 0; - } - - if ((opc & pt_opm_tip) == pt_opc_tip_pge) { - *dfun = &pt_decode_tip_pge; - return 0; - } - - if ((opc & pt_opm_tip) == pt_opc_tip_pgd) { - *dfun = &pt_decode_tip_pgd; - return 0; - } - - *dfun = &pt_decode_unknown; - return 0; - - case pt_opc_pad: - *dfun = &pt_decode_pad; - return 0; - - case pt_opc_mode: - *dfun = &pt_decode_mode; - return 0; - - case pt_opc_tsc: - *dfun = &pt_decode_tsc; - return 0; - - case pt_opc_mtc: - *dfun = &pt_decode_mtc; - return 0; - - case pt_opc_ext: - if (pos == end) - return -pte_eos; - - ext = *pos++; - switch (ext) { - default: - /* Check opcodes that require masking. */ - if ((ext & pt_opm_ptw) == pt_ext_ptw) { - *dfun = &pt_decode_ptw; - return 0; - } - - *dfun = &pt_decode_unknown; - return 0; - - case pt_ext_psb: - *dfun = &pt_decode_psb; - return 0; - - case pt_ext_ovf: - *dfun = &pt_decode_ovf; - return 0; - - case pt_ext_tnt_64: - *dfun = &pt_decode_tnt_64; - return 0; - - case pt_ext_psbend: - *dfun = &pt_decode_psbend; - return 0; - - case pt_ext_cbr: - *dfun = &pt_decode_cbr; - return 0; - - case pt_ext_pip: - *dfun = &pt_decode_pip; - return 0; - - case pt_ext_tma: - *dfun = &pt_decode_tma; - return 0; - - case pt_ext_stop: - *dfun = &pt_decode_stop; - return 0; - - case pt_ext_vmcs: - *dfun = &pt_decode_vmcs; - return 0; - - case pt_ext_exstop: - case pt_ext_exstop_ip: - *dfun = &pt_decode_exstop; - return 0; - - case pt_ext_mwait: - *dfun = &pt_decode_mwait; - return 0; - - case pt_ext_pwre: - *dfun = &pt_decode_pwre; - return 0; - - case pt_ext_pwrx: - *dfun = &pt_decode_pwrx; - return 0; - - case pt_ext_ext2: - if (pos == end) - return -pte_eos; - - ext2 = *pos++; - switch (ext2) { - default: - *dfun = &pt_decode_unknown; - return 0; - - case pt_ext2_mnt: - *dfun = &pt_decode_mnt; - return 0; - } - } - } -}
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/src/windows/pt_cpuid.c
Deleted
@@ -1,43 +0,0 @@ -/* - * Copyright (c) 2013-2022, Intel Corporation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "pt_cpuid.h" - -#include <intrin.h> - -extern void pt_cpuid(uint32_t leaf, uint32_t *eax, uint32_t *ebx, - uint32_t *ecx, uint32_t *edx) -{ - int cpu_info4; - - __cpuid(cpu_info, leaf); - *eax = cpu_info0; - *ebx = cpu_info1; - *ecx = cpu_info2; - *edx = cpu_info3; -}
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/test/src/ptunit-fetch.c
Deleted
@@ -1,693 +0,0 @@ -/* - * Copyright (c) 2014-2022, Intel Corporation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "ptunit.h" - -#include "pt_decoder_function.h" -#include "pt_packet_decoder.h" -#include "pt_query_decoder.h" -#include "pt_encoder.h" -#include "pt_opcodes.h" - -#include "intel-pt.h" - - -/* A test fixture for decoder function fetch tests. */ -struct fetch_fixture { - /* The trace buffer. */ - uint8_t buffer1024; - - /* A trace configuration. */ - struct pt_config config; - - /* A trace encoder. */ - struct pt_encoder encoder; - - /* The test fixture initialization and finalization functions. */ - struct ptunit_result (*init)(struct fetch_fixture *); - struct ptunit_result (*fini)(struct fetch_fixture *); -}; - -static struct ptunit_result ffix_init(struct fetch_fixture *ffix) -{ - memset(ffix->buffer, pt_opc_bad, sizeof(ffix->buffer)); - - memset(&ffix->config, 0, sizeof(ffix->config)); - ffix->config.size = sizeof(ffix->config); - ffix->config.begin = ffix->buffer; - ffix->config.end = ffix->buffer + sizeof(ffix->buffer); - - pt_encoder_init(&ffix->encoder, &ffix->config); - - return ptu_passed(); -} - -static struct ptunit_result ffix_fini(struct fetch_fixture *ffix) -{ - pt_encoder_fini(&ffix->encoder); - - return ptu_passed(); -} - - -static struct ptunit_result fetch_null(struct fetch_fixture *ffix) -{ - const struct pt_decoder_function *dfun; - int errcode; - - errcode = pt_df_fetch(NULL, ffix->config.begin, &ffix->config); - ptu_int_eq(errcode, -pte_internal); - - errcode = pt_df_fetch(&dfun, NULL, &ffix->config); - ptu_int_eq(errcode, -pte_nosync); - - errcode = pt_df_fetch(&dfun, ffix->config.begin, NULL); - ptu_int_eq(errcode, -pte_internal); - - return ptu_passed(); -} - -static struct ptunit_result fetch_empty(struct fetch_fixture *ffix) -{ - const struct pt_decoder_function *dfun; - int errcode; - - errcode = pt_df_fetch(&dfun, ffix->config.end, &ffix->config); - ptu_int_eq(errcode, -pte_eos); - - return ptu_passed(); -} - -static struct ptunit_result fetch_unknown(struct fetch_fixture *ffix) -{ - const struct pt_decoder_function *dfun; - int errcode; - - ffix->config.begin0 = pt_opc_bad; - - errcode = pt_df_fetch(&dfun, ffix->config.begin, &ffix->config); - ptu_int_eq(errcode, 0); - ptu_ptr_eq(dfun, &pt_decode_unknown); - - return ptu_passed(); -} - -static struct ptunit_result fetch_unknown_ext(struct fetch_fixture *ffix) -{ - const struct pt_decoder_function *dfun; - int errcode; - - ffix->config.begin0 = pt_opc_ext; - ffix->config.begin1 = pt_ext_bad; - - errcode = pt_df_fetch(&dfun, ffix->config.begin, &ffix->config); - ptu_int_eq(errcode, 0); - ptu_ptr_eq(dfun, &pt_decode_unknown); - - return ptu_passed(); -} - -static struct ptunit_result fetch_unknown_ext2(struct fetch_fixture *ffix) -{ - const struct pt_decoder_function *dfun; - int errcode; - - ffix->config.begin0 = pt_opc_ext; - ffix->config.begin1 = pt_ext_ext2; - ffix->config.begin2 = pt_ext2_bad; - - errcode = pt_df_fetch(&dfun, ffix->config.begin, &ffix->config); - ptu_int_eq(errcode, 0); - ptu_ptr_eq(dfun, &pt_decode_unknown); - - return ptu_passed(); -} - -static struct ptunit_result fetch_packet(struct fetch_fixture *ffix, - const struct pt_packet *packet, - const struct pt_decoder_function *df) -{ - const struct pt_decoder_function *dfun; - int errcode; - - errcode = pt_enc_next(&ffix->encoder, packet); - ptu_int_ge(errcode, 0); - - errcode = pt_df_fetch(&dfun, ffix->config.begin, &ffix->config); - ptu_int_eq(errcode, 0); - ptu_ptr_eq(dfun, df); - - return ptu_passed(); -} - -static struct ptunit_result fetch_type(struct fetch_fixture *ffix, - enum pt_packet_type type, - const struct pt_decoder_function *dfun) -{ - struct pt_packet packet; - - memset(&packet, 0, sizeof(packet)); - packet.type = type; - - ptu_test(fetch_packet, ffix, &packet, dfun); - - return ptu_passed(); -} - -static struct ptunit_result fetch_tnt_8(struct fetch_fixture *ffix) -{ - struct pt_packet packet; - - memset(&packet, 0, sizeof(packet)); - packet.type = ppt_tnt_8; - packet.payload.tnt.bit_size = 1; - - ptu_test(fetch_packet, ffix, &packet, &pt_decode_tnt_8); - - return ptu_passed(); -} - -static struct ptunit_result fetch_mode_exec(struct fetch_fixture *ffix) -{ - struct pt_packet packet; - - memset(&packet, 0, sizeof(packet)); - packet.type = ppt_mode; - packet.payload.mode.leaf = pt_mol_exec; - - ptu_test(fetch_packet, ffix, &packet, &pt_decode_mode); - - return ptu_passed(); -} - -static struct ptunit_result fetch_mode_tsx(struct fetch_fixture *ffix) -{ - struct pt_packet packet; - - memset(&packet, 0, sizeof(packet)); - packet.type = ppt_mode; - packet.payload.mode.leaf = pt_mol_tsx; - - ptu_test(fetch_packet, ffix, &packet, &pt_decode_mode); - - return ptu_passed(); -} - -static struct ptunit_result fetch_exstop_ip(struct fetch_fixture *ffix) -{ - struct pt_packet packet; - - memset(&packet, 0, sizeof(packet)); - packet.type = ppt_exstop; - packet.payload.exstop.ip = 1; - - ptu_test(fetch_packet, ffix, &packet, &pt_decode_exstop); - - return ptu_passed(); -} - -int main(int argc, char **argv) -{ - struct fetch_fixture ffix; - struct ptunit_suite suite; - - ffix.init = ffix_init; - ffix.fini = ffix_fini; - - suite = ptunit_mk_suite(argc, argv); - - ptu_run_f(suite, fetch_null, ffix); - ptu_run_f(suite, fetch_empty, ffix); - - ptu_run_f(suite, fetch_unknown, ffix); - ptu_run_f(suite, fetch_unknown_ext, ffix); - ptu_run_f(suite, fetch_unknown_ext2, ffix); - - ptu_run_fp(suite, fetch_type, ffix, ppt_pad, &pt_decode_pad); - ptu_run_fp(suite, fetch_type, ffix, ppt_psb, &pt_decode_psb); - ptu_run_fp(suite, fetch_type, ffix, ppt_tip, &pt_decode_tip); - ptu_run_fp(suite, fetch_type, ffix, ppt_tnt_64, &pt_decode_tnt_64); - ptu_run_fp(suite, fetch_type, ffix, ppt_tip_pge, &pt_decode_tip_pge); - ptu_run_fp(suite, fetch_type, ffix, ppt_tip_pgd, &pt_decode_tip_pgd); - ptu_run_fp(suite, fetch_type, ffix, ppt_fup, &pt_decode_fup); - ptu_run_fp(suite, fetch_type, ffix, ppt_pip, &pt_decode_pip); - ptu_run_fp(suite, fetch_type, ffix, ppt_ovf, &pt_decode_ovf); - ptu_run_fp(suite, fetch_type, ffix, ppt_psbend, &pt_decode_psbend); - ptu_run_fp(suite, fetch_type, ffix, ppt_tsc, &pt_decode_tsc); - ptu_run_fp(suite, fetch_type, ffix, ppt_cbr, &pt_decode_cbr); - ptu_run_fp(suite, fetch_type, ffix, ppt_tma, &pt_decode_tma); - ptu_run_fp(suite, fetch_type, ffix, ppt_mtc, &pt_decode_mtc); - ptu_run_fp(suite, fetch_type, ffix, ppt_cyc, &pt_decode_cyc); - ptu_run_fp(suite, fetch_type, ffix, ppt_stop, &pt_decode_stop); - ptu_run_fp(suite, fetch_type, ffix, ppt_vmcs, &pt_decode_vmcs); - ptu_run_fp(suite, fetch_type, ffix, ppt_mnt, &pt_decode_mnt); - ptu_run_fp(suite, fetch_type, ffix, ppt_exstop, &pt_decode_exstop); - ptu_run_fp(suite, fetch_type, ffix, ppt_mwait, &pt_decode_mwait); - ptu_run_fp(suite, fetch_type, ffix, ppt_pwre, &pt_decode_pwre); - ptu_run_fp(suite, fetch_type, ffix, ppt_pwrx, &pt_decode_pwrx); - ptu_run_fp(suite, fetch_type, ffix, ppt_ptw, &pt_decode_ptw); - - ptu_run_f(suite, fetch_tnt_8, ffix); - ptu_run_f(suite, fetch_mode_exec, ffix); - ptu_run_f(suite, fetch_mode_tsx, ffix); - ptu_run_f(suite, fetch_exstop_ip, ffix); - - return ptunit_report(&suite); -} - - -/* Dummy decode functions to satisfy link dependencies. - * - * As a nice side-effect, we will know if we need to add more tests when - * adding new decoder functions. - */ -int pt_pkt_decode_unknown(struct pt_packet_decoder *d, struct pt_packet *p) -{ - (void) d; - (void) p; - - return -pte_internal; -} -int pt_qry_decode_unknown(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} - -int pt_pkt_decode_pad(struct pt_packet_decoder *d, struct pt_packet *p) -{ - (void) d; - (void) p; - - return -pte_internal; -} -int pt_qry_decode_pad(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} - -int pt_pkt_decode_psb(struct pt_packet_decoder *d, struct pt_packet *p) -{ - (void) d; - (void) p; - - return -pte_internal; -} -int pt_qry_decode_psb(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} - -int pt_pkt_decode_tip(struct pt_packet_decoder *d, struct pt_packet *p) -{ - (void) d; - (void) p; - - return -pte_internal; -} -int pt_qry_decode_tip(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} - -int pt_pkt_decode_tnt_8(struct pt_packet_decoder *d, struct pt_packet *p) -{ - (void) d; - (void) p; - - return -pte_internal; -} -int pt_qry_decode_tnt_8(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} - -int pt_pkt_decode_tnt_64(struct pt_packet_decoder *d, struct pt_packet *p) -{ - (void) d; - (void) p; - - return -pte_internal; -} -int pt_qry_decode_tnt_64(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} - -int pt_pkt_decode_tip_pge(struct pt_packet_decoder *d, struct pt_packet *p) -{ - (void) d; - (void) p; - - return -pte_internal; -} -int pt_qry_decode_tip_pge(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} - -int pt_pkt_decode_tip_pgd(struct pt_packet_decoder *d, struct pt_packet *p) -{ - (void) d; - (void) p; - - return -pte_internal; -} -int pt_qry_decode_tip_pgd(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} - -int pt_pkt_decode_fup(struct pt_packet_decoder *d, struct pt_packet *p) -{ - (void) d; - (void) p; - - return -pte_internal; -} -int pt_qry_decode_fup(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} -int pt_qry_header_fup(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} - -int pt_pkt_decode_pip(struct pt_packet_decoder *d, struct pt_packet *p) -{ - (void) d; - (void) p; - - return -pte_internal; -} -int pt_qry_decode_pip(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} -int pt_qry_header_pip(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} - -int pt_pkt_decode_ovf(struct pt_packet_decoder *d, struct pt_packet *p) -{ - (void) d; - (void) p; - - return -pte_internal; -} -int pt_qry_decode_ovf(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} - -int pt_pkt_decode_mode(struct pt_packet_decoder *d, struct pt_packet *p) -{ - (void) d; - (void) p; - - return -pte_internal; -} -int pt_qry_decode_mode(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} -int pt_qry_header_mode(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} - -int pt_pkt_decode_psbend(struct pt_packet_decoder *d, struct pt_packet *p) -{ - (void) d; - (void) p; - - return -pte_internal; -} -int pt_qry_decode_psbend(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} - -int pt_pkt_decode_tsc(struct pt_packet_decoder *d, struct pt_packet *p) -{ - (void) d; - (void) p; - - return -pte_internal; -} -int pt_qry_decode_tsc(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} -int pt_qry_header_tsc(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} - -int pt_pkt_decode_cbr(struct pt_packet_decoder *d, struct pt_packet *p) -{ - (void) d; - (void) p; - - return -pte_internal; -} -int pt_qry_decode_cbr(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} -int pt_qry_header_cbr(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} - -int pt_pkt_decode_tma(struct pt_packet_decoder *d, struct pt_packet *p) -{ - (void) d; - (void) p; - - return -pte_internal; -} -int pt_qry_decode_tma(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} - -int pt_pkt_decode_mtc(struct pt_packet_decoder *d, struct pt_packet *p) -{ - (void) d; - (void) p; - - return -pte_internal; -} -int pt_qry_decode_mtc(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} - -int pt_pkt_decode_cyc(struct pt_packet_decoder *d, struct pt_packet *p) -{ - (void) d; - (void) p; - - return -pte_internal; -} -int pt_qry_decode_cyc(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} - -int pt_pkt_decode_stop(struct pt_packet_decoder *d, struct pt_packet *p) -{ - (void) d; - (void) p; - - return -pte_internal; -} -int pt_qry_decode_stop(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} - -int pt_pkt_decode_vmcs(struct pt_packet_decoder *d, struct pt_packet *p) -{ - (void) d; - (void) p; - - return -pte_internal; -} -int pt_qry_decode_vmcs(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} -int pt_qry_header_vmcs(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} - -int pt_pkt_decode_mnt(struct pt_packet_decoder *d, struct pt_packet *p) -{ - (void) d; - (void) p; - - return -pte_internal; -} -int pt_qry_decode_mnt(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} -int pt_qry_header_mnt(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} - -int pt_pkt_decode_exstop(struct pt_packet_decoder *d, struct pt_packet *p) -{ - (void) d; - (void) p; - - return -pte_internal; -} -int pt_qry_decode_exstop(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} - -int pt_pkt_decode_mwait(struct pt_packet_decoder *d, struct pt_packet *p) -{ - (void) d; - (void) p; - - return -pte_internal; -} -int pt_qry_decode_mwait(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} - -int pt_pkt_decode_pwre(struct pt_packet_decoder *d, struct pt_packet *p) -{ - (void) d; - (void) p; - - return -pte_internal; -} -int pt_qry_decode_pwre(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} - -int pt_pkt_decode_pwrx(struct pt_packet_decoder *d, struct pt_packet *p) -{ - (void) d; - (void) p; - - return -pte_internal; -} -int pt_qry_decode_pwrx(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} - -int pt_pkt_decode_ptw(struct pt_packet_decoder *d, struct pt_packet *p) -{ - (void) d; - (void) p; - - return -pte_internal; -} -int pt_qry_decode_ptw(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -}
View file
_service:tar_scm:v2.0.5.tar.gz/CMakeLists.txt -> _service:tar_scm:v2.1.tar.gz/CMakeLists.txt
Changed
@@ -1,4 +1,5 @@ -# Copyright (c) 2013-2022, Intel Corporation +# Copyright (c) 2013-2023, Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: @@ -24,7 +25,13 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -cmake_minimum_required(VERSION 2.8.12) +cmake_minimum_required(VERSION 3.1) + +# Do not add /W3 to MSVC command-line +# +if (POLICY CMP0092) + cmake_policy(SET CMP0092 NEW) +endif () project(PT C) @@ -36,8 +43,8 @@ # a build number and a version extension can be optionally specified. # set(PT_VERSION_MAJOR 2) -set(PT_VERSION_MINOR 0) -set(PT_VERSION_PATCH 5) +set(PT_VERSION_MINOR 1) +set(PT_VERSION_PATCH 0) set(PT_VERSION_BUILD "0" CACHE STRING "") set(PT_VERSION_EXT "" CACHE STRING "") @@ -75,6 +82,7 @@ option(PTDUMP "Enable ptdump, a packet dumper") option(PTXED "Enable ptxed, an instruction flow dumper") option(PTTC "Enable pttc, a test compiler") +option(PTSEG "Enable ptseg, a PSB segment finder") option(PTUNIT "Enable ptunit, a unit test system and libipt unit tests") option(MAN "Enable man pages (requires pandoc)." OFF) option(SIDEBAND "Enable libipt-sb, a sideband correlation library") @@ -86,8 +94,17 @@ if (PTXED OR PEVENT) option(FEATURE_ELF "Support ELF files." OFF) + if (FEATURE_ELF) + add_definitions( + -DFEATURE_ELF + ) + endif (FEATURE_ELF) endif (PTXED OR PEVENT) +if (PEVENT AND NOT SIDEBAND) + message(FATAL_ERROR "PEVENT requires SIDEBAND") +endif () + set(PTT OFF) if (BASH AND PTDUMP AND PTXED AND PTTC) set(PTT ON) @@ -112,12 +129,6 @@ ) endif (PTUNIT) -if (FEATURE_ELF) - add_definitions( - -DFEATURE_ELF - ) -endif (FEATURE_ELF) - if (SIDEBAND) add_definitions( -DFEATURE_SIDEBAND @@ -183,9 +194,11 @@ /D_CRT_SECURE_NO_WARNINGS ) - # enable parallel build - # - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /MP") + if (CMAKE_GENERATOR MATCHES "Visual Studio") + # enable parallel build + # + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /MP") + endif () if (DEVBUILD) # compiler warnings @@ -231,10 +244,6 @@ link_libraries(pthread) endif (FEATURE_THREADS) - # set the language - # - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99") - # windows-like dll export model # set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden") @@ -261,6 +270,9 @@ HAVE_C_Wno_format_truncation) endif (CMAKE_C_COMPILER_ID MATCHES "Cclang") + add_cflag_if_available("-Wno-debug-disables-optimization" + HAVE_C_Wno_debug_disables_optimization) + # warnings are errors # set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror") @@ -272,6 +284,10 @@ function(add_ptunit_test_base name) if (PTUNIT) add_executable(${name} ${ARGN}) + set_target_properties(${name} PROPERTIES + C_STANDARD 11 + C_STANDARD_REQUIRED ON + ) target_link_libraries(${name} ptunit) add_test(NAME ${name} COMMAND ${name}) @@ -304,6 +320,9 @@ if (PTTC) add_subdirectory(pttc) endif (PTTC) +if (PTSEG) + add_subdirectory(ptseg) +endif (PTSEG) if (PTUNIT) add_subdirectory(ptunit) endif (PTUNIT)
View file
_service:tar_scm:v2.0.5.tar.gz/LICENSE -> _service:tar_scm:v2.1.tar.gz/LICENSE
Changed
@@ -1,4 +1,5 @@ -Copyright (c) 2013-2022, Intel Corporation +Copyright (c) 2013-2023, Intel Corporation +SPDX-License-Identifier: BSD-3-Clause Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/README -> _service:tar_scm:v2.1.tar.gz/README
Changed
@@ -26,6 +26,8 @@ ptxed Example implementation of a trace disassembler + ptseg A simple tool to find surrounding PSB packets + pttc A trace test generator ptunit A simple unit test system
View file
_service:tar_scm:v2.1.tar.gz/SECURITY
Added
@@ -0,0 +1,15 @@ +Security Policy +--------------- + +Intel is committed to rapidly addressing security vulnerabilities +affecting our customers and providing clear guidance on the solution, +impact, severity and mitigation. + + +Reporting a Vulnerability +------------------------- + +Please report any security vulnerabilities in this project utilizing the +guidelines here. + +here: https://www.intel.com/content/www/us/en/security-center/vulnerability-handling-guidelines.html
View file
_service:tar_scm:v2.0.5.tar.gz/doc/getting_started.md -> _service:tar_scm:v2.1.tar.gz/doc/getting_started.md
Changed
@@ -2,7 +2,8 @@ ======================== <!--- - ! Copyright (c) 2013-2022, Intel Corporation + ! Copyright (c) 2013-2023, Intel Corporation + ! SPDX-License-Identifier: BSD-3-Clause ! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/doc/howto_build.md -> _service:tar_scm:v2.1.tar.gz/doc/howto_build.md
Changed
@@ -2,7 +2,8 @@ ============================================================================ <!--- - ! Copyright (c) 2013-2022, Intel Corporation + ! Copyright (c) 2013-2023, Intel Corporation + ! SPDX-License-Identifier: BSD-3-Clause ! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions are met: @@ -46,7 +47,7 @@ By default, only the decoder library is built. Other components can be enabled by setting the respective cmake variable to ON. -The following optional components are availble: +The following optional components are available: PTUNIT A simple unit test framework. A collection of unit tests for libipt. @@ -91,8 +92,8 @@ GCOV Support for code coverage using libgcov. - This build variant requires libgcov and is not availble - on Windows. + This build variant requires libgcov and is not + available on Windows. DEVBUILD Enable compiler warnings and turn them into errors.
View file
_service:tar_scm:v2.0.5.tar.gz/doc/howto_capture.md -> _service:tar_scm:v2.1.tar.gz/doc/howto_capture.md
Changed
@@ -2,7 +2,8 @@ ============================================= <!--- - ! Copyright (c) 2015-2022, Intel Corporation + ! Copyright (c) 2015-2023, Intel Corporation + ! SPDX-License-Identifier: BSD-3-Clause ! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/doc/howto_libipt.md -> _service:tar_scm:v2.1.tar.gz/doc/howto_libipt.md
Changed
@@ -2,7 +2,8 @@ ======================================================== <!--- - ! Copyright (c) 2013-2022, Intel Corporation + ! Copyright (c) 2013-2023, Intel Corporation + ! SPDX-License-Identifier: BSD-3-Clause ! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions are met: @@ -54,6 +55,9 @@ * *events* This layer deals with packet combinations that encode higher-level events. + * *query* This layer deals with the execution flow on branch + level. + * *instruction flow* This layer deals with the execution flow on the instruction level. @@ -72,7 +76,8 @@ * *enc* Packet encoding (packet layer). * *pkt* Packet decoding (packet layer). - * *qry* Event (or query) layer. + * *evt* Event layer. + * *qry* Query layer. * *insn* Instruction flow layer. * *blk* Block layer. @@ -414,6 +419,111 @@ integrate execution flow reconstruction with other functionality more tightly than it would be possible otherwise. +It provides a linear stream of events. Start by configuring and allocating a +`pt_evt_decoder` as shown below: + +~~~{.c} + struct pt_event_decoder *decoder; + struct pt_config config; + int errcode; + + memset(&config, 0, sizeof(config)); + config.size = sizeof(config); + config.begin = <pt buffer begin>; + config.end = <pt buffer end>; + config.cpu = <cpu identifier>; + config.decode.callback = <decode function>; + config.decode.context = <decode context>; + + decoder = pt_evt_alloc_decoder(&config); + if (!decoder) + <handle error>(errcode); +~~~ + +An optional packet decode callback function may be specified in addition to the +mandatory config fields. If specified, the callback function will be called for +packets the decoder does not know about. The decoder will ignore the unknown +packet except for its size in order to skip it. If there is no decode callback +specified, the decoder will abort with `-pte_bad_opc`. In addition to the +callback function pointer, an optional pointer to user-defined context +information can be specified. This context will be passed to the decode +callback function. + +Before the decoder can be used, it needs to be synchronized onto the Intel PT +packet stream. To iterate over synchronization points in the Intel PT packet +stream in forward or backward direction, the event decoder offers the following +two synchronization functions: + + pt_evt_sync_forward() + pt_evt_sync_backward() + + +To manually synchronize the decoder at a synchronization point (i.e. PSB packet) +in the Intel PT packet stream, use the following function: + + pt_evt_sync_set() + + +After successfully synchronizing, the event decoder will start reading the PSB+ +header to initialize its internal state. The following example shows +synchronizing to the first synchronization point: + +~~~{.c} + struct pt_event_decoder *decoder; + uint64_t ip; + int status; + + status = pt_evt_sync_forward(decoder); + if (status < 0) + <handle error>(status); +~~~ + +The decoder will remember the last synchronization packet it decoded. +Subsequent calls to `pt_evt_sync_forward` and `pt_evt_sync_backward` will use +this as their starting point. + +You can get the current decoder position as offset into the Intel PT buffer via: + + pt_evt_get_offset() + + +You can get the position of the last synchronization point as offset into the +Intel PT buffer via: + + pt_evt_get_sync_offset() + + +In addition to an event decoder, you will need an instruction decoder for +decoding and classifying instructions. + + +#### Iterating + +Once the decoder is synchronized, you can iterate over processor trace events by +repeated calls to `pt_evt_next()` as shown in the following example: + +~~~{.c} + struct pt_event_decoder *decoder; + int status; + + for (;;) { + struct pt_event event; + + status = pt_evt_next(decoder, &event, sizeof(event)); + if (status < 0) + break; + + ... + } +~~~ + + +## The Query Layer + +The query layer provides an API for querying processor trace whenever a +non-obvious control-flow decision needs to be made. If further provides +information about asynchronous events. + This section describes how to use the query decoder for reconstructing execution flow. See the instruction flow decoder as an example. Start by configuring and allocating a `pt_query_decoder` as shown below: @@ -786,7 +896,7 @@ status = pt_insn_next(decoder, &insn, sizeof(insn)); - if (insn.iclass != ptic_error) + if (insn.iclass != ptic_unknown) <process instruction>(&insn); if (status < 0) @@ -890,7 +1000,7 @@ status = pt_insn_next(decoder, &insn, sizeof(insn)); - if (insn.iclass != ptic_error) + if (insn.iclass != ptic_unknown) <process instruction>(&insn); if (status < 0) @@ -1265,7 +1375,19 @@ ## Threading -The decoder library API is not thread-safe. Different threads may allocate and -use different decoder objects at the same time. Different decoders must not use -the same image object. Use `pt_image_copy()` to give each decoder its own copy -of a shared master image. +The decoder library API is *partly* thread-safe. Specifically: + + * It's OK for different threads to allocate and use *different* decoder + objects at the same time, but no single decoder object can be used + concurrently by different threads. A decoder allocated in one thread may be + passed to, and used from, another thread, as long as the decoder is not used + concurrently. + + * Different decoder objects must not use the same image object, even if the + decoders are owned by the same thread. You can, however, use + `pt_image_copy()` to give each decoder its own copy of a shared master + image. Copying an image is lightweight and does not copy large amounts of + data. + + * Image section cache objects *can* be shared across threads and be used + concurrently, but only if you build libipt with `FEATURE_THREADS=ON`.
View file
_service:tar_scm:v2.0.5.tar.gz/doc/howto_pttc.md -> _service:tar_scm:v2.1.tar.gz/doc/howto_pttc.md
Changed
@@ -2,7 +2,8 @@ =========================================================================== <!--- - ! Copyright (c) 2013-2022, Intel Corporation + ! Copyright (c) 2013-2023, Intel Corporation + ! SPDX-License-Identifier: BSD-3-Clause ! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/doc/man/CMakeLists.txt -> _service:tar_scm:v2.1.tar.gz/doc/man/CMakeLists.txt
Changed
@@ -1,4 +1,5 @@ -# Copyright (c) 2015-2022, Intel Corporation +# Copyright (c) 2015-2023, Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: @@ -66,11 +67,11 @@ pt_pkt_alloc_decoder pt_pkt_sync_forward pt_pkt_get_offset + pt_evt_next pt_qry_alloc_decoder pt_qry_sync_forward pt_qry_get_offset pt_qry_cond_branch - pt_qry_event pt_qry_time pt_image_alloc pt_image_add_file @@ -121,8 +122,9 @@ add_man_page_alias(3 pt_qry_time pt_insn_core_bus_ratio) add_man_page_alias(3 pt_qry_time pt_blk_time) add_man_page_alias(3 pt_qry_time pt_blk_core_bus_ratio) -add_man_page_alias(3 pt_qry_event pt_insn_event) -add_man_page_alias(3 pt_qry_event pt_blk_event) +add_man_page_alias(3 pt_evt_next pt_qry_event) +add_man_page_alias(3 pt_evt_next pt_insn_event) +add_man_page_alias(3 pt_evt_next pt_blk_event) add_man_page_alias(3 pt_image_alloc pt_image_free) add_man_page_alias(3 pt_image_alloc pt_image_name) add_man_page_alias(3 pt_image_add_file pt_image_copy)
View file
_service:tar_scm:v2.0.5.tar.gz/doc/man/pt_alloc_encoder.3.md -> _service:tar_scm:v2.1.tar.gz/doc/man/pt_alloc_encoder.3.md
Changed
@@ -1,7 +1,8 @@ % PT_ALLOC_ENCODER(3) <!--- - ! Copyright (c) 2015-2022, Intel Corporation + ! Copyright (c) 2015-2023, Intel Corporation + ! SPDX-License-Identifier: BSD-3-Clause ! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/doc/man/pt_blk_alloc_decoder.3.md -> _service:tar_scm:v2.1.tar.gz/doc/man/pt_blk_alloc_decoder.3.md
Changed
@@ -1,7 +1,8 @@ % PT_BLK_ALLOC_DECODER(3) <!--- - ! Copyright (c) 2016-2022, Intel Corporation + ! Copyright (c) 2016-2023, Intel Corporation + ! SPDX-License-Identifier: BSD-3-Clause ! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/doc/man/pt_blk_get_offset.3.md -> _service:tar_scm:v2.1.tar.gz/doc/man/pt_blk_get_offset.3.md
Changed
@@ -1,7 +1,8 @@ % PT_BLK_GET_OFFSET(3) <!--- - ! Copyright (c) 2016-2022, Intel Corporation + ! Copyright (c) 2016-2023, Intel Corporation + ! SPDX-License-Identifier: BSD-3-Clause ! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/doc/man/pt_blk_next.3.md -> _service:tar_scm:v2.1.tar.gz/doc/man/pt_blk_next.3.md
Changed
@@ -1,7 +1,8 @@ % PT_BLK_NEXT(3) <!--- - ! Copyright (c) 2016-2022, Intel Corporation + ! Copyright (c) 2016-2023, Intel Corporation + ! SPDX-License-Identifier: BSD-3-Clause ! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions are met: @@ -94,9 +95,10 @@ /** The instruction class for the last instruction in this block. * - * This field may be set to ptic_error to indicate that the instruction - * class is not available. The block decoder may choose to not provide - * the instruction class in some cases for performance reasons. + * This field may be set to ptic_unknown to indicate that the + * instruction class is not available. The block decoder may choose to + * not provide the instruction class in some cases for performance + * reasons. */ enum pt_insn_class iclass; @@ -174,7 +176,7 @@ iclass : A coarse classification of the last instruction in the block. This may be - *ptic_error* to indicate that the classification is not available. + *ptic_unknown* to indicate that the classification is not available. The block decoder knows the instruction class of the instruction that ended the block most of the time. If it does, it provides this information to
View file
_service:tar_scm:v2.0.5.tar.gz/doc/man/pt_blk_sync_forward.3.md -> _service:tar_scm:v2.1.tar.gz/doc/man/pt_blk_sync_forward.3.md
Changed
@@ -1,7 +1,8 @@ % PT_BLK_SYNC_FORWARD(3) <!--- - ! Copyright (c) 2016-2022, Intel Corporation + ! Copyright (c) 2016-2023, Intel Corporation + ! SPDX-License-Identifier: BSD-3-Clause ! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/doc/man/pt_config.3.md -> _service:tar_scm:v2.1.tar.gz/doc/man/pt_config.3.md
Changed
@@ -1,7 +1,8 @@ % PT_CONFIG(3) <!--- - ! Copyright (c) 2015-2022, Intel Corporation + ! Copyright (c) 2015-2023, Intel Corporation + ! SPDX-License-Identifier: BSD-3-Clause ! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/doc/man/pt_enc_get_config.3.md -> _service:tar_scm:v2.1.tar.gz/doc/man/pt_enc_get_config.3.md
Changed
@@ -1,7 +1,8 @@ % PT_ENC_GET_CONFIG(3) <!--- - ! Copyright (c) 2015-2022, Intel Corporation + ! Copyright (c) 2015-2023, Intel Corporation + ! SPDX-License-Identifier: BSD-3-Clause ! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions are met: @@ -30,9 +31,9 @@ # NAME -pt_enc_get_config, pt_pkt_get_config, pt_qry_get_config, pt_insn_get_config, -pt_blk_get_config - get an Intel(R) Processor Trace encoder/decoder's -configuration +pt_enc_get_config, pt_pkt_get_config, pt_evt_get_config, pt_qry_get_config, +pt_insn_get_config, pt_blk_get_config - get an Intel(R) Processor Trace +encoder/decoder's configuration # SYNOPSIS @@ -46,6 +47,9 @@ | **pt_pkt_get_config(const struct pt_packet_decoder \**decoder*);** | | **const struct pt_config \*** +| **pt_evt_get_config(const struct pt_event_decoder \**decoder*);** +| +| **const struct pt_config \*** | **pt_qry_get_config(const struct pt_query_decoder \**decoder*);** | | **const struct pt_config \*** @@ -73,5 +77,5 @@ # SEE ALSO **pt_config**(3), **pt_alloc_encoder**(3), **pt_pkt_alloc_decoder**(3), -**pt_qry_alloc_decoder**(3), **pt_insn_alloc_decoder**(3), -**pt_blk_alloc_decoder**(3) +**pt_evt_alloc_decoder**(3), **pt_qry_alloc_decoder**(3)**, +**pt_insn_alloc_decoder**(3), **pt_blk_alloc_decoder**(3)
View file
_service:tar_scm:v2.0.5.tar.gz/doc/man/pt_enc_get_offset.3.md -> _service:tar_scm:v2.1.tar.gz/doc/man/pt_enc_get_offset.3.md
Changed
@@ -1,7 +1,8 @@ % PT_ENC_GET_OFFSET(3) <!--- - ! Copyright (c) 2015-2022, Intel Corporation + ! Copyright (c) 2015-2023, Intel Corporation + ! SPDX-License-Identifier: BSD-3-Clause ! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.1.tar.gz/doc/man/pt_evt_alloc_decoder.3.md
Added
@@ -0,0 +1,103 @@ +% PT_EVT_ALLOC_DECODER(3) + +<!--- + ! Copyright (c) 2015-2023, Intel Corporation + ! SPDX-License-Identifier: BSD-3-Clause + ! + ! Redistribution and use in source and binary forms, with or without + ! modification, are permitted provided that the following conditions are met: + ! + ! * Redistributions of source code must retain the above copyright notice, + ! this list of conditions and the following disclaimer. + ! * Redistributions in binary form must reproduce the above copyright notice, + ! this list of conditions and the following disclaimer in the documentation + ! and/or other materials provided with the distribution. + ! * Neither the name of Intel Corporation nor the names of its contributors + ! may be used to endorse or promote products derived from this software + ! without specific prior written permission. + ! + ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + ! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + ! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + ! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + ! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + ! POSSIBILITY OF SUCH DAMAGE. + !--> + +# NAME + +pt_evt_alloc_decoder, pt_evt_free_decoder - allocate/free an Intel(R) Processor +Trace event decoder + + +# SYNOPSIS + +| **\#include `<intel-pt.h>`** +| +| **struct pt_event_decoder \*** +| **pt_evt_alloc_decoder(const struct pt_config \**config*);** +| +| **void pt_evt_free_decoder(struct pt_event_decoder \**decoder*);** + +Link with *-lipt*. + + +# DESCRIPTION + +A event decoder decodes raw Intel Processor Trace (Intel PT) and combines Intel +PT packets into a stream of Intel PT events. + +This information can be used to reconstruct the execution flow of the traced +code. Decode instructions until the next event, then apply the event. + +**pt_evt_alloc_decoder**() allocates a new event decoder and returns a pointer +to it. The *config* argument points to a *pt_config* object. See +**pt_config**(3). The *config* argument will not be referenced by the returned +decoder but the trace buffer defined by the *config* argument's *begin* and +*end* fields will. + +The returned event decoder needs to be synchronized onto the trace stream before +it can be used. To synchronize the event decoder, use +**pt_evt_sync_forward**(3), **pt_evt_sync_backward**(3), or +**pt_evt_sync_set**(3). + +**pt_evt_free_decoder**() frees the Intel PT event decoder pointed to by +*decoder*. The *decoder* argument must be NULL or point to a decoder that has +been allocated by a call to **pt_evt_alloc_decoder**(). + + +# RETURN VALUE + +**pt_evt_alloc_decoder**() returns a pointer to a *pt_event_decoder* object on +success or NULL in case of an error. + + +# EXAMPLE + +~~~{.c} +int foo(const struct pt_config *config) { + struct pt_event_decoder *decoder; + errcode; + + decoder = pt_evt_alloc_decoder(config); + if (!decoder) + return -pte_nomem; + + errcode = bar(decoder); + + pt_evt_free_decoder(decoder); + return errcode; +} +~~~ + + +# SEE ALSO + +**pt_config**(3), **pt_evt_sync_forward**(3), **pt_evt_sync_backward**(3), +**pt_evt_sync_set**(3), **pt_evt_get_offset**(3), **pt_evt_get_sync_offset**(3), +**pt_evt_get_config**(3), **pt_evt_next**(3)
View file
_service:tar_scm:v2.1.tar.gz/doc/man/pt_evt_get_offset.3.md
Added
@@ -0,0 +1,82 @@ +% PT_EVT_GET_OFFSET(3) + +<!--- + ! Copyright (c) 2015-2023, Intel Corporation + ! SPDX-License-Identifier: BSD-3-Clause + ! + ! Redistribution and use in source and binary forms, with or without + ! modification, are permitted provided that the following conditions are met: + ! + ! * Redistributions of source code must retain the above copyright notice, + ! this list of conditions and the following disclaimer. + ! * Redistributions in binary form must reproduce the above copyright notice, + ! this list of conditions and the following disclaimer in the documentation + ! and/or other materials provided with the distribution. + ! * Neither the name of Intel Corporation nor the names of its contributors + ! may be used to endorse or promote products derived from this software + ! without specific prior written permission. + ! + ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + ! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + ! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + ! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + ! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + ! POSSIBILITY OF SUCH DAMAGE. + !--> + +# NAME + +pt_evt_get_offset, pt_evt_get_sync_offset - get an Intel(R) Processor Trace +event decoder's current/synchronization trace buffer offset + + +# SYNOPSIS + +| **\#include `<intel-pt.h>`** +| +| **int pt_evt_get_offset(const struct pt_event_decoder \**decoder*,** +| **uint64_t \**offset*);** +| **int pt_evt_get_sync_offset(const struct pt_event_decoder \**decoder*,** +| **uint64_t \**offset*);** + +Link with *-lipt*. + + +# DESCRIPTION + +**pt_evt_get_offset**() provides *decoder*'s current position as offset in +bytes from the beginning of *decoder*'s trace buffer in the unsigned integer +variable pointed to by *offset*. + +**pt_evt_get_sync_offset**() provides *decoder*'s last synchronization point as +offset in bytes from the beginning of *decoder*'s trace buffer in the unsigned +integer variable pointed to by *offset*. + + +# RETURN VALUE + +Both functions return zero on success or a negative *pt_error_code* enumeration +constant in case of an error. + + +# ERRORS + +pte_invalid +: The *decoder* or *offset* argument is NULL. + +pte_nosync +: *decoder* has not been synchronized onto the trace stream. Use + **pt_evt_sync_forward**(3), **pt_evt_sync_backward**(3), or + **pt_evt_sync_set**(3) to synchronize *decoder*. + + +# SEE ALSO + +**pt_evt_alloc_decoder**(3), **pt_evt_free_decoder**(3), +**pt_evt_sync_forward**(3), **pt_evt_sync_backward**(3), +**pt_evt_sync_set**(3), **pt_evt_get_config**(3), **pt_evt_next**(3)
View file
_service:tar_scm:v2.1.tar.gz/doc/man/pt_evt_next.3.md
Added
@@ -0,0 +1,308 @@ +% PT_EVT_NEXT(3) + +<!--- + ! Copyright (c) 2015-2023, Intel Corporation + ! SPDX-License-Identifier: BSD-3-Clause + ! + ! Redistribution and use in source and binary forms, with or without + ! modification, are permitted provided that the following conditions are met: + ! + ! * Redistributions of source code must retain the above copyright notice, + ! this list of conditions and the following disclaimer. + ! * Redistributions in binary form must reproduce the above copyright notice, + ! this list of conditions and the following disclaimer in the documentation + ! and/or other materials provided with the distribution. + ! * Neither the name of Intel Corporation nor the names of its contributors + ! may be used to endorse or promote products derived from this software + ! without specific prior written permission. + ! + ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + ! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + ! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + ! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + ! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + ! POSSIBILITY OF SUCH DAMAGE. + !--> + +# NAME + +pt_evt_next, pt_qry_event, pt_insn_event, pt_blk_event - query an Intel(R) +Processor Trace decoder for an (asynchronous) event + + +# SYNOPSIS + +| **\#include `<intel-pt.h>`** +| +| **int pt_evt_next(struct pt_event_decoder \**decoder*,** +| **struct pt_event \**event*, size_t *size*);** +| +| **int pt_qry_event(struct pt_query_decoder \**decoder*,** +| **struct pt_event \**event*, size_t *size*);** +| +| **int pt_insn_event(struct pt_insn_decoder \**decoder*,** +| **struct pt_event \**event*, size_t *size*);** +| +| **int pt_blk_event(struct pt_block_decoder \**decoder*,** +| **struct pt_event \**event*, size_t *size*);** + +Link with *-lipt*. + + +# DESCRIPTION + +**pt_evt_next**() provides the next Intel Processor Trace (Intel PT) event in +*decoder*'s Intel PT decode in the *pt_event* object pointed to by the *event* +argument. This function provides asynchronous events as well as synchronous +control-flow events. + +**pt_qry_event**(), **pt_insn_event**(), and **pt_blk_event**() provide the next +pending asynchronous event in *decoder*'s Intel PT decode in the *pt_event* +object pointed to by the *event* argument. Synchronous control-flow events are +interpreted by the decoder and will not be provided through this interface. + +The *size* argument must be set to *sizeof(struct pt_event)*. The function will +provide at most *size* bytes of the *pt_event* structure. A newer decoder +library may provide event types that are not yet defined. Those events may be +truncated. + +On success, detailed information about the event is provided in the *pt_event* +object pointed to by the *event* argument. The *pt_event* structure is declared +as: + +~~~{.c} +/** An event. */ +struct pt_event { + /** The type of the event. */ + enum pt_event_type type; + + /** A flag indicating that the event IP has been + * suppressed. + */ + uint32_t ip_suppressed:1; + + /** A flag indicating that the event is for status update. */ + uint32_t status_update:1; + + /** A flag indicating that the event has timing + * information. + */ + uint32_t has_tsc:1; + + /** The time stamp count of the event. + * + * This field is only valid if \@has_tsc is set. + */ + uint64_t tsc; + + /** The number of lost mtc and cyc packets. + * + * This gives an idea about the quality of the \@tsc. The + * more packets were dropped, the less precise timing is. + */ + uint32_t lost_mtc; + uint32_t lost_cyc; + + /* Reserved space for future extensions. */ + uint64_t reserved2; + + /** Event specific data. */ + union { + /** Event: enabled. */ + struct { + /** The address at which tracing resumes. */ + uint64_t ip; + + /** A flag indicating that tracing resumes from the IP + * at which tracing had been disabled before. + */ + uint32_t resumed:1; + } enabled; + + /** Event: disabled. */ + struct { + /** The destination of the first branch inside a + * filtered area. + * + * This field is not valid if \@ip_suppressed is set. + */ + uint64_t ip; + + /* The exact source ip needs to be determined using + * disassembly and the filter configuration. + */ + } disabled; + + ... + } variant; +}; +~~~ + +See the *intel-pt.h* header file for more detail. The common fields of the +*pt_event* structure are described in more detail below: + +type +: The type of the event as a *pt_event_type* enumeration, which is declared + as: + +~~~{.c} +/** Event types. */ +enum pt_event_type { + /* Tracing has been enabled/disabled. */ + ptev_enabled, + ptev_disabled, + + /* Tracing has been disabled asynchronously. */ + ptev_async_disabled, + + /* An asynchronous branch, e.g. interrupt. */ + ptev_async_branch, + + /* A synchronous paging event. */ + ptev_paging, + + /* An asynchronous paging event. */ + ptev_async_paging, + + /* Trace overflow. */ + ptev_overflow, + + /* An execution mode change. */ + ptev_exec_mode, + + /* A transactional execution state change. */ + ptev_tsx, + + /* Trace Stop. */ + ptev_stop, + + /* A synchronous vmcs event. */ + ptev_vmcs, + + /* An asynchronous vmcs event. */ + ptev_async_vmcs, + + /* Execution has stopped. */ + ptev_exstop, + + /* An MWAIT operation completed. */ + ptev_mwait, + + /* A power state was entered. */ + ptev_pwre, + + /* A power state was exited. */ + ptev_pwrx, + + /* A PTWRITE event. */ + ptev_ptwrite, + + /* A timing event. */ + ptev_tick, + + /* A core:bus ratio event. */ + ptev_cbr, + + /* A maintenance event. */ + ptev_mnt, + + /* An indirect branch event. */ + ptev_tip, + + /* A conditional branch indicator event. */ + ptev_tnt +}; +~~~ + +ip_suppressed +: A flag indicating whether the *ip* field in the event-dependent part is not + valid because the value has been suppressed in the trace. + +status_update +: A flag indicating whether the event is for updating the decoder's status. + Status update events originate from Intel PT packets in PSB+. + +has_tsc +: A flag indicating that the event's timing-related fields *tsc*, *lost_mtc*, + and *lost_cyc* are valid. + +tsc +: The last time stamp count before the event. Depending on the timing + configuration, the timestamp can be more or less precise. For + cycle-accurate tracing, event packets are typically CYC-eligible so the + timestamp should be cycle-accurate. + +lost_mtc, lost_cyc +: The number of lost MTC and CYC updates. An update is lost if the decoder + was not able to process an MTC or CYC packet due to missing information. + This can be either missing calibration or missing configuration information. + The number of lost MTC and CYC updates gives a rough idea about the quality + of the *tsc* field. + +variant +: This field contains event-specific information. See the *intel-pt.h* header + file for details. + + +# RETURN VALUE + +**pt_evt_next**(), **pt_qry_event**(), **pt_insn_event**(), and +**pt_blk_event**() return zero or a positive value on success or a negative +*pt_error_code* enumeration constant in case of an error. + +On success, **pt_qry_event**(), **pt_insn_event**(), and **pt_blk_event**() +return a bit-vector of *pt_status_flag* enumeration constants. The +*pt_status_flag* enumeration is declared as: + +~~~{.c} +/** Decoder status flags. */ +enum pt_status_flag { + /** There is an event pending. */ + pts_event_pending = 1 << 0, + + /** The address has been suppressed. */ + pts_ip_suppressed = 1 << 1, + + /** There is no more trace data available. */ + pts_eos = 1 << 2 +}; +~~~ + + +# ERRORS + +pte_invalid +: The *decoder* or *event* argument is NULL or the *size* argument is too + small. + +pte_eos +: Decode reached the end of the trace stream. + +pte_nosync +: The decoder has not been synchronized onto the trace stream. Use + **pt_evt_sync_forward**(3), **pt_evt_sync_backward**(3), or + **pt_evt_sync_set**(3) to synchronize *decoder*. + +pte_bad_opc +: The decoder encountered an unsupported Intel PT packet opcode. + +pte_bad_packet +: The decoder encountered an unsupported Intel PT packet payload. + +pte_bad_query +: The query does not match the data provided in the Intel PT stream. Based on + the trace, the decoder expected a call to **pt_qry_cond_branch**(3) or + **pt_qry_indirect_branch**(3). This usually means that execution flow + reconstruction and trace got out of sync. + + +# SEE ALSO + +**pt_evt_alloc_decoder**(3), **pt_evt_free_decoder**(3), +**pt_qry_cond_branch**(3), **pt_qry_indirect_branch**(3), **pt_insn_next**(3), +**pt_blk_next**(3)
View file
_service:tar_scm:v2.1.tar.gz/doc/man/pt_evt_sync_forward.3.md
Added
@@ -0,0 +1,127 @@ +% PT_EVT_SYNC_FORWARD(3) + +<!--- + ! Copyright (c) 2015-2023, Intel Corporation + ! SPDX-License-Identifier: BSD-3-Clause + ! + ! Redistribution and use in source and binary forms, with or without + ! modification, are permitted provided that the following conditions are met: + ! + ! * Redistributions of source code must retain the above copyright notice, + ! this list of conditions and the following disclaimer. + ! * Redistributions in binary form must reproduce the above copyright notice, + ! this list of conditions and the following disclaimer in the documentation + ! and/or other materials provided with the distribution. + ! * Neither the name of Intel Corporation nor the names of its contributors + ! may be used to endorse or promote products derived from this software + ! without specific prior written permission. + ! + ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + ! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + ! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + ! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + ! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + ! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + ! POSSIBILITY OF SUCH DAMAGE. + !--> + +# NAME + +pt_evt_sync_forward, pt_evt_sync_backward, pt_evt_sync_set - synchronize an +Intel(R) Processor Trace event decoder + + +# SYNOPSIS + +| **\#include `<intel-pt.h>`** +| +| **int pt_evt_sync_forward(struct pt_event_decoder \**decoder*);** +| **int pt_evt_sync_backward(struct pt_event_decoder \**decoder*);** +| **int pt_evt_sync_set(struct pt_event_decoder \**decoder*,** +| **uint64_t *offset*);** + +Link with *-lipt*. + + +# DESCRIPTION + +These functions synchronize an Intel Processor Trace (Intel PT) event decoder +pointed to by *decoder* onto the trace stream in *decoder*'s trace buffer. + +They search for a Packet Stream Boundary (PSB) packet in the trace stream and, +if successful, set *decoder*'s current position and synchronization position to +that packet and start processing packets. For synchronization to be +successful, there must be a full PSB+ header in the trace stream. + +**pt_evt_sync_forward**() searches in forward direction from *decoder*'s current +position towards the end of the trace buffer. If *decoder* has been newly +allocated and has not been synchronized yet, the search starts from the +beginning of the trace. + +**pt_evt_sync_backward**() searches in backward direction from *decoder*'s +current position towards the beginning of the trace buffer. If *decoder* has +been newly allocated and has not been synchronized yet, the search starts from +the end of the trace. + +**pt_evt_sync_set**() searches at *offset* bytes from the beginning of its trace +buffer. + + +# RETURN VALUE + +All synchronization functions return zero or a positive value on success or a +negative *pt_error_code* enumeration constant in case of an error. + + +# ERRORS + +pte_invalid +: The *decoder* argument is NULL. + +pte_eos +: There is no (further) PSB+ header in the trace stream + (**pt_evt_sync_forward**() and **pt_evt_sync_backward**()) or at *offset* + bytes into the trace buffer (**pt_evt_sync_set**()). + +pte_nosync +: There is no PSB packet at *offset* bytes from the beginning of the trace + (**pt_evt_sync_set**() only). + +pte_bad_opc +: The decoder encountered an unsupported Intel PT packet opcode. + +pte_bad_packet +: The decoder encountered an unsupported Intel PT packet payload. + + +# EXAMPLE + +The following example re-synchronizes an Intel PT event decoder after decode +errors: + +~~~{.c} +int foo(struct pt_event_decoder *decoder) { + for (;;) { + int errcode; + + errcode = pt_evt_sync_forward(decoder); + if (errcode < 0) + return errcode; + + do { + errcode = decode(decoder); + } while (errcode >= 0); + } +} +~~~ + + +# SEE ALSO + +**pt_evt_alloc_decoder**(3), **pt_evt_free_decoder**(3), +**pt_evt_get_offset**(3), **pt_evt_get_sync_offset**(3), +**pt_evt_get_config**(3), **pt_evt_next**(3) \ No newline at end of file
View file
_service:tar_scm:v2.0.5.tar.gz/doc/man/pt_image_add_file.3.md -> _service:tar_scm:v2.1.tar.gz/doc/man/pt_image_add_file.3.md
Changed
@@ -1,7 +1,8 @@ % PT_IMAGE_ADD_FILE(3) <!--- - ! Copyright (c) 2015-2022, Intel Corporation + ! Copyright (c) 2015-2023, Intel Corporation + ! SPDX-License-Identifier: BSD-3-Clause ! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/doc/man/pt_image_alloc.3.md -> _service:tar_scm:v2.1.tar.gz/doc/man/pt_image_alloc.3.md
Changed
@@ -1,7 +1,8 @@ % PT_IMAGE_ALLOC(3) <!--- - ! Copyright (c) 2015-2022, Intel Corporation + ! Copyright (c) 2015-2023, Intel Corporation + ! SPDX-License-Identifier: BSD-3-Clause ! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/doc/man/pt_image_remove_by_filename.3.md -> _service:tar_scm:v2.1.tar.gz/doc/man/pt_image_remove_by_filename.3.md
Changed
@@ -1,7 +1,8 @@ % PT_IMAGE_REMOVE_BY_FILENAME(3) <!--- - ! Copyright (c) 2015-2022, Intel Corporation + ! Copyright (c) 2015-2023, Intel Corporation + ! SPDX-License-Identifier: BSD-3-Clause ! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/doc/man/pt_image_set_callback.3.md -> _service:tar_scm:v2.1.tar.gz/doc/man/pt_image_set_callback.3.md
Changed
@@ -1,7 +1,8 @@ % PT_IMAGE_SET_CALLBACK(3) <!--- - ! Copyright (c) 2015-2022, Intel Corporation + ! Copyright (c) 2015-2023, Intel Corporation + ! SPDX-License-Identifier: BSD-3-Clause ! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/doc/man/pt_insn_alloc_decoder.3.md -> _service:tar_scm:v2.1.tar.gz/doc/man/pt_insn_alloc_decoder.3.md
Changed
@@ -1,7 +1,8 @@ % PT_INSN_ALLOC_DECODER(3) <!--- - ! Copyright (c) 2015-2022, Intel Corporation + ! Copyright (c) 2015-2023, Intel Corporation + ! SPDX-License-Identifier: BSD-3-Clause ! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/doc/man/pt_insn_get_image.3.md -> _service:tar_scm:v2.1.tar.gz/doc/man/pt_insn_get_image.3.md
Changed
@@ -1,7 +1,8 @@ % PT_INSN_GET_IMAGE(3) <!--- - ! Copyright (c) 2015-2022, Intel Corporation + ! Copyright (c) 2015-2023, Intel Corporation + ! SPDX-License-Identifier: BSD-3-Clause ! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/doc/man/pt_insn_get_offset.3.md -> _service:tar_scm:v2.1.tar.gz/doc/man/pt_insn_get_offset.3.md
Changed
@@ -1,7 +1,8 @@ % PT_INSN_GET_OFFSET(3) <!--- - ! Copyright (c) 2015-2022, Intel Corporation + ! Copyright (c) 2015-2023, Intel Corporation + ! SPDX-License-Identifier: BSD-3-Clause ! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/doc/man/pt_insn_next.3.md -> _service:tar_scm:v2.1.tar.gz/doc/man/pt_insn_next.3.md
Changed
@@ -1,7 +1,8 @@ % PT_INSN_NEXT(3) <!--- - ! Copyright (c) 2015-2022, Intel Corporation + ! Copyright (c) 2015-2023, Intel Corporation + ! SPDX-License-Identifier: BSD-3-Clause ! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions are met: @@ -143,8 +144,8 @@ * reconstructing the execution flow. */ enum pt_insn_class { - /* The instruction could not be classified. */ - ptic_error, + /* The instruction has not been classified. */ + ptic_unknown, /* The instruction is something not listed below. */ ptic_other, @@ -174,7 +175,13 @@ /* The instruction is a jump-like far transfer. * E.g. FAR JMP. */ - ptic_far_jump + ptic_far_jump, + + /* The instruction is a PTWRITE. */ + ptic_ptwrite, + + /* The instruction is an indirect jump or a far transfer. */ + ptic_indirect }; ~~~
View file
_service:tar_scm:v2.0.5.tar.gz/doc/man/pt_insn_sync_forward.3.md -> _service:tar_scm:v2.1.tar.gz/doc/man/pt_insn_sync_forward.3.md
Changed
@@ -1,7 +1,8 @@ % PT_INSN_SYNC_FORWARD(3) <!--- - ! Copyright (c) 2015-2022, Intel Corporation + ! Copyright (c) 2015-2023, Intel Corporation + ! SPDX-License-Identifier: BSD-3-Clause ! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/doc/man/pt_iscache_add_file.3.md -> _service:tar_scm:v2.1.tar.gz/doc/man/pt_iscache_add_file.3.md
Changed
@@ -1,7 +1,8 @@ % PT_ISCACHE_ADD_FILE(3) <!--- - ! Copyright (c) 2015-2022, Intel Corporation + ! Copyright (c) 2015-2023, Intel Corporation + ! SPDX-License-Identifier: BSD-3-Clause ! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/doc/man/pt_iscache_alloc.3.md -> _service:tar_scm:v2.1.tar.gz/doc/man/pt_iscache_alloc.3.md
Changed
@@ -1,7 +1,8 @@ % PT_ISCACHE_ALLOC(3) <!--- - ! Copyright (c) 2015-2022, Intel Corporation + ! Copyright (c) 2015-2023, Intel Corporation + ! SPDX-License-Identifier: BSD-3-Clause ! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/doc/man/pt_iscache_read.3.md -> _service:tar_scm:v2.1.tar.gz/doc/man/pt_iscache_read.3.md
Changed
@@ -1,7 +1,8 @@ % PT_ISCACHE_READ(3) <!--- - ! Copyright (c) 2015-2022, Intel Corporation + ! Copyright (c) 2015-2023, Intel Corporation + ! SPDX-License-Identifier: BSD-3-Clause ! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/doc/man/pt_iscache_set_limit.3.md -> _service:tar_scm:v2.1.tar.gz/doc/man/pt_iscache_set_limit.3.md
Changed
@@ -1,7 +1,8 @@ % PT_ISCACHE_SET_LIMIT(3) <!--- - ! Copyright (c) 2017-2022, Intel Corporation + ! Copyright (c) 2017-2023, Intel Corporation + ! SPDX-License-Identifier: BSD-3-Clause ! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/doc/man/pt_library_version.3.md -> _service:tar_scm:v2.1.tar.gz/doc/man/pt_library_version.3.md
Changed
@@ -1,7 +1,8 @@ % PT_LIBRARY_VERSION(3) <!--- - ! Copyright (c) 2015-2022, Intel Corporation + ! Copyright (c) 2015-2023, Intel Corporation + ! SPDX-License-Identifier: BSD-3-Clause ! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/doc/man/pt_packet.3.md -> _service:tar_scm:v2.1.tar.gz/doc/man/pt_packet.3.md
Changed
@@ -1,7 +1,8 @@ % PT_PACKET(3) <!--- - ! Copyright (c) 2015-2022, Intel Corporation + ! Copyright (c) 2015-2023, Intel Corporation + ! SPDX-License-Identifier: BSD-3-Clause ! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/doc/man/pt_pkt_alloc_decoder.3.md -> _service:tar_scm:v2.1.tar.gz/doc/man/pt_pkt_alloc_decoder.3.md
Changed
@@ -1,7 +1,8 @@ % PT_PKT_ALLOC_DECODER(3) <!--- - ! Copyright (c) 2015-2022, Intel Corporation + ! Copyright (c) 2015-2023, Intel Corporation + ! SPDX-License-Identifier: BSD-3-Clause ! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/doc/man/pt_pkt_get_offset.3.md -> _service:tar_scm:v2.1.tar.gz/doc/man/pt_pkt_get_offset.3.md
Changed
@@ -1,7 +1,8 @@ % PT_PKT_GET_OFFSET(3) <!--- - ! Copyright (c) 2015-2022, Intel Corporation + ! Copyright (c) 2015-2023, Intel Corporation + ! SPDX-License-Identifier: BSD-3-Clause ! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/doc/man/pt_pkt_sync_forward.3.md -> _service:tar_scm:v2.1.tar.gz/doc/man/pt_pkt_sync_forward.3.md
Changed
@@ -1,7 +1,8 @@ % PT_PKT_SYNC_FORWARD(3) <!--- - ! Copyright (c) 2015-2022, Intel Corporation + ! Copyright (c) 2015-2023, Intel Corporation + ! SPDX-License-Identifier: BSD-3-Clause ! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/doc/man/pt_qry_alloc_decoder.3.md -> _service:tar_scm:v2.1.tar.gz/doc/man/pt_qry_alloc_decoder.3.md
Changed
@@ -1,7 +1,8 @@ % PT_QRY_ALLOC_DECODER(3) <!--- - ! Copyright (c) 2015-2022, Intel Corporation + ! Copyright (c) 2015-2023, Intel Corporation + ! SPDX-License-Identifier: BSD-3-Clause ! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/doc/man/pt_qry_cond_branch.3.md -> _service:tar_scm:v2.1.tar.gz/doc/man/pt_qry_cond_branch.3.md
Changed
@@ -1,7 +1,8 @@ % PT_QRY_COND_BRANCH(3) <!--- - ! Copyright (c) 2015-2022, Intel Corporation + ! Copyright (c) 2015-2023, Intel Corporation + ! SPDX-License-Identifier: BSD-3-Clause ! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/doc/man/pt_qry_get_offset.3.md -> _service:tar_scm:v2.1.tar.gz/doc/man/pt_qry_get_offset.3.md
Changed
@@ -1,7 +1,8 @@ % PT_QRY_GET_OFFSET(3) <!--- - ! Copyright (c) 2015-2022, Intel Corporation + ! Copyright (c) 2015-2023, Intel Corporation + ! SPDX-License-Identifier: BSD-3-Clause ! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/doc/man/pt_qry_sync_forward.3.md -> _service:tar_scm:v2.1.tar.gz/doc/man/pt_qry_sync_forward.3.md
Changed
@@ -1,7 +1,8 @@ % PT_QRY_SYNC_FORWARD(3) <!--- - ! Copyright (c) 2015-2022, Intel Corporation + ! Copyright (c) 2015-2023, Intel Corporation + ! SPDX-License-Identifier: BSD-3-Clause ! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/doc/man/pt_qry_time.3.md -> _service:tar_scm:v2.1.tar.gz/doc/man/pt_qry_time.3.md
Changed
@@ -1,7 +1,8 @@ % PT_QRY_TIME(3) <!--- - ! Copyright (c) 2015-2022, Intel Corporation + ! Copyright (c) 2015-2023, Intel Corporation + ! SPDX-License-Identifier: BSD-3-Clause ! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.1.tar.gz/include/posix/pt_threads.h
Added
@@ -0,0 +1,257 @@ +/* + * Copyright (c) 2014-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * + * It looks like there is still no support for C11's threads.h. + * + * We implement the few features we actually need hoping that this file will + * soon go away. + */ + +#ifndef PT_THREADS_H +#define PT_THREADS_H + +#include <pthread.h> + +#if !defined(PTHREAD_MUTEX_NORMAL) && defined(PTHREAD_MUTEX_TIMED_NP) +# define PTHREAD_MUTEX_NORMAL PTHREAD_MUTEX_TIMED_NP +#endif + +#include <stdint.h> +#include <stdlib.h> + +enum { + thrd_success = 1, + thrd_error +}; + +struct pt_thread { + pthread_t thread; +}; +typedef struct pt_thread thrd_t; + +typedef int (*thrd_start_t)(void *); + + +struct thrd_args { + thrd_start_t fun; + void *arg; +}; + +static void *thrd_routine(void *arg) +{ + struct thrd_args *args; + int result; + + args = arg; + if (!args) + return (void *) (intptr_t) -1; + + result = -1; + if (args->fun) + result = args->fun(args->arg); + + free(args); + + return (void *) (intptr_t) result; +} + +static inline int thrd_create(thrd_t *thrd, thrd_start_t fun, void *arg) +{ + struct thrd_args *args; + int errcode; + + if (!thrd || !fun) + return thrd_error; + + args = malloc(sizeof(*args)); + if (!args) + return thrd_error; + + args->fun = fun; + args->arg = arg; + + errcode = pthread_create(&thrd->thread, NULL, thrd_routine, args); + if (errcode) { + free(args); + return thrd_error; + } + + return thrd_success; +} + +static inline int thrd_join(thrd_t thrd, int *res) +{ + void *result; + int errcode; + + errcode = pthread_join(thrd.thread, &result); + if (errcode) + return thrd_error; + + if (res) + *res = (int) (intptr_t) result; + + return thrd_success; +} + + +struct pt_mutex { + pthread_mutex_t mutex; +}; +typedef struct pt_mutex mtx_t; + +enum { + mtx_plain = PTHREAD_MUTEX_NORMAL +}; + +static inline int mtx_init(mtx_t *mtx, int type) +{ + int errcode; + + if (!mtx || type != mtx_plain) + return thrd_error; + + errcode = pthread_mutex_init(&mtx->mutex, NULL); + if (errcode) + return thrd_error; + + return thrd_success; +} + +static inline void mtx_destroy(mtx_t *mtx) +{ + if (mtx) + (void) pthread_mutex_destroy(&mtx->mutex); +} + +static inline int mtx_lock(mtx_t *mtx) +{ + int errcode; + + if (!mtx) + return thrd_error; + + errcode = pthread_mutex_lock(&mtx->mutex); + if (errcode) + return thrd_error; + + return thrd_success; +} + +static inline int mtx_unlock(mtx_t *mtx) +{ + int errcode; + + if (!mtx) + return thrd_error; + + errcode = pthread_mutex_unlock(&mtx->mutex); + if (errcode) + return thrd_error; + + return thrd_success; +} + + +struct pt_cond { + pthread_cond_t cond; +}; +typedef struct pt_cond cnd_t; + +static inline int cnd_init(cnd_t *cnd) +{ + int errcode; + + if (!cnd) + return thrd_error; + + errcode = pthread_cond_init(&cnd->cond, NULL); + if (errcode) + return thrd_error; + + return thrd_success; +} + +static inline int cnd_destroy(cnd_t *cnd) +{ + int errcode; + + if (!cnd) + return thrd_error; + + errcode = pthread_cond_destroy(&cnd->cond); + if (errcode) + return thrd_error; + + return thrd_success; +} + +static inline int cnd_signal(cnd_t *cnd) +{ + int errcode; + + if (!cnd) + return thrd_error; + + errcode = pthread_cond_signal(&cnd->cond); + if (errcode) + return thrd_error; + + return thrd_success; +} + +static inline int cnd_broadcast(cnd_t *cnd) +{ + int errcode; + + if (!cnd) + return thrd_error; + + errcode = pthread_cond_broadcast(&cnd->cond); + if (errcode) + return thrd_error; + + return thrd_success; +} + +static inline int cnd_wait(cnd_t *cnd, mtx_t *mtx) +{ + int errcode; + + if (!cnd || !mtx) + return thrd_error; + + errcode = pthread_cond_wait(&cnd->cond, &mtx->mutex); + if (errcode) + return thrd_error; + + return thrd_success; +} + +#endif /* PT_THREADS_H */
View file
_service:tar_scm:v2.0.5.tar.gz/include/pt_compiler.h -> _service:tar_scm:v2.1.tar.gz/include/pt_compiler.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2017-2022, Intel Corporation + * Copyright (c) 2017-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/include/pt_version.h -> _service:tar_scm:v2.1.tar.gz/include/pt_version.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2018-2022, Intel Corporation + * Copyright (c) 2018-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/include/windows/inttypes.h -> _service:tar_scm:v2.1.tar.gz/include/windows/inttypes.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.1.tar.gz/include/windows/pt_threads.h
Added
@@ -0,0 +1,237 @@ +/* + * Copyright (c) 2014-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * + * It looks like there is still no support for C11's threads.h. + * + * We implement the few features we actually need hoping that this file will + * soon go away. + */ + +#ifndef PT_THREADS_H +#define PT_THREADS_H + +#include "windows.h" + + +enum { + thrd_success = 1, + thrd_error +}; + + +struct pt_thread { + HANDLE handle; +}; +typedef struct pt_thread thrd_t; + +typedef int (*thrd_start_t)(void *); + + +struct thrd_args { + thrd_start_t fun; + void *arg; +}; + +static DWORD WINAPI thrd_routine(void *arg) +{ + struct thrd_args *args; + int result; + + args = (struct thrd_args *) arg; + if (!args) + return (DWORD) -1; + + result = -1; + if (args->fun) + result = args->fun(args->arg); + + free(args); + + return (DWORD) result; +} + +static inline int thrd_create(thrd_t *thrd, thrd_start_t fun, void *arg) +{ + struct thrd_args *args; + HANDLE handle; + + if (!thrd || !fun) + return thrd_error; + + args = malloc(sizeof(*args)); + if (!args) + return thrd_error; + + args->fun = fun; + args->arg = arg; + + handle = CreateThread(NULL, 0, thrd_routine, args, 0, NULL); + if (!handle) { + free(args); + return thrd_error; + } + + thrd->handle = handle; + return thrd_success; +} + +static inline int thrd_join(thrd_t thrd, int *res) +{ + DWORD status; + BOOL success; + + status = WaitForSingleObject(thrd.handle, INFINITE); + if (status) + return thrd_error; + + if (res) { + DWORD result; + + success = GetExitCodeThread(thrd.handle, &result); + if (!success) { + (void) CloseHandle(thrd.handle); + return thrd_error; + } + + *res = (int) result; + } + + success = CloseHandle(thrd.handle); + if (!success) + return thrd_error; + + return thrd_success; +} + +struct pt_mutex { + CRITICAL_SECTION cs; +}; +typedef struct pt_mutex mtx_t; + +enum { + mtx_plain +}; + +static inline int mtx_init(mtx_t *mtx, int type) +{ + if (!mtx || type != mtx_plain) + return thrd_error; + + InitializeCriticalSection(&mtx->cs); + + return thrd_success; +} + +static inline void mtx_destroy(mtx_t *mtx) +{ + if (mtx) + DeleteCriticalSection(&mtx->cs); +} + +static inline int mtx_lock(mtx_t *mtx) +{ + if (!mtx) + return thrd_error; + + EnterCriticalSection(&mtx->cs); + + return thrd_success; +} + +static inline int mtx_unlock(mtx_t *mtx) +{ + if (!mtx) + return thrd_error; + + LeaveCriticalSection(&mtx->cs); + + return thrd_success; +} + + +struct pt_cond { + CONDITION_VARIABLE cond; +}; +typedef struct pt_cond cnd_t; + +static inline int cnd_init(cnd_t *cnd) +{ + if (!cnd) + return thrd_error; + + InitializeConditionVariable(&cnd->cond); + + return thrd_success; +} + +static inline int cnd_destroy(cnd_t *cnd) +{ + if (!cnd) + return thrd_error; + + /* Nothing to do. */ + + return thrd_success; +} + +static inline int cnd_signal(cnd_t *cnd) +{ + if (!cnd) + return thrd_error; + + WakeConditionVariable(&cnd->cond); + + return thrd_success; +} + +static inline int cnd_broadcast(cnd_t *cnd) +{ + if (!cnd) + return thrd_error; + + WakeAllConditionVariable(&cnd->cond); + + return thrd_success; +} + +static inline int cnd_wait(cnd_t *cnd, mtx_t *mtx) +{ + BOOL success; + + if (!cnd || !mtx) + return thrd_error; + + success = SleepConditionVariableCS(&cnd->cond, &mtx->cs, INFINITE); + if (!success) + return thrd_error; + + return thrd_success; +} + +#endif /* PT_THREADS_H */
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/CMakeLists.txt -> _service:tar_scm:v2.1.tar.gz/libipt/CMakeLists.txt
Changed
@@ -1,4 +1,5 @@ -# Copyright (c) 2013-2022, Intel Corporation +# Copyright (c) 2013-2023, Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: @@ -36,6 +37,7 @@ set(LIBIPT_FILES src/pt_error.c src/pt_packet_decoder.c + src/pt_event_decoder.c src/pt_query_decoder.c src/pt_encoder.c src/pt_sync.c @@ -51,7 +53,6 @@ src/pt_asid.c src/pt_event_queue.c src/pt_packet.c - src/pt_decoder_function.c src/pt_config.c src/pt_insn.c src/pt_block_decoder.c @@ -98,9 +99,12 @@ set_target_properties(libipt PROPERTIES PREFIX "" + IMPORT_PREFIX "" PUBLIC_HEADER ${CMAKE_CURRENT_BINARY_DIR}/include/intel-pt.h VERSION ${PT_VERSION} SOVERSION ${PT_VERSION_MAJOR} + C_STANDARD 11 + C_STANDARD_REQUIRED ON ) install(TARGETS libipt @@ -127,7 +131,7 @@ add_ptunit_std_test(image src/pt_asid.c) add_ptunit_std_test(sync src/pt_packet.c) add_ptunit_std_test(config) -add_ptunit_std_test(image_section_cache) +add_ptunit_std_test(image_section_cache ${LIBIPT_SECTION_FILES}) add_ptunit_std_test(block_cache) add_ptunit_std_test(msec_cache) @@ -135,14 +139,13 @@ add_ptunit_c_test(query src/pt_encoder.c src/pt_last_ip.c - src/pt_packet_decoder.c + src/pt_event_decoder.c src/pt_sync.c src/pt_tnt_cache.c src/pt_time.c src/pt_event_queue.c src/pt_query_decoder.c src/pt_packet.c - src/pt_decoder_function.c src/pt_packet_decoder.c src/pt_config.c src/pt_time.c @@ -159,14 +162,26 @@ src/pt_packet_decoder.c src/pt_sync.c src/pt_packet.c - src/pt_decoder_function.c src/pt_config.c ) -add_ptunit_c_test(fetch - src/pt_decoder_function.c +add_ptunit_c_test(encoder src/pt_encoder.c src/pt_config.c ) +add_ptunit_c_test(packet_decoder + src/pt_packet_decoder.c + src/pt_packet.c + src/pt_config.c + src/pt_sync.c + src/pt_query_decoder.c + src/pt_event_decoder.c + src/pt_event_queue.c + src/pt_last_ip.c + src/pt_tnt_cache.c + src/pt_time.c +) +add_ptunit_c_test(insn_decoder ${LIBIPT_FILES}) +add_ptunit_c_test(block_decoder ${LIBIPT_FILES}) add_ptunit_cpp_test(cpp) add_ptunit_libraries(cpp libipt)
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/include/intel-pt.h.in -> _service:tar_scm:v2.1.tar.gz/libipt/include/intel-pt.h.in
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -45,6 +46,7 @@ * - Errors * - Configuration * - Packet encoder / decoder + * - Event decoder * - Query decoder * - Traced image * - Instruction flow decoder @@ -55,6 +57,7 @@ struct pt_encoder; struct pt_packet_decoder; +struct pt_event_decoder; struct pt_query_decoder; struct pt_insn_decoder; struct pt_block_decoder; @@ -374,14 +377,66 @@ /** End a block after a jump instruction. */ uint32_t end_on_jump:1; + +#if (LIBIPT_VERSION >= 0x201) + /** Preserve timing calibration on overflow. */ + uint32_t keep_tcal_on_ovf:1; + + /** Enable iflags events. + * + * Use this only when Event Tracing was enabled via + * IA32_RTIT_CTL31. + */ + uint32_t enable_iflags_events:1; +#endif } block; /** Flags for the instruction flow decoder. */ struct { /** Enable tick events for timing updates. */ uint32_t enable_tick_events:1; + +#if (LIBIPT_VERSION >= 0x201) + /** Preserve timing calibration on overflow. */ + uint32_t keep_tcal_on_ovf:1; + + /** Enable iflags events. + * + * Use this only when Event Tracing was enabled via + * IA32_RTIT_CTL31. + */ + uint32_t enable_iflags_events:1; +#endif } insn; +#if (LIBIPT_VERSION >= 0x201) + /** Flags for the query decoder. */ + struct { + /** Preserve timing calibration on overflow. */ + uint32_t keep_tcal_on_ovf:1; + + /** Enable iflags events. + * + * Use this only when Event Tracing was enabled via + * IA32_RTIT_CTL31. + */ + uint32_t enable_iflags_events:1; + } query; + + /** Flags for the event decoder. */ + struct { + /** Preserve timing calibration on overflow. */ + uint32_t keep_tcal_on_ovf:1; + + /** Enable iflags events. + * + * Use this only when Event Tracing was enabled via + * IA32_RTIT_CTL31. + */ + uint32_t enable_iflags_events:1; + } event; +#endif /* (LIBIPT_VERSION >= 0x201) */ + /* Reserve a few bytes for future extensions. */ uint32_t reserved4; } variant; @@ -555,7 +610,11 @@ ppt_mwait, ppt_pwre, ppt_pwrx, - ppt_ptw + ppt_ptw, +#if (LIBIPT_VERSION >= 0x201) + ppt_cfe, + ppt_evd, +#endif }; /** The IP compression. */ @@ -621,6 +680,14 @@ /** The mode.exec csd bit. */ uint32_t csd:1; + +#if (LIBIPT_VERSION >= 0x201) + /** The mode.exec if bit. + * + * Enable Event Tracing to get updates when IF changes. + */ + uint32_t iflag:1; +#endif }; static inline enum pt_exec_mode @@ -637,6 +704,7 @@ { struct pt_packet_mode_exec packet; + memset(&packet, 0, sizeof(packet)); switch (mode) { default: packet.csl = 1; @@ -645,17 +713,13 @@ case ptem_64bit: packet.csl = 1; - packet.csd = 0; break; case ptem_32bit: - packet.csl = 0; packet.csd = 1; break; case ptem_16bit: - packet.csl = 0; - packet.csd = 0; break; } @@ -823,6 +887,92 @@ return -pte_internal; } +#if (LIBIPT_VERSION >= 0x201) +/* Control-flow event types. */ +enum pt_cfe_type { + pt_cfe_intr = 0x01, + pt_cfe_iret = 0x02, + pt_cfe_smi = 0x03, + pt_cfe_rsm = 0x04, + pt_cfe_sipi = 0x05, + pt_cfe_init = 0x06, + pt_cfe_vmentry = 0x07, + pt_cfe_vmexit = 0x08, + pt_cfe_vmexit_intr = 0x09, + pt_cfe_shutdown = 0x0a, + pt_cfe_uintr = 0x0c, + pt_cfe_uiret = 0x0d, +}; + +/* Interrupt vectors defined in Table 6-1 in §6.5 of Vol.1 of the SDM. */ +enum pt_cfe_intr { + pt_cfe_intr_de = 0, /* Divide Error. */ + pt_cfe_intr_db = 1, /* Debug. */ + pt_cfe_intr_nmi = 2, /* Non Maskable Interrupt. */ + pt_cfe_intr_bp = 3, /* Breakpoint. */ + pt_cfe_intr_of = 4, /* Overflow. */ + pt_cfe_intr_br = 5, /* Bound Range Exceeded. */ + pt_cfe_intr_ud = 6, /* Undefined Opcode. */ + pt_cfe_intr_nm = 7, /* Device Not Available. */ + pt_cfe_intr_df = 8, /* Double Fault. */ + pt_cfe_intr_ts = 10, /* Invalid TSS. */ + pt_cfe_intr_np = 11, /* Segment Not Present. */ + pt_cfe_intr_ss = 12, /* Stack Segment Fault. */ + pt_cfe_intr_gp = 13, /* General Protection Fault. */ + pt_cfe_intr_pf = 14, /* Page Fault. */ + pt_cfe_intr_mf = 16, /* Math Fault. */ + pt_cfe_intr_ac = 17, /* Alignment Check. */ + pt_cfe_intr_mc = 18, /* Machine Check. */ + pt_cfe_intr_xm = 19, /* SIMD Floating Point Exception. */ + pt_cfe_intr_ve = 20, /* Virtualization Exception. */ + pt_cfe_intr_cp = 21, /* Control Protection Exception. */ +}; + +/** A CFE packet. */ +struct pt_packet_cfe { + /** The type of control-flow event. */ + enum pt_cfe_type type; + + /** The vector depending on the type: + * + * pt_cfe_intr: the event vector. + * pt_cfe_vmexit_intr: the event vector. + * pt_cfe_sipi: the SIPI vector. + * pt_cfe_uintr: the user interrupt vector. + */ + uint8_t vector; + + /** A flag specifying the binding of the packet: + * + * set: binds to the next FUP. + * clear: binds to the next FUP + TIP, if tracing enabled. + * clear: standalone, if tracing disabled. + */ + uint32_t ip:1; +}; + +/* Event data types. */ +enum pt_evd_type { + pt_evd_cr2 = 0x00, /* Page fault linear address (cr2). */ + pt_evd_vmxq = 0x01, /* VMX exit qualification. */ + pt_evd_vmxr = 0x02, /* VMX exit reason. */ +}; + +/** A EVD packet. */ +struct pt_packet_evd { + /** The type of control-flow event. */ + enum pt_evd_type type; + + /** The payload depending on the type: + * + * 0x00: page fault linear address (cr2). + * 0x01: vmx exit qualification. + * 0x02: vmx exit reason. + */ + uint64_t payload; +}; +#endif /* (LIBIPT_VERSION >= 0x201) */ + /** An unknown packet decodable by the optional decoder callback. */ struct pt_packet_unknown { /** Pointer to the raw packet bytes. */ @@ -895,6 +1045,13 @@ /** Packet: ptw. */ struct pt_packet_ptw ptw; +#if (LIBIPT_VERSION >= 0x201) + /** Packet: cfe. */ + struct pt_packet_cfe cfe; + + /** Packet: evd. */ + struct pt_packet_evd evd; +#endif /** Packet: unknown. */ struct pt_packet_unknown unknown; } payload; @@ -1083,21 +1240,9 @@ -/* Query decoder. */ - - - -/** Decoder status flags. */ -enum pt_status_flag { - /** There is an event pending. */ - pts_event_pending = 1 << 0, +/* Event decoder. */ - /** The address has been suppressed. */ - pts_ip_suppressed = 1 << 1, - /** There is no more trace data available. */ - pts_eos = 1 << 2 -}; /** Event types. */ enum pt_event_type { @@ -1157,7 +1302,55 @@ ptev_cbr, /* A maintenance event. */ - ptev_mnt + ptev_mnt, + +#if (LIBIPT_VERSION >= 0x201) + /* An indirect branch event. */ + ptev_tip, + + /* A conditional branch indicator event. */ + ptev_tnt, + + /* An interrupt status event. */ + ptev_iflags, + + /* An interrupt or exception event. + * + * This event extends the async_branch event generated for the + * control-flow change; it does not replace that event. + */ + ptev_interrupt, + + /* A return from interrupt event. */ + ptev_iret, + + /* A system management interrupt. */ + ptev_smi, + + /* A return from system management mode. */ + ptev_rsm, + + /* A SIPI message. */ + ptev_sipi, + + /* An INIT reset. */ + ptev_init, + + /* A Virtual Machine entry. */ + ptev_vmentry, + + /* A Virtual Machine exit. */ + ptev_vmexit, + + /* A shutdown event. */ + ptev_shutdown, + + /* A user interrupt. */ + ptev_uintr, + + /* A return from user interrupt. */ + ptev_uiret, +#endif }; /** An event. */ @@ -1436,7 +1629,8 @@ /** Event: tick. */ struct { - /** The instruction address near which the tick occured. + /** The instruction address near which the tick + * occurred. * * A timestamp can sometimes be attributed directly to * an instruction (e.g. to an indirect branch that @@ -1458,10 +1652,325 @@ /** The raw payload. */ uint64_t payload; } mnt; + +#if (LIBIPT_VERSION >= 0x201) + /** Event: tip. */ + struct { + /** The target instruction address. */ + uint64_t ip; + } tip; + + /** Event: tnt. */ + struct { + /** A sequence of conditional branch indicator bits. + * + * Indicators are ordered from oldest (bitssize-1) to + * youngest (bits0) branch: + * + * 0...branch not taken + * 1...branch taken + */ + uint64_t bits; + + /** The number of valid bits in @bits. */ + uint8_t size; + } tnt; + + /** Event: iflags. */ + struct { + /** The EFLAGS.IF status. */ + uint32_t iflag:1; + + /** The address of the instruction at which the new + * status applies. + * + * This field is not valid, if \@ip_suppressed is set. + */ + uint64_t ip; + } iflags; + + /** Event: interrupt/exception. */ + struct { + /** A flag saying whether the \@cr2 field is valid. */ + uint32_t has_cr2:1; + + /** The interrupt/exception vector. */ + uint8_t vector; + + /** The page fault linear address in cr2. + * + * This field is only valid if \@has_cr2 is set. + */ + uint64_t cr2; + + /** The address of the instruction at which the + * interrupt or exception occurred. + * + * For faults, this will be the faulting instruction. + * For traps, this will be the next instruction. + * + * This field is not valid, if \@ip_suppressed is set. + */ + uint64_t ip; + } interrupt; + + /** Event: iret. */ + struct { + /** The address of the instruction. + * + * This field is not valid, if \@ip_suppressed is set. + */ + uint64_t ip; + } iret; + + /** Event: smi. */ + struct { + /** The address of the instruction at/before which the + * system management interrupt occurred. + * + * This field is not valid, if \@ip_suppressed is set. + */ + uint64_t ip; + } smi; + + /** Event: rsm. */ + struct { + /** The address of the instruction. + * + * This field is not valid, if \@ip_suppressed is set. + */ + uint64_t ip; + } rsm; + + /** Event: sipi. */ + struct { + /** The SIPI vector. */ + uint8_t vector; + } sipi; + + /** Event: init. */ + struct { + /** The address of the instruction. + * + * This field is not valid, if \@ip_suppressed is set. + */ + uint64_t ip; + } init; + + /** Event: vmentry. */ + struct { + /** The address of the instruction. + * + * This field is not valid, if \@ip_suppressed is set. + */ + uint64_t ip; + } vmentry; + + /** Event: vmexit. */ + struct { + /** A flag saying whether the \@vector field is valid. + * + * When set, the vmexit occurred due to an interrupt or + * exception. + */ + uint32_t has_vector:1; + + /** A flag saying whether the \@vmxr field is valid. */ + uint32_t has_vmxr:1; + + /** A flag saying whether the \@vmxq field is valid. */ + uint32_t has_vmxq:1; + + /** The interrupt/exception vector. + * + * This field is only valid if \@has_vector is set. + */ + uint8_t vector; + + /** The vmexit reason. + * + * This field is only valid if \@has_vmxr is set. + */ + uint64_t vmxr; + + /** The vmexit qualification. + * + * This field is only valid if \@has_vmxq is set. + */ + uint64_t vmxq; + + /** The address of the instruction at which the + * interrupt or exception occurred. + * + * For faults, this will be the faulting instruction. + * For traps, this will be the next instruction. + * + * This field is not valid, if \@ip_suppressed is set. + */ + uint64_t ip; + } vmexit; + + /** Event: shutdown. */ + struct { + /** The address of the first instruction that did not + * complete due to the shutdown. + * + * This field is not valid, if \@ip_suppressed is set. + */ + uint64_t ip; + } shutdown; + + /** Event: user interrupt. */ + struct { + /** The user interrupt vector. */ + uint8_t vector; + + /** The address of the instruction before which the + * user interrupt was delivered. + * + * This field is not valid, if \@ip_suppressed is set. + */ + uint64_t ip; + } uintr; + + /** Event: uiret. */ + struct { + /** The address of the instruction. + * + * This field is not valid, if \@ip_suppressed is set. + */ + uint64_t ip; + } uiret; +#endif /* (LIBIPT_VERSION >= 0x201) */ } variant; }; +#if (LIBIPT_VERSION >= 0x201) +/** Allocate an Intel PT event decoder. + * + * The decoder will work on the buffer defined in \@config, it shall contain + * raw trace data and remain valid for the lifetime of the decoder. + * + * The decoder needs to be synchronized before it can be used. + */ +extern pt_export struct pt_event_decoder * +pt_evt_alloc_decoder(const struct pt_config *config); + +/** Free an Intel PT event decoder. + * + * The \@decoder must not be used after a successful return. + */ +extern pt_export void pt_evt_free_decoder(struct pt_event_decoder *decoder); + +/** Synchronize an Intel PT event decoder. + * + * Search for the next synchronization point in forward or backward direction. + * + * If \@decoder has not been synchronized, yet, the search is started at the + * beginning of the trace buffer in case of forward synchronization and at the + * end of the trace buffer in case of backward synchronization. + * + * Returns zero or a positive value on success, a negative error code otherwise. + * + * Returns -pte_bad_opc if an unknown packet is encountered. + * Returns -pte_bad_packet if an unknown packet payload is encountered. + * Returns -pte_eos if no further synchronization point is found. + * Returns -pte_invalid if \@decoder is NULL. + */ +extern pt_export int pt_evt_sync_forward(struct pt_event_decoder *decoder); +extern pt_export int pt_evt_sync_backward(struct pt_event_decoder *decoder); + +/** Manually synchronize an Intel PT event decoder. + * + * Synchronize \@decoder on the syncpoint at \@offset. There must be a PSB + * packet at \@offset. + * + * Returns zero or a positive value on success, a negative error code otherwise. + * + * Returns -pte_bad_opc if an unknown packet is encountered. + * Returns -pte_bad_packet if an unknown packet payload is encountered. + * Returns -pte_eos if \@offset lies outside of \@decoder's trace buffer. + * Returns -pte_eos if \@decoder reaches the end of its trace buffer. + * Returns -pte_invalid if \@decoder is NULL. + * Returns -pte_nosync if there is no syncpoint at \@offset. + */ +extern pt_export int pt_evt_sync_set(struct pt_event_decoder *decoder, + uint64_t offset); + +/** Get the current decoder position. + * + * Fills the current \@decoder position into \@offset. + * + * This is useful for reporting errors. + * + * Returns zero on success, a negative error code otherwise. + * + * Returns -pte_invalid if \@decoder or \@offset is NULL. + * Returns -pte_nosync if \@decoder is out of sync. + */ +extern pt_export int pt_evt_get_offset(const struct pt_event_decoder *decoder, + uint64_t *offset); + +/** Get the position of the last synchronization point. + * + * Fills the last synchronization position into \@offset. + * + * This is useful for splitting a trace stream for parallel decoding. + * + * Returns zero on success, a negative error code otherwise. + * + * Returns -pte_invalid if \@decoder or \@offset is NULL. + * Returns -pte_nosync if \@decoder is out of sync. + */ +extern pt_export int +pt_evt_get_sync_offset(const struct pt_event_decoder *decoder, + uint64_t *offset); + +/* Return a pointer to \@decoder's configuration. + * + * Returns a non-null pointer on success, NULL if \@decoder is NULL. + */ +extern pt_export const struct pt_config * +pt_evt_get_config(const struct pt_event_decoder *decoder); + +/** Determine the next event. + * + * On success, provides the next event in \@event. + * + * The \@size argument must be set to sizeof(struct pt_event). + * + * Returns zero or a positive value on success, a negative error code + * otherwise. + * + * Returns -pte_bad_opc if the packet is unknown. + * Returns -pte_bad_packet if an unknown packet payload is encountered. + * Returns -pte_eos if \@decoder reached the end of the Intel PT buffer. + * Returns -pte_invalid if \@decoder or \@event is NULL. + * Returns -pte_nosync if \@decoder is out of sync. + */ +extern pt_export int pt_evt_next(struct pt_event_decoder *decoder, + struct pt_event *event, size_t size); +#endif /* (LIBIPT_VERSION >= 0x201) */ + + + +/* Query decoder. */ + + + +/** Decoder status flags. */ +enum pt_status_flag { + /** There is an event pending. */ + pts_event_pending = 1 << 0, + + /** The address has been suppressed. */ + pts_ip_suppressed = 1 << 1, + + /** There is no more trace data available. */ + pts_eos = 1 << 2 +}; + /** Allocate an Intel PT query decoder. * * The decoder will work on the buffer defined in \@config, it shall contain @@ -1913,8 +2422,16 @@ * the execution flow. */ enum pt_insn_class { - /* The instruction could not be classified. */ +#if (LIBIPT_VERSION >= 0x201) + /* The instruction has not been classified. */ + ptic_unknown, + + /* For backwards compatibility. */ + ptic_error = ptic_unknown, +#else + /* The instruction has not been classified. */ ptic_error, +#endif /* The instruction is something not listed below. */ ptic_other, @@ -1947,7 +2464,12 @@ ptic_far_jump, /* The instruction is a PTWRITE. */ - ptic_ptwrite + ptic_ptwrite, + +#if (LIBIPT_VERSION >= 0x201) + /* The instruction is an indirect jump or a far transfer. */ + ptic_indirect, +#endif }; /** The maximal size of an instruction. */ @@ -2236,9 +2758,10 @@ /** The instruction class for the last instruction in this block. * - * This field may be set to ptic_error to indicate that the instruction - * class is not available. The block decoder may choose to not provide - * the instruction class in some cases for performance reasons. + * This field may be set to ptic_unknown (ptic_error prior to v2.1) to + * indicate that the instruction class is not available. The block + * decoder may choose to not provide the instruction class in some + * cases for performance reasons. */ enum pt_insn_class iclass;
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/internal/include/posix/pt_section_posix.h -> _service:tar_scm:v2.1.tar.gz/libipt/internal/include/posix/pt_section_posix.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2015-2022, Intel Corporation + * Copyright (c) 2015-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/internal/include/pt_asid.h -> _service:tar_scm:v2.1.tar.gz/libipt/internal/include/pt_asid.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2014-2022, Intel Corporation + * Copyright (c) 2014-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/internal/include/pt_block_cache.h -> _service:tar_scm:v2.1.tar.gz/libipt/internal/include/pt_block_cache.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2016-2022, Intel Corporation + * Copyright (c) 2016-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -33,6 +34,13 @@ #include <stdint.h> +#if !defined(__STDC_NO_ATOMICS__) +# include <stdatomic.h> +# define PT_ATOMIC _Atomic +#else +# define PT_ATOMIC /* nothing */ +#endif + /* A block cache entry qualifier. * @@ -184,8 +192,15 @@ /* The number of cache entries. */ uint32_t nentries; - /* A variable-length array of @nentries entries. */ - struct pt_bcache_entry entry; + /* A variable-length array of @nentries entries. + * + * We access entries without locking. + * + * We use atomic operations, if supported, and rely on guaranteed + * atomic operations, otherwise. See section 8.1.1 in Volume 3A of the + * Intel(R) Software Developer's Manual at http://www.intel.com/sdm. + */ + struct pt_bcache_entry PT_ATOMIC entry; }; /* Create a block cache. @@ -219,7 +234,6 @@ * Returns -pte_internal if @index is outside of @bcache. */ extern int pt_bcache_lookup(struct pt_bcache_entry *bce, - const struct pt_block_cache *bcache, - uint64_t index); + struct pt_block_cache *bcache, uint64_t index); #endif /* PT_BLOCK_CACHE_H */
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/internal/include/pt_block_decoder.h -> _service:tar_scm:v2.1.tar.gz/libipt/internal/include/pt_block_decoder.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2016-2022, Intel Corporation + * Copyright (c) 2016-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -29,7 +30,7 @@ #ifndef PT_BLOCK_DECODER_H #define PT_BLOCK_DECODER_H -#include "pt_query_decoder.h" +#include "pt_event_decoder.h" #include "pt_image.h" #include "pt_retstack.h" #include "pt_ild.h" @@ -43,8 +44,8 @@ * of trace. */ struct pt_block_decoder { - /* The Intel(R) Processor Trace query decoder. */ - struct pt_query_decoder query; + /* The event decoder. */ + struct pt_event_decoder evdec; /* The configuration flags. * @@ -65,7 +66,17 @@ /* The current address space. */ struct pt_asid asid; - /* The current Intel(R) Processor Trace event. */ + /* The current event. + * + * This will be valid as long as there are events available, i.e. until + * @status is not negative. + * + * The decoder starts by reading the first event after synchronizing + * onto the trace stream. + * + * When it is done processing an event, it fetches the next event for + * the next iteration. + */ struct pt_event event; /* The call/return stack for ret compression. */ @@ -85,14 +96,22 @@ */ uint64_t ip; + /* The last TSC. + * + * We use it to check for time updates when generating tick events. + */ + uint64_t tsc; + + /* The number of lost MTC and CYC packets. */ + uint32_t lost_mtc, lost_cyc; + + /* The last CBR. */ + uint32_t cbr; + /* The current execution mode. */ enum pt_exec_mode mode; - /* The status of the last successful decoder query. - * - * Errors are reported directly; the status is always a non-negative - * pt_status_flag bit-vector. - */ + /* The last status of the event decoder. */ int status; /* A collection of flags defining how to proceed flow reconstruction: @@ -101,12 +120,12 @@ */ uint32_t enabled:1; - /* - process @event. */ - uint32_t process_event:1; - /* - instructions are executed speculatively. */ uint32_t speculative:1; + /* - whether @tsc tracks wall-clock time. */ + uint32_t has_tsc:1; + /* - process @insn/@iext. * * We have started processing events binding to @insn/@iext. The @@ -126,6 +145,15 @@ /* - a ptwrite event has already been bound to @insn/@iext. */ uint32_t bound_ptwrite:1; + + /* - an iret event has already been bound to @insn/@iext. */ + uint32_t bound_iret:1; + + /* - a vmentry event has already been bound to @insn/@iext. */ + uint32_t bound_vmentry:1; + + /* - an uiret event has already been bound to @insn/@iext. */ + uint32_t bound_uiret:1; }; @@ -140,4 +168,21 @@ /* Finalize a block decoder. */ extern void pt_blk_decoder_fini(struct pt_block_decoder *decoder); +static inline const struct pt_config * +pt_blk_config(const struct pt_block_decoder *decoder) +{ + if (!decoder) + return NULL; + + return pt_evt_config(&decoder->evdec); +} + +static inline const uint8_t *pt_blk_pos(const struct pt_block_decoder *decoder) +{ + if (!decoder) + return NULL; + + return pt_evt_pos(&decoder->evdec); +} + #endif /* PT_BLOCK_DECODER_H */
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/internal/include/pt_config.h -> _service:tar_scm:v2.1.tar.gz/libipt/internal/include/pt_config.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2015-2022, Intel Corporation + * Copyright (c) 2015-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/internal/include/pt_cpu.h -> _service:tar_scm:v2.1.tar.gz/libipt/internal/include/pt_cpu.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -41,14 +42,4 @@ */ extern int pt_cpu_parse(struct pt_cpu *cpu, const char *s); -/* Get the cpu we're running on. - * - * Reads the family/model/stepping of the processor on which this function - * is executed and stores the value in @cpu. - * - * Returns zero on success, a negative error code otherwise. - * Returns -pte_invalid if @cpu is NULL. - */ -extern int pt_cpu_read(struct pt_cpu *cpu); - #endif /* PT_CPU_H */
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/internal/include/pt_encoder.h -> _service:tar_scm:v2.1.tar.gz/libipt/internal/include/pt_encoder.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2014-2022, Intel Corporation + * Copyright (c) 2014-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.1.tar.gz/libipt/internal/include/pt_event_decoder.h
Added
@@ -0,0 +1,170 @@ +/* + * Copyright (c) 2018-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef PT_EVENT_DECODER_H +#define PT_EVENT_DECODER_H + +#include "pt_packet_decoder.h" +#include "pt_event_queue.h" +#include "pt_last_ip.h" +#include "pt_time.h" + +#include "intel-pt.h" + + +/* An Intel PT event decoder. + * + * It decodes sequences of Intel PT packets into events. + */ +struct pt_event_decoder { + /* The Intel PT packet decoder. */ + struct pt_packet_decoder pacdec; + + /* The configuration flags. + * + * Those are our flags set by the user. In @pacdec.config.flags, we + * set the flags we need for the packet decoder. + */ + struct pt_conf_flags flags; + + /* The current packet to be processed. + * + * This will be valid as long as there are packets available. It will + * be of type ppt_invalid when the packet decoder returned an error + * (which will be stored in @status). + * + * The decoder starts by reading the first packet after synchronizing + * onto the trace stream. + * + * When it is done processing a packet, it fetches the next packet for + * the next iteration. + */ + struct pt_packet packet; + + /* The last-ip. */ + struct pt_last_ip ip; + + /* Timing information. */ + struct pt_time time; + + /* Timing calibration. */ + struct pt_time_cal tcal; + + /* Pending (incomplete) events. */ + struct pt_event_queue evq; + + /* The current event. */ + struct pt_event *event; + + /* The last status of the packet decoder. + * + * It will be zero most of the time. Since we fetch new packets at the + * end of an iteration, we need to store the status until the next + * pt_evt_next() call. + */ + int status; + + /* The current mode.exec state. + * + * This is updated when processing mode.exec packets and it is used for + * mapping mode.exec packets to events depending on which part of the + * state changed. + * + * Since we use only one bit for each piece, we need a separate valid + * flag. The below mode.exec state bits are only valid if + * @mode_exec_valid is set. + */ + unsigned int mode_exec_valid:1; + unsigned int iflag:1; + unsigned int csd:1; + unsigned int csl:1; + + /* A collection of flags saying whether: + * + * - tracing is enabled. + */ + unsigned int enabled:1; + + /* - the current packet is already bound and must not be interpreted as + * standalone packet once events have been processed. + */ + unsigned int bound:1; +}; + +/* A special, internal-only event type used for binding packets without + * generating an event. + * + * We alias the tick event since compilers diagnose values outside of the + * enumerated type in switch statements and we want to keep compilers to + * diagnose unhandled cases, which is guarded by the same compiler option. + * + * The tick event is synthesized by higher-level decoders and does not appear + * on event level. + */ +#define ptev_ignore ptev_tick + +/* Initialize the event decoder. + * + * Returns zero on success, a negative error code otherwise. + */ +extern int pt_evt_decoder_init(struct pt_event_decoder *decoder, + const struct pt_config *config); + +/* Finalize the event decoder. */ +extern void pt_evt_decoder_fini(struct pt_event_decoder *decoder); + +static inline const struct pt_config * +pt_evt_config(const struct pt_event_decoder *decoder) +{ + if (!decoder) + return NULL; + + return pt_pkt_config(&decoder->pacdec); +} + +static inline const uint8_t *pt_evt_pos(const struct pt_event_decoder *decoder) +{ + if (!decoder) + return NULL; + + return pt_pkt_pos(&decoder->pacdec); +} + +static inline const uint8_t *pt_evt_end(const struct pt_event_decoder *decoder) +{ + const struct pt_config *config; + + config = pt_evt_config(decoder); + if (!config) + return NULL; + + return config->end; +} + +#endif /* PT_EVENT_DECODER_H */
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/internal/include/pt_event_queue.h -> _service:tar_scm:v2.1.tar.gz/libipt/internal/include/pt_event_queue.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -36,26 +37,36 @@ /* Events are grouped by the packet the event binds to. */ enum pt_event_binding { - evb_psbend, - evb_tip, - evb_fup, - - evb_max + evb_psbend = 1 << 0, + evb_tip = 1 << 1, + evb_fup = 1 << 2, + evb_fup_bound = 1 << 3, + evb_exstop = 1 << 4, + evb_cfe = 1 << 5, }; enum { /* The maximal number of pending events - should be a power of two. */ - evq_max = 8 + evq_max = 16 +}; + +/* An event queue entry. */ +struct pt_evq_entry { + /* The event. */ + struct pt_event event; + + /* The event binding as a bit vector of enum pt_event_binding. */ + uint32_t binding; }; /* A queue of events. */ struct pt_event_queue { - /* A collection of event queues, one per binding. */ - struct pt_event queueevb_maxevq_max; + /* A fixed-sized array of event queue entries. */ + struct pt_evq_entry queueevq_max; - /* The begin and end indices for the above event queues. */ - uint8_t beginevb_max; - uint8_t endevb_max; + /* The begin and end index for the above event queue. */ + uint8_t begin; + uint8_t end; /* A standalone event to be published immediately. */ struct pt_event standalone; @@ -81,7 +92,7 @@ * Returns NULL if @evq is full. */ extern struct pt_event *pt_evq_enqueue(struct pt_event_queue *evq, - enum pt_event_binding evb); + uint32_t evb); /* Dequeue an event. @@ -93,17 +104,29 @@ * Returns NULL if @evq is empty. */ extern struct pt_event *pt_evq_dequeue(struct pt_event_queue *evq, - enum pt_event_binding evb); + uint32_t evb); + +/* Requeue an event. + * + * Adds @ev to @evq for binding @evb, where @ev must be a recently dequeued or + * standalone event of @evq. + * + * Returns a pointer to the event on success. + * Returns NULL if @evq or @ev is NULL or @evb is invalid. + * Returns NULL if @evq is full. + */ +extern struct pt_event *pt_evq_requeue(struct pt_event_queue *evq, + struct pt_event *ev, + uint32_t evb); /* Clear a queue and discard events. * - * Removes all events for binding @evb from @evq. + * Removes all events from @evq. * * Returns zero on success, a negative error code otherwise. * Returns -pte_internal if @evq is NULL or @evb is invalid. */ -extern int pt_evq_clear(struct pt_event_queue *evq, - enum pt_event_binding evb); +extern int pt_evq_clear(struct pt_event_queue *evq); /* Check for emptiness. * @@ -113,8 +136,7 @@ * Returns zero if @evq is not empty. * Returns -pte_internal if @evq is NULL or @evb is invalid. */ -extern int pt_evq_empty(const struct pt_event_queue *evq, - enum pt_event_binding evb); +extern int pt_evq_empty(const struct pt_event_queue *evq, uint32_t evb); /* Check for non-emptiness. * @@ -124,20 +146,29 @@ * Returns zero if @evq is empty. * Returns -pte_internal if @evq is NULL or @evb is invalid. */ -extern int pt_evq_pending(const struct pt_event_queue *evq, - enum pt_event_binding evb); +extern int pt_evq_pending(const struct pt_event_queue *evq, uint32_t evb); /* Find an event by type. * - * Searches @evq for binding @evb for an event of type @evt. + * Searches @evq for an event of type @evt with binding @evb. * * Returns a pointer to the first matching event on success. * Returns NULL if there is no such event. * Returns NULL if @evq is NULL. * Returns NULL if @evb or @evt is invalid. */ -extern struct pt_event *pt_evq_find(struct pt_event_queue *evq, - enum pt_event_binding evb, +extern struct pt_event *pt_evq_find(struct pt_event_queue *evq, uint32_t evb, enum pt_event_type evt); +/* Find an event by binding. + * + * Searches @evq for an event with binding @evb. + * + * Returns a pointer to the first matching event on success. + * Returns NULL if there is no such event. + * Returns NULL if @evq is NULL. + * Returns NULL if @evb is invalid. + */ +extern struct pt_event *pt_evq_peek(struct pt_event_queue *evq, uint32_t evb); + #endif /* PT_EVENT_QUEUE_H */
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/internal/include/pt_ild.h -> _service:tar_scm:v2.1.tar.gz/libipt/internal/include/pt_ild.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/internal/include/pt_image.h -> _service:tar_scm:v2.1.tar.gz/libipt/internal/include/pt_image.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -79,8 +80,8 @@ * * Add @section identified by @isid to @image at @vaddr in @asid. If @section * overlaps with existing sections, the existing sections are shrunk, split, or - * removed to accomodate @section. Absence of a section identifier is indicated - * by an @isid of zero. + * removed to accommodate @section. Absence of a section identifier is + * indicated by an @isid of zero. * * Returns zero on success. * Returns -pte_internal if @image, @section, or @asid is NULL.
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/internal/include/pt_image_section_cache.h -> _service:tar_scm:v2.1.tar.gz/libipt/internal/include/pt_image_section_cache.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2016-2022, Intel Corporation + * Copyright (c) 2016-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -32,7 +33,11 @@ #include <stdint.h> #if defined(FEATURE_THREADS) -# include <threads.h> +# if !defined(__STDC_NO_THREADS__) +# include <threads.h> +# else +# include "pt_threads.h" +# endif #endif /* defined(FEATURE_THREADS) */ struct pt_section;
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/internal/include/pt_insn.h -> _service:tar_scm:v2.1.tar.gz/libipt/internal/include/pt_insn.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2016-2022, Intel Corporation + * Copyright (c) 2016-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -170,6 +171,28 @@ extern int pt_insn_is_ptwrite(const struct pt_insn *insn, const struct pt_insn_ext *iext); +/* Check if the instruction @insn/@iext is a return-from-interrupt instruction. + * + * Returns non-zero if it is, zero if it isn't (or @insn/@iext is NULL). + */ +extern int pt_insn_is_iret(const struct pt_insn *insn, + const struct pt_insn_ext *iext); + +/* Check if the instruction @insn/@iext is a vmentry instruction. + * + * Returns non-zero if it is, zero if it isn't (or @insn/@iext is NULL). + */ +extern int pt_insn_is_vmentry(const struct pt_insn *insn, + const struct pt_insn_ext *iext); + +/* Check if the instruction @insn/@iext is a return-from-user-interrupt + * instruction. + * + * Returns non-zero if it is, zero if it isn't (or @insn/@iext is NULL). + */ +extern int pt_insn_is_uiret(const struct pt_insn *insn, + const struct pt_insn_ext *iext); + /* Determine the IP of the next instruction. * * Tries to determine the IP of the next instruction without using trace and
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/internal/include/pt_insn_decoder.h -> _service:tar_scm:v2.1.tar.gz/libipt/internal/include/pt_insn_decoder.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -121,6 +122,15 @@ /* - a ptwrite event has already been bound to @insn/@iext. */ uint32_t bound_ptwrite:1; + + /* - an iret event has already been bound to @insn/@iext. */ + uint32_t bound_iret:1; + + /* - a vmentry event has already been bound to @insn/@iext. */ + uint32_t bound_vmentry:1; + + /* - an uiret event has already been bound to @insn/@iext. */ + uint32_t bound_uiret:1; }; @@ -136,4 +146,13 @@ /* Finalize an instruction flow decoder. */ extern void pt_insn_decoder_fini(struct pt_insn_decoder *decoder); +static inline const struct pt_config * +pt_insn_config(const struct pt_insn_decoder *decoder) +{ + if (!decoder) + return NULL; + + return pt_qry_config(&decoder->query); +} + #endif /* PT_INSN_DECODER_H */
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/internal/include/pt_last_ip.h -> _service:tar_scm:v2.1.tar.gz/libipt/internal/include/pt_last_ip.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/internal/include/pt_mapped_section.h -> _service:tar_scm:v2.1.tar.gz/libipt/internal/include/pt_mapped_section.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2014-2022, Intel Corporation + * Copyright (c) 2014-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/internal/include/pt_msec_cache.h -> _service:tar_scm:v2.1.tar.gz/libipt/internal/include/pt_msec_cache.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2017-2022, Intel Corporation + * Copyright (c) 2017-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/internal/include/pt_opcodes.h -> _service:tar_scm:v2.1.tar.gz/libipt/internal/include/pt_opcodes.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -67,6 +68,8 @@ pt_ext_pwre = 0x22, pt_ext_pwrx = 0xa2, pt_ext_ptw = 0x12, + pt_ext_cfe = 0x13, + pt_ext_evd = 0x53, pt_ext_bad = 0x04 }; @@ -145,7 +148,9 @@ pt_opcs_mwait = 2, pt_opcs_pwre = 2, pt_opcs_pwrx = 2, - pt_opcs_ptw = 2 + pt_opcs_ptw = 2, + pt_opcs_cfe = 2, + pt_opcs_evd = 2, }; /* The psb magic payload. @@ -317,7 +322,25 @@ pt_pl_pwrx_wr_store = 0x400, /* The bit-mask for the autonomous wake reason in the PWRX payload. */ - pt_pl_pwrx_wr_hw = 0x800 + pt_pl_pwrx_wr_hw = 0x800, + + /* The size in bytes of the CFE payload. */ + pt_pl_cfe_size = 2, + + /* The bit mask for the type field in the CFE payload. */ + pt_pl_cfe_type = 0x1f, + + /* The bit mask for the IP bit in the CFE payload. */ + pt_pl_cfe_ip = 0x80, + + /* The size in bytes of the EVD payload field. */ + pt_pl_evd_pl_size = 8, + + /* The size in bytes of the EVD payload. */ + pt_pl_evd_size = 9, + + /* The bit mask for the type field in the EVD payload. */ + pt_pl_evd_type = 0x1f, }; /* Mode packet masks. */ @@ -332,6 +355,7 @@ /* mode.exec */ pt_mob_exec_csl = 0x01, pt_mob_exec_csd = 0x02, + pt_mob_exec_iflag = 0x04, /* mode.tsx */ pt_mob_tsx_intx = 0x01, @@ -384,7 +408,9 @@ ptps_pwre = pt_opcs_pwre + pt_pl_pwre_size, ptps_pwrx = pt_opcs_pwrx + pt_pl_pwrx_size, ptps_ptw_32 = pt_opcs_ptw + 4, - ptps_ptw_64 = pt_opcs_ptw + 8 + ptps_ptw_64 = pt_opcs_ptw + 8, + ptps_cfe = pt_opcs_cfe + pt_pl_cfe_size, + ptps_evd = pt_opcs_evd + pt_pl_evd_size, }; /* Supported address range configurations. */
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/internal/include/pt_packet.h -> _service:tar_scm:v2.1.tar.gz/libipt/internal/include/pt_packet.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2014-2022, Intel Corporation + * Copyright (c) 2014-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -49,6 +50,8 @@ struct pt_packet_pwre; struct pt_packet_pwrx; struct pt_packet_ptw; +struct pt_packet_cfe; +struct pt_packet_evd; /* Read the payload of an Intel PT packet. @@ -107,5 +110,9 @@ const struct pt_config *config); extern int pt_pkt_read_ptw(struct pt_packet_ptw *packet, const uint8_t *pos, const struct pt_config *config); +extern int pt_pkt_read_cfe(struct pt_packet_cfe *packet, const uint8_t *pos, + const struct pt_config *config); +extern int pt_pkt_read_evd(struct pt_packet_evd *packet, const uint8_t *pos, + const struct pt_config *config); #endif /* PT_PACKET_H */
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/internal/include/pt_packet_decoder.h -> _service:tar_scm:v2.1.tar.gz/libipt/internal/include/pt_packet_decoder.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2014-2022, Intel Corporation + * Copyright (c) 2014-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -55,38 +56,34 @@ /* Finalize the packet decoder. */ extern void pt_pkt_decoder_fini(struct pt_packet_decoder *); +static inline const struct pt_config * +pt_pkt_config(const struct pt_packet_decoder *decoder) +{ + if (!decoder) + return NULL; -/* Decoder functions for the packet decoder. */ -extern int pt_pkt_decode_unknown(struct pt_packet_decoder *, - struct pt_packet *); -extern int pt_pkt_decode_pad(struct pt_packet_decoder *, struct pt_packet *); -extern int pt_pkt_decode_psb(struct pt_packet_decoder *, struct pt_packet *); -extern int pt_pkt_decode_tip(struct pt_packet_decoder *, struct pt_packet *); -extern int pt_pkt_decode_tnt_8(struct pt_packet_decoder *, struct pt_packet *); -extern int pt_pkt_decode_tnt_64(struct pt_packet_decoder *, - struct pt_packet *); -extern int pt_pkt_decode_tip_pge(struct pt_packet_decoder *, - struct pt_packet *); -extern int pt_pkt_decode_tip_pgd(struct pt_packet_decoder *, - struct pt_packet *); -extern int pt_pkt_decode_fup(struct pt_packet_decoder *, struct pt_packet *); -extern int pt_pkt_decode_pip(struct pt_packet_decoder *, struct pt_packet *); -extern int pt_pkt_decode_ovf(struct pt_packet_decoder *, struct pt_packet *); -extern int pt_pkt_decode_mode(struct pt_packet_decoder *, struct pt_packet *); -extern int pt_pkt_decode_psbend(struct pt_packet_decoder *, - struct pt_packet *); -extern int pt_pkt_decode_tsc(struct pt_packet_decoder *, struct pt_packet *); -extern int pt_pkt_decode_cbr(struct pt_packet_decoder *, struct pt_packet *); -extern int pt_pkt_decode_tma(struct pt_packet_decoder *, struct pt_packet *); -extern int pt_pkt_decode_mtc(struct pt_packet_decoder *, struct pt_packet *); -extern int pt_pkt_decode_cyc(struct pt_packet_decoder *, struct pt_packet *); -extern int pt_pkt_decode_stop(struct pt_packet_decoder *, struct pt_packet *); -extern int pt_pkt_decode_vmcs(struct pt_packet_decoder *, struct pt_packet *); -extern int pt_pkt_decode_mnt(struct pt_packet_decoder *, struct pt_packet *); -extern int pt_pkt_decode_exstop(struct pt_packet_decoder *, struct pt_packet *); -extern int pt_pkt_decode_mwait(struct pt_packet_decoder *, struct pt_packet *); -extern int pt_pkt_decode_pwre(struct pt_packet_decoder *, struct pt_packet *); -extern int pt_pkt_decode_pwrx(struct pt_packet_decoder *, struct pt_packet *); -extern int pt_pkt_decode_ptw(struct pt_packet_decoder *, struct pt_packet *); + return &decoder->config; +} + +static inline const uint8_t * +pt_pkt_pos(const struct pt_packet_decoder *decoder) +{ + if (!decoder) + return NULL; + + return decoder->pos; +} + +static inline const uint8_t * +pt_pkt_end(const struct pt_packet_decoder *decoder) +{ + const struct pt_config *config; + + config = pt_pkt_config(decoder); + if (!config) + return NULL; + + return config->end; +} #endif /* PT_PACKET_DECODER_H */
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/internal/include/pt_query_decoder.h -> _service:tar_scm:v2.1.tar.gz/libipt/internal/include/pt_query_decoder.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2014-2022, Intel Corporation + * Copyright (c) 2014-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -29,59 +30,50 @@ #ifndef PT_QUERY_DECODER_H #define PT_QUERY_DECODER_H -#include "pt_last_ip.h" +#include "pt_event_decoder.h" #include "pt_tnt_cache.h" -#include "pt_time.h" -#include "pt_event_queue.h" #include "intel-pt.h" -struct pt_decoder_function; - /* An Intel PT query decoder. */ struct pt_query_decoder { - /* The decoder configuration. */ - struct pt_config config; - - /* The current position in the trace buffer. */ - const uint8_t *pos; - - /* The position of the last PSB packet. */ - const uint8_t *sync; + /* The Intel PT event decoder. */ + struct pt_event_decoder evdec; - /* The decoding function for the next packet. */ - const struct pt_decoder_function *next; - - /* The last-ip. */ - struct pt_last_ip ip; + /* The configuration flags. + * + * Those are our flags set by the user. In @evdec.config.flags, we set + * the flags we need for the event decoder. + */ + struct pt_conf_flags flags; /* The cached tnt indicators. */ struct pt_tnt_cache tnt; - /* Timing information. */ - struct pt_time time; - /* The time at the last query (before reading ahead). */ struct pt_time last_time; - /* Timing calibration. */ - struct pt_time_cal tcal; - - /* Pending (incomplete) events. */ - struct pt_event_queue evq; - - /* The current event. */ - struct pt_event *event; - - /* A collection of flags relevant for decoding: + /* The current event to be processed. + * + * This will be valid as long as there are events available, i.e. until + * @status is not negative. * - * - tracing is enabled. + * The decoder starts by reading the first event after synchronizing + * onto the trace stream. + * + * When it is done processing an event, it fetches the next event for + * the next iteration. */ - uint32_t enabled:1; + struct pt_event event; - /* - consume the current packet. */ - uint32_t consume_packet:1; + /* The last status of the event decoder. + * + * It will be zero most of the time. Since we fetch new events at the + * end of an iteration, we need to store the status until the next + * pt_qry_*() call. + */ + int status; }; /* Initialize the query decoder. @@ -94,41 +86,21 @@ /* Finalize the query decoder. */ extern void pt_qry_decoder_fini(struct pt_query_decoder *); -/* Decoder functions (tracing context). */ -extern int pt_qry_decode_unknown(struct pt_query_decoder *); -extern int pt_qry_decode_pad(struct pt_query_decoder *); -extern int pt_qry_decode_psb(struct pt_query_decoder *); -extern int pt_qry_decode_tip(struct pt_query_decoder *); -extern int pt_qry_decode_tnt_8(struct pt_query_decoder *); -extern int pt_qry_decode_tnt_64(struct pt_query_decoder *); -extern int pt_qry_decode_tip_pge(struct pt_query_decoder *); -extern int pt_qry_decode_tip_pgd(struct pt_query_decoder *); -extern int pt_qry_decode_fup(struct pt_query_decoder *); -extern int pt_qry_decode_pip(struct pt_query_decoder *); -extern int pt_qry_decode_ovf(struct pt_query_decoder *); -extern int pt_qry_decode_mode(struct pt_query_decoder *); -extern int pt_qry_decode_psbend(struct pt_query_decoder *); -extern int pt_qry_decode_tsc(struct pt_query_decoder *); -extern int pt_qry_header_tsc(struct pt_query_decoder *); -extern int pt_qry_decode_cbr(struct pt_query_decoder *); -extern int pt_qry_header_cbr(struct pt_query_decoder *); -extern int pt_qry_decode_tma(struct pt_query_decoder *); -extern int pt_qry_decode_mtc(struct pt_query_decoder *); -extern int pt_qry_decode_cyc(struct pt_query_decoder *); -extern int pt_qry_decode_stop(struct pt_query_decoder *); -extern int pt_qry_decode_vmcs(struct pt_query_decoder *); -extern int pt_qry_decode_mnt(struct pt_query_decoder *); -extern int pt_qry_decode_exstop(struct pt_query_decoder *); -extern int pt_qry_decode_mwait(struct pt_query_decoder *); -extern int pt_qry_decode_pwre(struct pt_query_decoder *); -extern int pt_qry_decode_pwrx(struct pt_query_decoder *); -extern int pt_qry_decode_ptw(struct pt_query_decoder *); - -/* Decoder functions (header context). */ -extern int pt_qry_header_fup(struct pt_query_decoder *); -extern int pt_qry_header_pip(struct pt_query_decoder *); -extern int pt_qry_header_mode(struct pt_query_decoder *); -extern int pt_qry_header_vmcs(struct pt_query_decoder *); -extern int pt_qry_header_mnt(struct pt_query_decoder *); +static inline const struct pt_config * +pt_qry_config(const struct pt_query_decoder *decoder) +{ + if (!decoder) + return NULL; + + return pt_evt_config(&decoder->evdec); +} + +static inline const uint8_t *pt_qry_pos(const struct pt_query_decoder *decoder) +{ + if (!decoder) + return NULL; + + return pt_evt_pos(&decoder->evdec); +} #endif /* PT_QUERY_DECODER_H */
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/internal/include/pt_retstack.h -> _service:tar_scm:v2.1.tar.gz/libipt/internal/include/pt_retstack.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/internal/include/pt_section.h -> _service:tar_scm:v2.1.tar.gz/libipt/internal/include/pt_section.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -32,8 +33,19 @@ #include <stdint.h> #include <stddef.h> +#if !defined(__STDC_NO_ATOMICS__) +# include <stdatomic.h> +# define PT_ATOMIC _Atomic +#else +# define PT_ATOMIC /* nothing */ +#endif + #if defined(FEATURE_THREADS) -# include <threads.h> +# if !defined(__STDC_NO_THREADS__) +# include <threads.h> +# else +# include "pt_threads.h" +# endif #endif /* defined(FEATURE_THREADS) */ #include "intel-pt.h" @@ -78,11 +90,11 @@ * We read this field without locking and only lock the section in order * to install the block cache. * - * We rely on guaranteed atomic operations as specified in section 8.1.1 - * in Volume 3A of the Intel(R) Software Developer's Manual at - * http://www.intel.com/sdm. + * We use atomic operations, if supported, and rely on guaranteed + * atomic operations, otherwise. See section 8.1.1 in Volume 3A of the + * Intel(R) Software Developer's Manual at http://www.intel.com/sdm. */ - struct pt_block_cache *bcache; + struct pt_block_cache * PT_ATOMIC bcache; /* A pointer to the iscache attached to this section. * @@ -162,10 +174,15 @@ * The returned section is not mapped and starts with a user count of one and * instruction caching enabled. * - * Returns a new section on success, NULL otherwise. + * Returns zero on success, a negative pt_error_code otherwise. + * Returns -pte_internal if @psection is NULL. + * Returns -pte_nomem when running out of memory. + * Returns -pte_bad_file if @filename cannot be opened. + * Returns -pte_invalid if @offset lies beyond @file. + * Returns -pte_invalid if @filename is too long. */ -extern struct pt_section *pt_mk_section(const char *file, uint64_t offset, - uint64_t size); +extern int pt_mk_section(struct pt_section **psection, const char *filename, + uint64_t offset, uint64_t size); /* Lock a section. * @@ -265,21 +282,6 @@ */ extern int pt_section_alloc_bcache(struct pt_section *section); -/* Request block caching. - * - * The caller must ensure that @section is mapped. - */ -static inline int pt_section_request_bcache(struct pt_section *section) -{ - if (!section) - return -pte_internal; - - if (section->bcache) - return 0; - - return pt_section_alloc_bcache(section); -} - /* Return @section's block cache, if available. * * The caller must ensure that @section is mapped. @@ -288,12 +290,31 @@ * @section mapped. */ static inline struct pt_block_cache * -pt_section_bcache(const struct pt_section *section) +pt_section_bcache(struct pt_section *section) { if (!section) return NULL; +#if !defined(__STDC_NO_ATOMICS__) + return atomic_load(§ion->bcache); +#else return section->bcache; +#endif +} + +/* Request block caching. + * + * The caller must ensure that @section is mapped. + */ +static inline int pt_section_request_bcache(struct pt_section *section) +{ + struct pt_block_cache *bcache; + + bcache = pt_section_bcache(section); + if (bcache) + return 0; + + return pt_section_alloc_bcache(section); } /* Create the OS-specific file status.
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/internal/include/pt_section_file.h -> _service:tar_scm:v2.1.tar.gz/libipt/internal/include/pt_section_file.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -33,7 +34,11 @@ #include <stdint.h> #if defined(FEATURE_THREADS) -# include <threads.h> +# if !defined(__STDC_NO_THREADS__) +# include <threads.h> +# else +# include "pt_threads.h" +# endif #endif /* defined(FEATURE_THREADS) */ struct pt_section;
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/internal/include/pt_sync.h -> _service:tar_scm:v2.1.tar.gz/libipt/internal/include/pt_sync.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2014-2022, Intel Corporation + * Copyright (c) 2014-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/internal/include/pt_time.h -> _service:tar_scm:v2.1.tar.gz/libipt/internal/include/pt_time.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2014-2022, Intel Corporation + * Copyright (c) 2014-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -233,5 +234,7 @@ const struct pt_config *); extern int pt_tcal_update_psb(struct pt_time_cal *, const struct pt_config *); +extern int pt_tcal_update_ovf(struct pt_time_cal *, + const struct pt_config *); #endif /* PT_TIME_H */
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/internal/include/pt_tnt_cache.h -> _service:tar_scm:v2.1.tar.gz/libipt/internal/include/pt_tnt_cache.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -72,17 +73,15 @@ */ extern int pt_tnt_cache_query(struct pt_tnt_cache *cache); -/* Update the tnt cache based on Intel PT packets. +/* Add TNT bits to the cache. * - * Updates @cache based on @packet and, if non-null, @config. + * Add the least significant @size bits from @tnt to @cache. * - * Returns zero on success. - * Returns -pte_invalid if @cache or @packet is NULL. - * Returns -pte_bad_packet if @packet appears to be corrupted. - * Returns -pte_bad_context if the tnt cache is not empty. + * Returns zero on success, a negative pt_error_code otherwise. + * Returns -pte_invalid if @cache is NULL. + * Returns -pte_overflow if @cache has not enough space. */ -extern int pt_tnt_cache_update_tnt(struct pt_tnt_cache *cache, - const struct pt_packet_tnt *packet, - const struct pt_config *config); +extern int pt_tnt_cache_add(struct pt_tnt_cache *cache, uint64_t tnt, + uint8_t size); #endif /* PT_TNT_CACHE_H */
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/internal/include/pti-disp-defs.h -> _service:tar_scm:v2.1.tar.gz/libipt/internal/include/pti-disp-defs.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/internal/include/pti-disp.h -> _service:tar_scm:v2.1.tar.gz/libipt/internal/include/pti-disp.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/internal/include/pti-disp_default.h -> _service:tar_scm:v2.1.tar.gz/libipt/internal/include/pti-disp_default.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2017-2022, Intel Corporation + * Copyright (c) 2017-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/internal/include/pti-imm-defs.h -> _service:tar_scm:v2.1.tar.gz/libipt/internal/include/pti-imm-defs.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/internal/include/pti-imm.h -> _service:tar_scm:v2.1.tar.gz/libipt/internal/include/pti-imm.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/internal/include/pti-modrm-defs.h -> _service:tar_scm:v2.1.tar.gz/libipt/internal/include/pti-modrm-defs.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/internal/include/pti-modrm.h -> _service:tar_scm:v2.1.tar.gz/libipt/internal/include/pti-modrm.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/internal/include/pti-sib.h -> _service:tar_scm:v2.1.tar.gz/libipt/internal/include/pti-sib.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2017-2022, Intel Corporation + * Copyright (c) 2017-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/internal/include/windows/pt_section_windows.h -> _service:tar_scm:v2.1.tar.gz/libipt/internal/include/windows/pt_section_windows.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2015-2022, Intel Corporation + * Copyright (c) 2015-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/src/posix/pt_section_posix.c -> _service:tar_scm:v2.1.tar.gz/libipt/src/posix/pt_section_posix.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -53,7 +54,7 @@ errcode = stat(filename, &buffer); if (errcode < 0) - return errcode; + return -pte_bad_file; if (buffer.st_size < 0) return -pte_bad_image; @@ -81,7 +82,7 @@ errcode = fstat(fd, &stat); if (errcode) - return -pte_bad_image; + return -pte_bad_file; status = section->status; if (!status) @@ -218,7 +219,7 @@ if (!filename) goto out_unlock; - errcode = -pte_bad_image; + errcode = -pte_bad_file; fd = open(filename, O_RDONLY); if (fd == -1) goto out_unlock; @@ -239,8 +240,10 @@ * if we fail to convert the file descriptor. */ file = fdopen(fd, "rb"); - if (!file) + if (!file) { + errcode = -pte_bad_file; goto out_fd; + } /* We need to keep the file open on success. It will be closed when * the section is unmapped.
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/src/pt_asid.c -> _service:tar_scm:v2.1.tar.gz/libipt/src/pt_asid.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2014-2022, Intel Corporation + * Copyright (c) 2014-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/src/pt_block_cache.c -> _service:tar_scm:v2.1.tar.gz/libipt/src/pt_block_cache.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2016-2022, Intel Corporation + * Copyright (c) 2016-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -68,17 +69,16 @@ if (bcache->nentries <= index) return -pte_internal; - /* We rely on guaranteed atomic operations as specified in section 8.1.1 - * in Volume 3A of the Intel(R) Software Developer's Manual at - * http://www.intel.com/sdm. - */ +#if !defined(__STDC_NO_ATOMICS__) + atomic_store(&bcache->entry(uint32_t) index, bce); +#else bcache->entry(uint32_t) index = bce; - +#endif return 0; } int pt_bcache_lookup(struct pt_bcache_entry *bce, - const struct pt_block_cache *bcache, uint64_t index) + struct pt_block_cache *bcache, uint64_t index) { if (!bce || !bcache) return -pte_internal; @@ -86,11 +86,10 @@ if (bcache->nentries <= index) return -pte_internal; - /* We rely on guaranteed atomic operations as specified in section 8.1.1 - * in Volume 3A of the Intel(R) Software Developer's Manual at - * http://www.intel.com/sdm. - */ +#if !defined(__STDC_NO_ATOMICS__) + *bce = atomic_load(&bcache->entry(uint32_t) index); +#else *bce = bcache->entry(uint32_t) index; - +#endif return 0; }
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/src/pt_block_decoder.c -> _service:tar_scm:v2.1.tar.gz/libipt/src/pt_block_decoder.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2016-2022, Intel Corporation + * Copyright (c) 2016-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -44,65 +45,86 @@ static int pt_blk_proceed_trailing_event(struct pt_block_decoder *, struct pt_block *); - -static int pt_blk_status(const struct pt_block_decoder *decoder, int flags) +static int pt_blk_fetch_event(struct pt_block_decoder *decoder) { - int status; + struct pt_event *ev; + int errcode; if (!decoder) return -pte_internal; - status = decoder->status; + ev = &decoder->event; + decoder->tsc = ev->tsc; + decoder->has_tsc = ev->has_tsc; + decoder->lost_mtc = ev->lost_mtc; + decoder->lost_cyc = ev->lost_cyc; + + errcode = pt_evt_next(&decoder->evdec, ev, sizeof(*ev)); + if (errcode < 0) { + decoder->status = errcode; + memset(ev, 0xff, sizeof(*ev)); + } + + return 0; +} + +static int pt_blk_status(const struct pt_block_decoder *decoder, int flags) +{ + if (!decoder) + return -pte_internal; - /* Indicate whether tracing is disabled or enabled. - * - * This duplicates the indication in struct pt_insn and covers the case - * where we indicate the status after synchronizing. - */ if (!decoder->enabled) flags |= pts_ip_suppressed; - /* Forward end-of-trace indications. - * - * Postpone it as long as we're still processing events, though. - */ - if ((status & pts_eos) && !decoder->process_event) + if (decoder->status == -pte_eos) flags |= pts_eos; return flags; } -static void pt_blk_reset(struct pt_block_decoder *decoder) +static int pt_blk_reset(struct pt_block_decoder *decoder) { if (!decoder) - return; + return -pte_internal; + decoder->tsc = 0ull; + decoder->lost_mtc = 0u; + decoder->lost_cyc = 0u; + decoder->cbr = 0u; decoder->mode = ptem_unknown; decoder->ip = 0ull; - decoder->status = 0; + decoder->status = -pte_nosync; decoder->enabled = 0; - decoder->process_event = 0; decoder->speculative = 0; + decoder->has_tsc = 0; decoder->process_insn = 0; decoder->bound_paging = 0; decoder->bound_vmcs = 0; decoder->bound_ptwrite = 0; + decoder->bound_iret = 0; + decoder->bound_vmentry = 0; + decoder->bound_uiret = 0; - memset(&decoder->event, 0, sizeof(decoder->event)); + memset(&decoder->event, 0xff, sizeof(decoder->event)); pt_retstack_init(&decoder->retstack); pt_asid_init(&decoder->asid); + + return 0; } -/* Initialize the query decoder flags based on our flags. */ +/* Initialize the event decoder flags based on our flags. */ -static int pt_blk_init_qry_flags(struct pt_conf_flags *qflags, +static int pt_blk_init_evt_flags(struct pt_conf_flags *qflags, const struct pt_conf_flags *flags) { if (!qflags || !flags) return -pte_internal; memset(qflags, 0, sizeof(*qflags)); - + qflags->variant.event.keep_tcal_on_ovf = + flags->variant.block.keep_tcal_on_ovf; + qflags->variant.event.enable_iflags_events = + flags->variant.block.enable_iflags_events; return 0; } @@ -122,12 +144,12 @@ /* The user supplied decoder flags. */ decoder->flags = config.flags; - /* Set the flags we need for the query decoder we use. */ - errcode = pt_blk_init_qry_flags(&config.flags, &decoder->flags); + /* Set the flags we need for the event decoder we use. */ + errcode = pt_blk_init_evt_flags(&config.flags, &decoder->flags); if (errcode < 0) return errcode; - errcode = pt_qry_decoder_init(&decoder->query, &config); + errcode = pt_evt_decoder_init(&decoder->evdec, &config); if (errcode < 0) return errcode; @@ -138,9 +160,7 @@ if (errcode < 0) return errcode; - pt_blk_reset(decoder); - - return 0; + return pt_blk_reset(decoder); } void pt_blk_decoder_fini(struct pt_block_decoder *decoder) @@ -150,7 +170,7 @@ pt_msec_cache_fini(&decoder->scache); pt_image_fini(&decoder->default_image); - pt_qry_decoder_fini(&decoder->query); + pt_evt_decoder_fini(&decoder->evdec); } struct pt_block_decoder * @@ -181,205 +201,284 @@ free(decoder); } -/* Maybe synthesize a tick event. +/* Synthesize a tick event or fetch the next event. * - * If we're not already processing events, check the current time against the - * last event's time. If it changed, synthesize a tick event with the new time. + * We consumed a TIP or TNT event. If the user asked for tick events, rewrite + * the current event, otherwise fetch the next event. * - * Returns zero if no tick event has been created. - * Returns a positive integer if a tick event has been created. - * Returns a negative error code otherwise. + * Returns zero on success, a negative pt_error_code otherwise. */ static int pt_blk_tick(struct pt_block_decoder *decoder, uint64_t ip) { - struct pt_event *ev; - uint64_t tsc; - uint32_t lost_mtc, lost_cyc; - int errcode; - if (!decoder) return -pte_internal; - /* We're not generating tick events if tracing is disabled. */ - if (!decoder->enabled) - return -pte_internal; + if (decoder->flags.variant.block.enable_tick_events) { + struct pt_event *ev; - /* Events already provide a timestamp so there is no need to synthesize - * an artificial tick event. There's no room, either, since this would - * overwrite the in-progress event. - * - * In rare cases where we need to proceed to an event location using - * trace this may cause us to miss a timing update if the event is not - * forwarded to the user. - * - * The only case I can come up with at the moment is a MODE.EXEC binding - * to the TIP IP of a far branch. - */ - if (decoder->process_event) - return 0; + ev = &decoder->event; + if (ev->tsc != decoder->tsc) { + ev->type = ptev_tick; + ev->variant.tick.ip = ip; - errcode = pt_qry_time(&decoder->query, &tsc, &lost_mtc, &lost_cyc); - if (errcode < 0) { - /* If we don't have wall-clock time, we use relative time. */ - if (errcode != -pte_no_time) - return errcode; + return 0; + } } - ev = &decoder->event; - - /* We're done if time has not changed since the last event. */ - if (tsc == ev->tsc) - return 0; - - /* Time has changed so we create a new tick event. */ - memset(ev, 0, sizeof(*ev)); - ev->type = ptev_tick; - ev->variant.tick.ip = ip; - - /* Indicate if we have wall-clock time or only relative time. */ - if (errcode != -pte_no_time) - ev->has_tsc = 1; - ev->tsc = tsc; - ev->lost_mtc = lost_mtc; - ev->lost_cyc = lost_cyc; - - /* We now have an event to process. */ - decoder->process_event = 1; - - return 1; + return pt_blk_fetch_event(decoder); } -/* Query an indirect branch. +/* Handle an indirect branch. * - * Returns zero on success, a negative error code otherwise. + * Returns zero on success, a negative pt_error_code otherwise. */ -static int pt_blk_indirect_branch(struct pt_block_decoder *decoder, - uint64_t *ip) +static int pt_blk_proceed_indirect(struct pt_block_decoder *decoder) { - uint64_t evip; - int status, errcode; + struct pt_event *ev; if (!decoder) return -pte_internal; - evip = decoder->ip; + ev = &decoder->event; + switch (ev->type) { + case ptev_tip: { + uint64_t ip; - status = pt_qry_indirect_branch(&decoder->query, ip); - if (status < 0) - return status; + if (ev->ip_suppressed) + return -pte_bad_packet; - if (decoder->flags.variant.block.enable_tick_events) { - errcode = pt_blk_tick(decoder, evip); - if (errcode < 0) - return errcode; + ip = decoder->ip; + decoder->ip = ev->variant.tip.ip; + + return pt_blk_tick(decoder, ip); } - return status; -} + case ptev_tnt: { + struct pt_event_decoder evdec; + struct pt_event tnt; + int errcode; -/* Query a conditional branch. - * - * Returns zero on success, a negative error code otherwise. - */ -static int pt_blk_cond_branch(struct pt_block_decoder *decoder, int *taken) -{ - int status, errcode; + /* Deferred TIP may hide a TIP behind an in-progress TNT. + * + * We read ahead to get to the TIP and then re-install the + * in-progress TNT again. + * + * Back up the event decode state in case this isn't a deferred + * TIP after all. + */ + evdec = decoder->evdec; + tnt = *ev; - if (!decoder) - return -pte_internal; + errcode = pt_evt_next(&decoder->evdec, ev, sizeof(*ev)); + if ((errcode < 0) || (ev->type != ptev_tip)) { + decoder->evdec = evdec; + *ev = tnt; - status = pt_qry_cond_branch(&decoder->query, taken); - if (status < 0) - return status; + return -pte_bad_query; + } - if (decoder->flags.variant.block.enable_tick_events) { - errcode = pt_blk_tick(decoder, decoder->ip); - if (errcode < 0) - return errcode; + decoder->ip = ev->variant.tip.ip; + + /* We can't generate tick events for this TIP since we have to + * restore the in-progress TNT. + */ + *ev = tnt; + + return 0; } - return status; + default: + return -pte_bad_query; + } } -static int pt_blk_start(struct pt_block_decoder *decoder, int status) +/* Handle a conditional branch. + * + * Returns a positive number if the branch was taken. + * Returns zero if the branch was not taken. + * Returns a negative pt_error_code otherwise. + */ +static int pt_blk_cond_branch(struct pt_block_decoder *decoder) { + struct pt_event *ev; + uint8_t size; + if (!decoder) return -pte_internal; - if (status < 0) - return status; + ev = &decoder->event; + if (ev->type != ptev_tnt) + return -pte_bad_query; - decoder->status = status; - if (!(status & pts_ip_suppressed)) - decoder->enabled = 1; + size = ev->variant.tnt.size; + if (!size) + return -pte_internal; - /* We will always have an event. - * - * If we synchronized onto an empty PSB+, tracing is disabled and we'll - * process events until the enabled event. - * - * If tracing is enabled, PSB+ must at least provide the execution mode, - * which we're going to forward to the user. + size -= 1; + ev->variant.tnt.size = size; + + /* We postpone fetching the next event when size becomes zero to + * support tick events on one-bit TNT events. */ - return pt_blk_proceed_trailing_event(decoder, NULL); + return (int) ((ev->variant.tnt.bits >> size) & 1); } -static int pt_blk_sync_reset(struct pt_block_decoder *decoder) +static int pt_blk_start(struct pt_block_decoder *decoder) { + struct pt_event_decoder evdec; + struct pt_event ev; + int errcode; + if (!decoder) return -pte_internal; - pt_blk_reset(decoder); + /* We need to process satus update events from PSB+ in order to + * initialize our internal state and be able to diagnose + * inconsistencies during tracing. + * + * On the other hand, we need to provide those same status events to + * our user. We do that by using a local copy of our event decoder, so + * when we're done, we rewind back to where we started. + */ + evdec = decoder->evdec; - return 0; + /* Process status update events from PSB+ to initialize our state. */ + for (;;) { + /* Check that we're still processing the initial events. + * + * When the event decoder moves ahead, we're done with the + * initial PSB+. We may get additional events from an adjacent + * PSB+, but we don't want to process them here. + */ + if (pt_evt_pos(&evdec) != pt_blk_pos(decoder)) + break; + + errcode = pt_evt_next(&evdec, &ev, sizeof(ev)); + if (errcode < 0) { + if (errcode != -pte_eos) + return errcode; + + break; + } + + if (!ev.status_update) + break; + + switch (ev.type) { + case ptev_enabled: + decoder->enabled = 1; + decoder->ip = ev.variant.enabled.ip; + break; + + default: + continue; + } + + break; + } + + decoder->status = 0; + + errcode = pt_blk_fetch_event(decoder); + if (errcode < 0) + return errcode; + + return pt_blk_proceed_trailing_event(decoder, NULL); } int pt_blk_sync_forward(struct pt_block_decoder *decoder) { - int errcode, status; + int errcode; if (!decoder) return -pte_invalid; - errcode = pt_blk_sync_reset(decoder); + errcode = pt_blk_reset(decoder); if (errcode < 0) return errcode; - status = pt_qry_sync_forward(&decoder->query, &decoder->ip); + errcode = pt_evt_sync_forward(&decoder->evdec); + if (errcode < 0) + return errcode; - return pt_blk_start(decoder, status); + return pt_blk_start(decoder); } int pt_blk_sync_backward(struct pt_block_decoder *decoder) { - int errcode, status; + const uint8_t *start, *sync, *pos; + int errcode; if (!decoder) return -pte_invalid; - errcode = pt_blk_sync_reset(decoder); - if (errcode < 0) - return errcode; + start = pt_blk_pos(decoder); + if (!start) { + const struct pt_config *config; + + config = pt_blk_config(decoder); + if (!config) + return -pte_internal; - status = pt_qry_sync_backward(&decoder->query, &decoder->ip); + start = config->end; + if (!start) + return -pte_bad_config; + } + + sync = start; + for (;;) { + errcode = pt_blk_reset(decoder); + if (errcode < 0) + return errcode; + + do { + errcode = pt_evt_sync_backward(&decoder->evdec); + if (errcode < 0) + return errcode; + + pos = pt_blk_pos(decoder); + } while (sync <= pos); + + sync = pos; + + errcode = pt_blk_start(decoder); + if (errcode < 0) { + /* Ignore incomplete trace segments at the end. We + * need a full PSB+ to start decoding. + */ + if (errcode != -pte_eos) + return errcode; - return pt_blk_start(decoder, status); + continue; + } + + /* When starting inside or right after PSB+, we may end up at + * the same PSB again. Skip it. + */ + pos = pt_blk_pos(decoder); + if (pos < start) + break; + } + + return 0; } int pt_blk_sync_set(struct pt_block_decoder *decoder, uint64_t offset) { - int errcode, status; + int errcode; if (!decoder) return -pte_invalid; - errcode = pt_blk_sync_reset(decoder); + errcode = pt_blk_reset(decoder); if (errcode < 0) return errcode; - status = pt_qry_sync_set(&decoder->query, &decoder->ip, offset); + errcode = pt_evt_sync_set(&decoder->evdec, offset); + if (errcode < 0) + return errcode; - return pt_blk_start(decoder, status); + return pt_blk_start(decoder); } int pt_blk_get_offset(const struct pt_block_decoder *decoder, uint64_t *offset) @@ -387,7 +486,7 @@ if (!decoder) return -pte_invalid; - return pt_qry_get_offset(&decoder->query, offset); + return pt_evt_get_offset(&decoder->evdec, offset); } int pt_blk_get_sync_offset(const struct pt_block_decoder *decoder, @@ -396,7 +495,7 @@ if (!decoder) return -pte_invalid; - return pt_qry_get_sync_offset(&decoder->query, offset); + return pt_evt_get_sync_offset(&decoder->evdec, offset); } struct pt_image *pt_blk_get_image(struct pt_block_decoder *decoder) @@ -425,16 +524,20 @@ if (!decoder) return NULL; - return pt_qry_get_config(&decoder->query); + return pt_evt_get_config(&decoder->evdec); } int pt_blk_time(struct pt_block_decoder *decoder, uint64_t *time, uint32_t *lost_mtc, uint32_t *lost_cyc) { - if (!decoder || !time) + if (!decoder || !time || !lost_mtc || !lost_cyc) return -pte_invalid; - return pt_qry_time(&decoder->query, time, lost_mtc, lost_cyc); + *time = decoder->tsc; + *lost_mtc = decoder->lost_mtc; + *lost_cyc = decoder->lost_cyc; + + return 0; } int pt_blk_core_bus_ratio(struct pt_block_decoder *decoder, uint32_t *cbr) @@ -442,7 +545,9 @@ if (!decoder || !cbr) return -pte_invalid; - return pt_qry_core_bus_ratio(&decoder->query, cbr); + *cbr = decoder->cbr; + + return 0; } int pt_blk_asid(const struct pt_block_decoder *decoder, struct pt_asid *asid, @@ -454,39 +559,6 @@ return pt_asid_to_user(asid, &decoder->asid, size); } -/* Fetch the next pending event. - * - * Checks for pending events. If an event is pending, fetches it (if not - * already in process). - * - * Returns zero if no event is pending. - * Returns a positive integer if an event is pending or in process. - * Returns a negative error code otherwise. - */ -static inline int pt_blk_fetch_event(struct pt_block_decoder *decoder) -{ - int status; - - if (!decoder) - return -pte_internal; - - if (decoder->process_event) - return 1; - - if (!(decoder->status & pts_event_pending)) - return 0; - - status = pt_qry_event(&decoder->query, &decoder->event, - sizeof(decoder->event)); - if (status < 0) - return status; - - decoder->process_event = 1; - decoder->status = status; - - return 1; -} - static inline int pt_blk_block_is_empty(const struct pt_block *block) { if (!block) @@ -506,7 +578,8 @@ /* Zero out any unknown bytes. */ if (sizeof(*block) < size) { - memset(ublock + sizeof(*block), 0, size - sizeof(*block)); + memset(((uint8_t *) ublock) + sizeof(*block), 0, + size - sizeof(*block)); size = sizeof(*block); } @@ -525,31 +598,24 @@ return 0; } -/* Determine the next IP using trace. - * - * Tries to determine the IP of the next instruction using trace and provides it - * in @pip. +/* Proceed to the next IP using trace. * - * Not requiring trace to determine the IP is treated as an internal error. + * We failed to proceed without trace. This ends the current block. Now use + * trace to do one final step to determine the start IP of the next block. * * Does not update the return compression stack for indirect calls. This is * expected to have been done, already, when trying to determine the next IP * without using trace. * - * Does not update @decoder->status. The caller is expected to do that. - * - * Returns a non-negative pt_status_flag bit-vector on success, a negative error - * code otherwise. + * Returns zero on success, a negative pt_error_code otherwise. * Returns -pte_internal if @pip, @decoder, @insn, or @iext are NULL. * Returns -pte_internal if no trace is required. */ -static int pt_blk_next_ip(uint64_t *pip, struct pt_block_decoder *decoder, - const struct pt_insn *insn, - const struct pt_insn_ext *iext) +static int pt_blk_proceed_with_trace(struct pt_block_decoder *decoder, + const struct pt_insn *insn, + const struct pt_insn_ext *iext) { - int status, errcode; - - if (!pip || !decoder || !insn || !iext) + if (!decoder || !insn || !iext) return -pte_internal; /* We handle non-taken conditional branches, and compressed returns @@ -560,44 +626,43 @@ switch (insn->iclass) { case ptic_cond_jump: { uint64_t ip; - int taken; - - status = pt_blk_cond_branch(decoder, &taken); - if (status < 0) - return status; + int tnt; ip = insn->ip + insn->size; - if (taken) + + tnt = pt_blk_cond_branch(decoder); + if (tnt != 0) { + if (tnt < 0) + return tnt; + ip += (uint64_t) (int64_t) iext->variant.branch.displacement; + } - *pip = ip; - return status; + decoder->ip = ip; + + return 0; } case ptic_return: { - int taken; + int tnt; - /* Check for a compressed return. */ - status = pt_blk_cond_branch(decoder, &taken); - if (status < 0) { - if (status != -pte_bad_query) - return status; - - break; - } - - /* A compressed return is indicated by a taken conditional - * branch. + /* Check for a compressed return. + * + * It is indicated by a taken conditional branch. */ - if (!taken) - return -pte_bad_retcomp; + tnt = pt_blk_cond_branch(decoder); + if (tnt <= 0) { + if (tnt == -pte_bad_query) + break; - errcode = pt_retstack_pop(&decoder->retstack, pip); - if (errcode < 0) - return errcode; + if (!tnt) + tnt = -pte_bad_retcomp; - return status; + return tnt; + } + + return pt_retstack_pop(&decoder->retstack, &decoder->ip); } case ptic_jump: @@ -611,13 +676,14 @@ case ptic_far_call: case ptic_far_return: case ptic_far_jump: + case ptic_indirect: break; case ptic_ptwrite: case ptic_other: return -pte_internal; - case ptic_error: + case ptic_unknown: return -pte_bad_insn; } @@ -626,39 +692,7 @@ * This covers indirect jumps and calls, non-compressed returns, and all * flavors of far transfers. */ - return pt_blk_indirect_branch(decoder, pip); -} - -/* Proceed to the next IP using trace. - * - * We failed to proceed without trace. This ends the current block. Now use - * trace to do one final step to determine the start IP of the next block. - * - * Returns zero on success, a negative error code otherwise. - */ -static int pt_blk_proceed_with_trace(struct pt_block_decoder *decoder, - const struct pt_insn *insn, - const struct pt_insn_ext *iext) -{ - int status; - - if (!decoder) - return -pte_internal; - - status = pt_blk_next_ip(&decoder->ip, decoder, insn, iext); - if (status < 0) - return status; - - /* Preserve the query decoder's response which indicates upcoming - * events. - */ - decoder->status = status; - - /* We do need an IP in order to proceed. */ - if (status & pts_ip_suppressed) - return -pte_noip; - - return 0; + return pt_blk_proceed_indirect(decoder); } /* Decode one instruction in a known section. @@ -924,45 +958,6 @@ } } -/* Proceed to a particular IP with trace, if necessary. - * - * Proceed until we reach @ip or until: - * - * - @block is full: return zero - * - @block would switch sections: return zero - * - we need trace: return zero - * - * Update @decoder->ip to point to the last IP that was reached. - * - * A return of zero ends @block. - * - * Returns a positive integer if @ip was reached. - * Returns zero if no such instruction was reached. - * Returns a negative error code otherwise. - */ -static int pt_blk_proceed_to_ip_with_trace(struct pt_block_decoder *decoder, - struct pt_block *block, - uint64_t ip) -{ - struct pt_insn_ext iext; - struct pt_insn insn; - int status; - - /* Try to reach @ip without trace. - * - * We're also OK if @block overflowed or we switched sections and we - * have to try again in the next iteration. - */ - status = pt_blk_proceed_to_ip(decoder, block, &insn, &iext, ip); - if (status != -pte_bad_query) - return status; - - /* Needing trace is not an error. We use trace to determine the next - * start IP and end the block. - */ - return pt_blk_proceed_with_trace(decoder, &insn, &iext); -} - static int pt_insn_skl014(const struct pt_insn *insn, const struct pt_insn_ext *iext) { @@ -1004,12 +999,17 @@ struct pt_insn_ext *iext) { const struct pt_conf_addr_filter *addr_filter; + const struct pt_config *config; int status; if (!decoder || !block || !insn || !iext) return -pte_internal; - addr_filter = &decoder->query.config.addr_filter; + config = pt_blk_config(decoder); + if (!config) + return -pte_internal; + + addr_filter = &config->addr_filter; for (;;) { uint64_t ip; @@ -1084,6 +1084,12 @@ return -pte_internal; if (ev->ip_suppressed) { + const struct pt_config *config; + + config = pt_blk_config(decoder); + if (!config) + return -pte_internal; + /* Due to SKL014 the TIP.PGD payload may be suppressed also for * direct branches. * @@ -1092,8 +1098,8 @@ * * We might otherwise disable tracing too early. */ - if (decoder->query.config.addr_filter.config.addr_cfg && - decoder->query.config.errata.skl014) + if (config->addr_filter.config.addr_cfg && + config->errata.skl014) return pt_blk_proceed_skl014(decoder, block, insn, iext); @@ -1140,108 +1146,228 @@ return 0; } -/* Proceed to the event location for an async paging event. +/* Proceed to the event location for a ptwrite event. + * + * We have a ptwrite event pending. Proceed to the event location and indicate + * whether we were able to reach it. + * + * In case of the event binding to a ptwrite instruction, we pass beyond that + * instruction and update the event to provide the instruction's IP. * - * We have an async paging event pending. Proceed to the event location and - * indicate whether we were able to reach it. Needing trace in order to proceed - * is not an error in this case but ends the block. + * In the case of the event binding to an IP provided in the event, we move + * beyond the instruction at that IP. * * Returns a positive integer if the event location was reached. * Returns zero if the event location was not reached. * Returns a negative error code otherwise. */ -static int pt_blk_proceed_to_async_paging(struct pt_block_decoder *decoder, - struct pt_block *block, - const struct pt_event *ev) +static int pt_blk_proceed_to_ptwrite(struct pt_block_decoder *decoder, + struct pt_block *block, + struct pt_insn *insn, + struct pt_insn_ext *iext, + struct pt_event *ev) { int status; - if (!decoder || !ev) + if (!insn || !ev) return -pte_internal; - /* Apply the event immediately if we don't have an IP. */ - if (ev->ip_suppressed) - return 1; + /* If we don't have an IP, the event binds to the next PTWRITE + * instruction. + * + * If we have an IP it still binds to the next PTWRITE instruction but + * now the IP tells us where that instruction is. This makes most sense + * when tracing is disabled and we don't have any other means of finding + * the PTWRITE instruction. We nevertheless distinguish the two cases, + * here. + * + * In both cases, we move beyond the PTWRITE instruction, so it will be + * the last instruction in the current block and @decoder->ip will point + * to the instruction following it. + */ + if (ev->ip_suppressed) { + status = pt_blk_proceed_to_insn(decoder, block, insn, iext, + pt_insn_is_ptwrite); + if (status <= 0) + return status; - status = pt_blk_proceed_to_ip_with_trace(decoder, block, - ev->variant.async_paging.ip); - if (status < 0) - return status; + /* We now know the IP of the PTWRITE instruction corresponding + * to this event. Fill it in to make it more convenient for the + * user to process the event. + */ + ev->variant.ptwrite.ip = insn->ip; + ev->ip_suppressed = 0; + } else { + status = pt_blk_proceed_to_ip(decoder, block, insn, iext, + ev->variant.ptwrite.ip); + if (status <= 0) + return status; - /* We may have reached the IP. */ - return (decoder->ip == ev->variant.async_paging.ip ? 1 : 0); + /* We reached the PTWRITE instruction and @decoder->ip points to + * it; @insn/@iext still contain the preceding instruction. + * + * Proceed beyond the PTWRITE to account for it. Note that we + * may still overflow the block, which would cause us to + * postpone both instruction and event to the next block. + */ + status = pt_blk_proceed_one_insn(decoder, block, insn, iext); + if (status <= 0) + return status; + } + + return 1; } -/* Proceed to the event location for an async vmcs event. +/* Proceed to the event location for an iret event. + * + * We have an iret event pending. Proceed to the event location and indicate + * whether we were able to reach it. * - * We have an async vmcs event pending. Proceed to the event location and - * indicate whether we were able to reach it. Needing trace in order to proceed - * is not an error in this case but ends the block. + * In case of the event binding to an iret instruction, we pass beyond that + * instruction and update the event to provide the instruction's IP. + * + * In the case of the event binding to an IP provided in the event, we move + * beyond the instruction at that IP. * * Returns a positive integer if the event location was reached. * Returns zero if the event location was not reached. * Returns a negative error code otherwise. */ -static int pt_blk_proceed_to_async_vmcs(struct pt_block_decoder *decoder, - struct pt_block *block, - const struct pt_event *ev) +static int pt_blk_proceed_to_iret(struct pt_block_decoder *decoder, + struct pt_block *block, + struct pt_insn *insn, + struct pt_insn_ext *iext, + struct pt_event *ev) { int status; - if (!decoder || !ev) + if (!insn || !ev) return -pte_internal; - /* Apply the event immediately if we don't have an IP. */ - if (ev->ip_suppressed) - return 1; + /* If we don't have an IP, the event binds to the next IRET + * instruction. + * + * If we have an IP it still binds to the next IRET instruction but now + * the IP tells us where that instruction is. This makes most sense + * when tracing is disabled and we don't have any other means of + * finding the IRET instruction. We nevertheless distinguish the two + * cases, here. + * + * In both cases, we move beyond the IRET instruction, so it will be + * the last instruction in the current block and @decoder->ip will + * point to the instruction following it. + */ + if (ev->ip_suppressed) { + status = pt_blk_proceed_to_insn(decoder, block, insn, iext, + pt_insn_is_iret); + if (status <= 0) + return status; - status = pt_blk_proceed_to_ip_with_trace(decoder, block, - ev->variant.async_vmcs.ip); - if (status < 0) - return status; + /* We now know the IP of the IRET instruction corresponding to + * this event. Fill it in to make it more convenient for the + * user to process the event. + */ + ev->variant.iret.ip = insn->ip; + ev->ip_suppressed = 0; + } else { + status = pt_blk_proceed_to_ip(decoder, block, insn, iext, + ev->variant.iret.ip); + if (status <= 0) + return status; - /* We may have reached the IP. */ - return (decoder->ip == ev->variant.async_vmcs.ip ? 1 : 0); + /* We reached the IRET instruction and @decoder->ip points to + * it; @insn/@iext still contain the preceding instruction. + * + * Proceed beyond the IRET to account for it. Note that we may + * still overflow the block, which would cause us to postpone + * both instruction and event to the next block. + */ + status = pt_blk_proceed_one_insn(decoder, block, insn, iext); + if (status <= 0) + return status; + } + + return 1; } -/* Proceed to the event location for an exec mode event. +/* Proceed to the event location for a vmentry event. + * + * We have a vmentry event pending. Proceed to the event location and indicate + * whether we were able to reach it. * - * We have an exec mode event pending. Proceed to the event location and - * indicate whether we were able to reach it. Needing trace in order to proceed - * is not an error in this case but ends the block. + * In case of the event binding to a vmentry instruction, we pass beyond that + * instruction and update the event to provide the instruction's IP. + * + * In the case of the event binding to an IP provided in the event, we move + * beyond the instruction at that IP. * * Returns a positive integer if the event location was reached. * Returns zero if the event location was not reached. * Returns a negative error code otherwise. */ -static int pt_blk_proceed_to_exec_mode(struct pt_block_decoder *decoder, - struct pt_block *block, - const struct pt_event *ev) +static int pt_blk_proceed_to_vmentry(struct pt_block_decoder *decoder, + struct pt_block *block, + struct pt_insn *insn, + struct pt_insn_ext *iext, + struct pt_event *ev) { int status; - if (!decoder || !ev) + if (!insn || !ev) return -pte_internal; - /* Apply the event immediately if we don't have an IP. */ - if (ev->ip_suppressed) - return 1; + /* If we don't have an IP, the event binds to the next vmentry + * instruction. + * + * If we have an IP it still binds to the next vmentry instruction but + * now the IP tells us where that instruction is. This makes most + * sense when tracing is disabled and we don't have any other means of + * finding the vmentry instruction. We nevertheless distinguish the + * two cases, here. + * + * In both cases, we move beyond the vmentry instruction, so it will be + * the last instruction in the current block and @decoder->ip will + * point to the instruction following it. + */ + if (ev->ip_suppressed) { + status = pt_blk_proceed_to_insn(decoder, block, insn, iext, + pt_insn_is_vmentry); + if (status <= 0) + return status; - status = pt_blk_proceed_to_ip_with_trace(decoder, block, - ev->variant.exec_mode.ip); - if (status < 0) - return status; + /* We now know the IP of the vmentry instruction corresponding + * to this event. Fill it in to make it more convenient for + * the user to process the event. + */ + ev->variant.vmentry.ip = insn->ip; + ev->ip_suppressed = 0; + } else { + status = pt_blk_proceed_to_ip(decoder, block, insn, iext, + ev->variant.vmentry.ip); + if (status <= 0) + return status; - /* We may have reached the IP. */ - return (decoder->ip == ev->variant.exec_mode.ip ? 1 : 0); + /* We reached the vmentry instruction and @decoder->ip points + * to it; @insn/@iext still contain the preceding instruction. + * + * Proceed beyond the vmentry to account for it. Note that we + * may still overflow the block, which would cause us to + * postpone both instruction and event to the next block. + */ + status = pt_blk_proceed_one_insn(decoder, block, insn, iext); + if (status <= 0) + return status; + } + + return 1; } -/* Proceed to the event location for a ptwrite event. +/* Proceed to the event location for an uiret event. * - * We have a ptwrite event pending. Proceed to the event location and indicate + * We have an uiret event pending. Proceed to the event location and indicate * whether we were able to reach it. * - * In case of the event binding to a ptwrite instruction, we pass beyond that + * In case of the event binding to an uiret instruction, we pass beyond that * instruction and update the event to provide the instruction's IP. * * In the case of the event binding to an IP provided in the event, we move @@ -1251,52 +1377,52 @@ * Returns zero if the event location was not reached. * Returns a negative error code otherwise. */ -static int pt_blk_proceed_to_ptwrite(struct pt_block_decoder *decoder, - struct pt_block *block, - struct pt_insn *insn, - struct pt_insn_ext *iext, - struct pt_event *ev) +static int pt_blk_proceed_to_uiret(struct pt_block_decoder *decoder, + struct pt_block *block, + struct pt_insn *insn, + struct pt_insn_ext *iext, + struct pt_event *ev) { int status; if (!insn || !ev) return -pte_internal; - /* If we don't have an IP, the event binds to the next PTWRITE + /* If we don't have an IP, the event binds to the next UIRET * instruction. * - * If we have an IP it still binds to the next PTWRITE instruction but - * now the IP tells us where that instruction is. This makes most sense - * when tracing is disabled and we don't have any other means of finding - * the PTWRITE instruction. We nevertheless distinguish the two cases, - * here. - * - * In both cases, we move beyond the PTWRITE instruction, so it will be - * the last instruction in the current block and @decoder->ip will point - * to the instruction following it. + * If we have an IP it still binds to the next UIRET instruction but + * now the IP tells us where that instruction is. This makes most + * sense when tracing is disabled and we don't have any other means of + * finding the UIRET instruction. We nevertheless distinguish the two + * cases, here. + * + * In both cases, we move beyond the UIRET instruction, so it will be + * the last instruction in the current block and @decoder->ip will + * point to the instruction following it. */ if (ev->ip_suppressed) { status = pt_blk_proceed_to_insn(decoder, block, insn, iext, - pt_insn_is_ptwrite); + pt_insn_is_uiret); if (status <= 0) return status; - /* We now know the IP of the PTWRITE instruction corresponding - * to this event. Fill it in to make it more convenient for the + /* We now know the IP of the UIRET instruction corresponding to + * this event. Fill it in to make it more convenient for the * user to process the event. */ - ev->variant.ptwrite.ip = insn->ip; + ev->variant.uiret.ip = insn->ip; ev->ip_suppressed = 0; } else { status = pt_blk_proceed_to_ip(decoder, block, insn, iext, - ev->variant.ptwrite.ip); + ev->variant.uiret.ip); if (status <= 0) return status; - /* We reached the PTWRITE instruction and @decoder->ip points to + /* We reached the UIRET instruction and @decoder->ip points to * it; @insn/@iext still contain the preceding instruction. * - * Proceed beyond the PTWRITE to account for it. Note that we + * Proceed beyond the UIRET to account for it. Note that we * may still overflow the block, which would cause us to * postpone both instruction and event to the next block. */ @@ -1393,6 +1519,9 @@ decoder->bound_paging = 0; decoder->bound_vmcs = 0; decoder->bound_ptwrite = 0; + decoder->bound_iret = 0; + decoder->bound_vmentry = 0; + decoder->bound_uiret = 0; return 0; } @@ -1458,7 +1587,7 @@ struct pt_event *ev; int status; - if (!decoder || !decoder->process_event || !block) + if (!decoder || !block) return -pte_internal; ev = &decoder->event; @@ -1467,6 +1596,9 @@ break; case ptev_disabled: + if (ev->status_update) + break; + status = pt_blk_proceed_to_disabled(decoder, block, &insn, &iext, ev); if (status <= 0) { @@ -1484,13 +1616,19 @@ break; - case ptev_async_disabled: + case ptev_async_disabled: { + const struct pt_config *config; + status = pt_blk_proceed_to_ip(decoder, block, &insn, &iext, ev->variant.async_disabled.at); if (status <= 0) return status; - if (decoder->query.config.errata.skd022) { + config = pt_blk_config(decoder); + if (!config) + return -pte_internal; + + if (config->errata.skd022) { status = pt_blk_handle_erratum_skd022(decoder, ev); if (status != 0) { if (status < 0) @@ -1504,6 +1642,7 @@ } break; + } case ptev_async_branch: status = pt_blk_proceed_to_ip(decoder, block, &insn, &iext, @@ -1530,7 +1669,11 @@ return pt_blk_postpone_insn(decoder, &insn, &iext); case ptev_async_paging: - status = pt_blk_proceed_to_async_paging(decoder, block, ev); + if (ev->ip_suppressed) + break; + + status = pt_blk_proceed_to_ip(decoder, block, &insn, &iext, + ev->variant.async_paging.ip); if (status <= 0) return status; @@ -1553,7 +1696,11 @@ return pt_blk_postpone_insn(decoder, &insn, &iext); case ptev_async_vmcs: - status = pt_blk_proceed_to_async_vmcs(decoder, block, ev); + if (ev->ip_suppressed) + break; + + status = pt_blk_proceed_to_ip(decoder, block, &insn, &iext, + ev->variant.async_vmcs.ip); if (status <= 0) return status; @@ -1563,7 +1710,11 @@ break; case ptev_exec_mode: - status = pt_blk_proceed_to_exec_mode(decoder, block, ev); + if (ev->ip_suppressed) + break; + + status = pt_blk_proceed_to_ip(decoder, block, &insn, &iext, + ev->variant.exec_mode.ip); if (status <= 0) return status; @@ -1629,6 +1780,141 @@ case ptev_cbr: case ptev_mnt: break; + + case ptev_tip: + case ptev_tnt: + return -pte_internal; + + case ptev_iflags: + if (ev->ip_suppressed) + break; + + status = pt_blk_proceed_to_ip(decoder, block, &insn, &iext, + ev->variant.iflags.ip); + if (status <= 0) + return status; + + break; + + case ptev_interrupt: + if (ev->ip_suppressed) + break; + + status = pt_blk_proceed_to_ip(decoder, block, &insn, &iext, + ev->variant.interrupt.ip); + if (status <= 0) + return status; + + break; + + case ptev_iret: + if (!decoder->enabled) + break; + + status = pt_blk_proceed_to_iret(decoder, block, &insn, &iext, + ev); + if (status <= 0) + return status; + + /* We bound an iret event. Make sure we do not bind further + * iret events to this instruction. + */ + decoder->bound_iret = 1; + + return pt_blk_postpone_insn(decoder, &insn, &iext); + + case ptev_smi: + if (ev->ip_suppressed) + break; + + status = pt_blk_proceed_to_ip(decoder, block, &insn, &iext, + ev->variant.smi.ip); + if (status <= 0) + return status; + + break; + + case ptev_rsm: + break; + + case ptev_sipi: + break; + + case ptev_init: + if (ev->ip_suppressed) + break; + + status = pt_blk_proceed_to_ip(decoder, block, &insn, &iext, + ev->variant.init.ip); + if (status <= 0) + return status; + + break; + + case ptev_vmentry: + if (!decoder->enabled) + break; + + status = pt_blk_proceed_to_vmentry(decoder, block, &insn, + &iext, ev); + if (status <= 0) + return status; + + /* We bound a vmentry event. Make sure we do not bind further + * vmentry events to this instruction. + */ + decoder->bound_vmentry = 1; + + return pt_blk_postpone_insn(decoder, &insn, &iext); + + case ptev_vmexit: + if (ev->ip_suppressed) + break; + + status = pt_blk_proceed_to_ip(decoder, block, &insn, &iext, + ev->variant.vmexit.ip); + if (status <= 0) + return status; + + break; + + case ptev_shutdown: + if (ev->ip_suppressed) + break; + + status = pt_blk_proceed_to_ip(decoder, block, &insn, &iext, + ev->variant.shutdown.ip); + if (status <= 0) + return status; + + break; + + case ptev_uintr: + if (ev->ip_suppressed) + break; + + status = pt_blk_proceed_to_ip(decoder, block, &insn, &iext, + ev->variant.uintr.ip); + if (status <= 0) + return status; + + break; + + case ptev_uiret: + if (!decoder->enabled) + break; + + status = pt_blk_proceed_to_uiret(decoder, block, &insn, &iext, + ev); + if (status <= 0) + return status; + + /* We bound an uiret event. Make sure we do not bind further + * uiret events to this instruction. + */ + decoder->bound_uiret = 1; + + return pt_blk_postpone_insn(decoder, &insn, &iext); } return pt_blk_status(decoder, pts_event_pending); @@ -1817,7 +2103,7 @@ switch (insn.iclass) { case ptic_ptwrite: - case ptic_error: + case ptic_unknown: case ptic_other: return -pte_internal; @@ -1848,6 +2134,7 @@ case ptic_far_call: case ptic_far_return: case ptic_far_jump: + case ptic_indirect: bce.qualifier = ptbq_indirect; break; } @@ -2193,8 +2480,8 @@ decoder->ip = nip; /* We don't know the instruction class so we should be setting it to - * ptic_error. Since we will be able to fill it back in later in most - * cases, we move the clearing to the switch cases that don't. + * ptic_unknown. Since we will be able to fill it back in later in + * most cases, we move the clearing to the switch cases that don't. */ block->end_ip = nip; block->ninsn = ninsn; @@ -2211,7 +2498,7 @@ * clear any previously stored instruction class which has * become invalid when we updated @block->ninsn. */ - block->iclass = ptic_error; + block->iclass = ptic_unknown; return pt_blk_proceed_no_event_cached(decoder, block, bcache, msec); @@ -2229,7 +2516,7 @@ */ if (bce.isize) { uint64_t ip; - int taken; + int tnt; /* If the branch is not taken, we don't need to decode * the instruction at @decoder->ip. @@ -2238,20 +2525,15 @@ * We can't use the normal decode and proceed-with-trace * flow since we already consumed the TNT bit. */ - status = pt_blk_cond_branch(decoder, &taken); - if (status < 0) - return status; - - /* Preserve the query decoder's response which indicates - * upcoming events. - */ - decoder->status = status; - ip = decoder->ip; - if (taken) { + tnt = pt_blk_cond_branch(decoder); + if (tnt != 0) { struct pt_insn_ext iext; struct pt_insn insn; + if (tnt < 0) + return tnt; + memset(&iext, 0, sizeof(iext)); memset(&insn, 0, sizeof(insn)); @@ -2268,7 +2550,8 @@ } decoder->ip = ip + bce.isize; - break; + + return 0; } fallthrough; @@ -2331,7 +2614,7 @@ (insn.iclass == ptic_call)) || (decoder->flags.variant.block.end_on_jump && (insn.iclass == ptic_jump))) - break; + return 0; /* If we can proceed without trace and we stay in @msec we may * proceed further. @@ -2339,7 +2622,7 @@ * We're done if we switch sections, though. */ if (!pt_blk_is_in_section(msec, decoder->ip)) - break; + return 0; return pt_blk_proceed_no_event_cached(decoder, block, bcache, msec); @@ -2382,53 +2665,34 @@ if (status < 0) return status; - status = pt_blk_indirect_branch(decoder, &decoder->ip); - if (status < 0) - return status; - - /* Preserve the query decoder's response which indicates - * upcoming events. - */ - decoder->status = status; - break; + return pt_blk_proceed_indirect(decoder); } case ptbq_return: { - int taken; + int tnt; /* We're at a near return. */ block->iclass = ptic_return; - /* Check for a compressed return. */ - status = pt_blk_cond_branch(decoder, &taken); - if (status < 0) { - if (status != -pte_bad_query) - return status; - - /* The return is not compressed. We need another query - * to determine the destination IP. - */ - status = pt_blk_indirect_branch(decoder, &decoder->ip); - if (status < 0) - return status; - - /* Preserve the query decoder's response which indicates - * upcoming events. + /* Check for a compressed return. + * + * It is indicated by a taken conditional branch. + */ + tnt = pt_blk_cond_branch(decoder); + if (tnt <= 0) { + /* If we do not have a TNT bit, the return is not + * compressed. + * + * We need another query to determine the destination. */ - decoder->status = status; - break; - } + if (tnt == -pte_bad_query) + return pt_blk_proceed_indirect(decoder); - /* Preserve the query decoder's response which indicates - * upcoming events. - */ - decoder->status = status; + if (!tnt) + tnt = -pte_bad_retcomp; - /* A compressed return is indicated by a taken conditional - * branch. - */ - if (!taken) - return -pte_bad_retcomp; + return tnt; + } return pt_retstack_pop(&decoder->retstack, &decoder->ip); } @@ -2439,28 +2703,19 @@ * We don't know the exact instruction class and there's no * reason to decode the instruction for any other purpose. * - * Indicate that we don't know the instruction class and leave - * it to our caller to decode the instruction if needed. + * Leave it to our caller to decode the instruction if needed. */ - block->iclass = ptic_error; + block->iclass = ptic_indirect; /* This is neither a near call nor return so we don't need to * touch the return-address stack. * * Just query the destination IP. */ - status = pt_blk_indirect_branch(decoder, &decoder->ip); - if (status < 0) - return status; - - /* Preserve the query decoder's response which indicates - * upcoming events. - */ - decoder->status = status; - break; + return pt_blk_proceed_indirect(decoder); } - return 0; + return -pte_internal; } static int pt_blk_msec_fill(struct pt_block_decoder *decoder, @@ -2573,31 +2828,57 @@ static int pt_blk_proceed(struct pt_block_decoder *decoder, struct pt_block *block) { + const struct pt_event *ev; int status; - status = pt_blk_fetch_event(decoder); - if (status != 0) { + if (!decoder) + return -pte_internal; + + /* Report deferred event decode errors. */ + status = decoder->status; + if (status < 0) { + if (status != -pte_eos) + return status; + + /* If we ran out of trace, we still allow the user to proceed + * until we actually need trace. We indicate the upcoming end + * of the trace on each pt_blk_next() or pt_blk_event() call. + * + * This allows the user to stitch traces from adjacent PSB + * segments together. + * + * We do need tracing to be enabled, though. + */ + if (!decoder->enabled) + return -pte_eos; + + status = pt_blk_proceed_no_event(decoder, block); if (status < 0) return status; - return pt_blk_proceed_event(decoder, block); + return pts_eos; } - /* If tracing is disabled we should either be out of trace or we should - * have taken the event flow above. - */ - if (!decoder->enabled) { - if (decoder->status & pts_eos) - return -pte_eos; + ev = &decoder->event; + switch (ev->type) { + case ptev_tnt: + case ptev_tip: + /* Tracing must be enabled. + * + * If we ran out of trace we should have taken the above route. + */ + if (!decoder->enabled) + return -pte_no_enable; - return -pte_no_enable; - } + status = pt_blk_proceed_no_event(decoder, block); + if (status < 0) + return status; - status = pt_blk_proceed_no_event(decoder, block); - if (status < 0) - return status; + return pt_blk_proceed_trailing_event(decoder, block); - return pt_blk_proceed_trailing_event(decoder, block); + default: + return pt_blk_proceed_event(decoder, block); + } } enum { @@ -2691,10 +2972,19 @@ if (ev->ip_suppressed) return 0; - if (block && decoder->query.config.errata.bdm64) { - status = pt_blk_handle_erratum_bdm64(decoder, block, ev); - if (status < 0) - return 1; + if (block) { + const struct pt_config *config; + + config = pt_blk_config(decoder); + if (!config) + return -pte_internal; + + if (config->errata.bdm64) { + status = pt_blk_handle_erratum_bdm64(decoder, block, + ev); + if (status < 0) + return 1; + } } if (decoder->ip != ev->variant.tsx.ip) @@ -2726,20 +3016,83 @@ if (!decoder) return -pte_internal; - status = pt_blk_fetch_event(decoder); - if (status <= 0) { - if (status < 0) - return status; + /* Check if there is an event to process. */ + status = decoder->status; + if (status < 0) { + int errcode, flags; - status = pt_blk_proceed_postponed_insn(decoder); - if (status < 0) - return status; + /* Proceed past any postponed instruction. */ + errcode = pt_blk_proceed_postponed_insn(decoder); + if (errcode < 0) + return errcode; + + /* Indicate a pending event to have higher layers query the + * event decode error, unless we just want to indicate the end + * of the trace, which is handled by pt_blk_status(). + */ + flags = 0; + if (status != -pte_eos) + flags |= pts_event_pending; - return pt_blk_status(decoder, 0); + return pt_blk_status(decoder, flags); } ev = &decoder->event; switch (ev->type) { + case ptev_tnt: + /* Synthesize a tick event on the first used TNT bit. + * + * We do not actually need to track whether this is the first + * or any other bit in the current TNT event. On the second + * bit, the decoder's TSC will already match the event's. + * + * This also covers TNT events that did not get their own + * timestamp, e.g. due to non-zero CYC threshold. They will + * not receive a separate tick event. + */ + + /* We only generate tick events on request, during normal + * processing, and only once. + */ + if (!decoder->flags.variant.block.enable_tick_events || + !block || + (!ev->has_tsc || (ev->tsc == decoder->tsc))) { + /* We're done if this TNT event is still in use. */ + if (ev->variant.tnt.size) + break; + + /* We postponed fetching the next event when we used up + * all the TNT bits to also cover 1-bit TNT events. + * + * Fetch it now that we decided to not generate a tick + * event. + */ + status = pt_blk_fetch_event(decoder); + if (status < 0) + return status; + + /* This may expose new trailing events. */ + return pt_blk_proceed_trailing_event(decoder, block); + } + + /* Postpone the tick event if we had to break the block. */ + if ((block->iclass != ptic_cond_jump) && + (block->iclass != ptic_return)) + break; + + return pt_blk_status(decoder, pts_event_pending); + + case ptev_tip: + break; + + case ptev_tick: + /* This event does not bind to an instruction. */ + status = pt_blk_proceed_postponed_insn(decoder); + if (status < 0) + return status; + + return pt_blk_status(decoder, pts_event_pending); + case ptev_disabled: /* Synchronous disable events are normally indicated on the * event flow. @@ -2792,7 +3145,9 @@ return pt_blk_status(decoder, pts_event_pending); - case ptev_async_disabled: + case ptev_async_disabled: { + const struct pt_config *config; + /* This event does not bind to an instruction. */ status = pt_blk_proceed_postponed_insn(decoder); if (status < 0) @@ -2801,7 +3156,11 @@ if (decoder->ip != ev->variant.async_disabled.at) break; - if (decoder->query.config.errata.skd022) { + config = pt_blk_config(decoder); + if (!config) + return -pte_internal; + + if (config->errata.skd022) { status = pt_blk_handle_erratum_skd022(decoder, ev); if (status != 0) { if (status < 0) @@ -2817,6 +3176,7 @@ } return pt_blk_status(decoder, pts_event_pending); + } case ptev_async_branch: /* This event does not bind to an instruction. */ @@ -2923,6 +3283,22 @@ if (status < 0) return status; + /* With Event Tracing, we may get exec_mode events with an IP + * while tracing is disabled. + * + * One scenario would be BranchEn=0; another scenario would be + * IP filtering, which affects PacketEn, but not ContextEn, so + * we may still see MODE.EXEC due to IF changes while tracing + * is disabled as long as we are in context. + * + * The event decoder re-orders exec_mode and enabled events + * originating from MODE.EXEC + TIP.PGE sequences such that the + * enabled event comes first and events that bind to the enable + * IP follow, such as paging, vmcs, or mode. + */ + if (!decoder->enabled) + return pt_blk_status(decoder, pts_event_pending); + if (!ev->ip_suppressed && decoder->ip != ev->variant.exec_mode.ip) break; @@ -3014,7 +3390,6 @@ return pt_blk_status(decoder, pts_event_pending); - case ptev_tick: case ptev_cbr: case ptev_mnt: /* This event does not bind to an instruction. */ @@ -3023,6 +3398,198 @@ return status; return pt_blk_status(decoder, pts_event_pending); + + case ptev_iflags: + /* This event does not bind to an instruction. */ + status = pt_blk_proceed_postponed_insn(decoder); + if (status < 0) + return status; + + if (decoder->enabled && !ev->ip_suppressed && + decoder->ip != ev->variant.iflags.ip) + break; + + return pt_blk_status(decoder, pts_event_pending); + + case ptev_interrupt: + /* This event does not bind to an instruction. */ + status = pt_blk_proceed_postponed_insn(decoder); + if (status < 0) + return status; + + if (decoder->enabled && !ev->ip_suppressed && + decoder->ip != ev->variant.interrupt.ip) + break; + + return pt_blk_status(decoder, pts_event_pending); + + case ptev_iret: + /* We apply the event immediately if we're not tracing. */ + if (!decoder->enabled) + return pt_blk_status(decoder, pts_event_pending); + + /* Iret events are normally indicated on the event flow, unless + * they bind to the same instruction as a previous event. + * + * We bind at most one iret event to an instruction, though. + */ + if (!decoder->process_insn || decoder->bound_iret) + break; + + /* We're done if we're not binding to the currently postponed + * instruction. We will process the event on the normal event + * flow in the next iteration. + */ + if (!ev->ip_suppressed || + !pt_insn_is_iret(&decoder->insn, &decoder->iext)) + break; + + /* We bound an iret event. Make sure we do not bind further + * iret events to this instruction. + */ + decoder->bound_iret = 1; + + return pt_blk_status(decoder, pts_event_pending); + + case ptev_smi: + /* This event does not bind to an instruction. */ + status = pt_blk_proceed_postponed_insn(decoder); + if (status < 0) + return status; + + if (decoder->enabled && !ev->ip_suppressed && + decoder->ip != ev->variant.smi.ip) + break; + + return pt_blk_status(decoder, pts_event_pending); + + case ptev_rsm: + /* This event does not bind to an instruction. */ + status = pt_blk_proceed_postponed_insn(decoder); + if (status < 0) + return status; + + if (!ev->ip_suppressed) + return -pte_internal; + + return pt_blk_status(decoder, pts_event_pending); + + case ptev_sipi: + /* This event does not bind to an instruction. */ + status = pt_blk_proceed_postponed_insn(decoder); + if (status < 0) + return status; + + if (!ev->ip_suppressed) + return -pte_internal; + + return pt_blk_status(decoder, pts_event_pending); + + case ptev_init: + /* This event does not bind to an instruction. */ + status = pt_blk_proceed_postponed_insn(decoder); + if (status < 0) + return status; + + if (decoder->enabled && !ev->ip_suppressed && + decoder->ip != ev->variant.init.ip) + break; + + return pt_blk_status(decoder, pts_event_pending); + + case ptev_vmentry: + /* We apply the event immediately if we're not tracing. */ + if (!decoder->enabled) + return pt_blk_status(decoder, pts_event_pending); + + /* Vmentry events are normally indicated on the event flow, + * unless they bind to the same instruction as a previous + * event. + * + * We bind at most one vmentry event to an instruction, though. + */ + if (!decoder->process_insn || decoder->bound_vmentry) + break; + + /* We're done if we're not binding to the currently postponed + * instruction. We will process the event on the normal event + * flow in the next iteration. + */ + if (!ev->ip_suppressed || + !pt_insn_is_vmentry(&decoder->insn, &decoder->iext)) + break; + + /* We bound a vmentry event. Make sure we do not bind further + * vmentry events to this instruction. + */ + decoder->bound_vmentry = 1; + + return pt_blk_status(decoder, pts_event_pending); + + case ptev_vmexit: + /* This event does not bind to an instruction. */ + status = pt_blk_proceed_postponed_insn(decoder); + if (status < 0) + return status; + + if (decoder->enabled && !ev->ip_suppressed && + decoder->ip != ev->variant.vmexit.ip) + break; + + return pt_blk_status(decoder, pts_event_pending); + + case ptev_shutdown: + /* This event does not bind to an instruction. */ + status = pt_blk_proceed_postponed_insn(decoder); + if (status < 0) + return status; + + if (decoder->enabled && !ev->ip_suppressed && + decoder->ip != ev->variant.shutdown.ip) + break; + + return pt_blk_status(decoder, pts_event_pending); + + case ptev_uintr: + /* This event does not bind to an instruction. */ + status = pt_blk_proceed_postponed_insn(decoder); + if (status < 0) + return status; + + if (decoder->enabled && !ev->ip_suppressed && + decoder->ip != ev->variant.uintr.ip) + break; + + return pt_blk_status(decoder, pts_event_pending); + + case ptev_uiret: + /* We apply the event immediately if we're not tracing. */ + if (!decoder->enabled) + return pt_blk_status(decoder, pts_event_pending); + + /* Uiret events are normally indicated on the event flow, + * unless they bind to the same instruction as a previous + * event. + * + * We bind at most one uiret event to an instruction, though. + */ + if (!decoder->process_insn || decoder->bound_uiret) + break; + + /* We're done if we're not binding to the currently postponed + * instruction. We will process the event on the normal event + * flow in the next iteration. + */ + if (!ev->ip_suppressed || + !pt_insn_is_uiret(&decoder->insn, &decoder->iext)) + break; + + /* We bound an uiret event. Make sure we do not bind further + * uiret events to this instruction. + */ + decoder->bound_uiret = 1; + + return pt_blk_status(decoder, pts_event_pending); } /* No further events. Proceed past any postponed instruction. */ @@ -3080,9 +3647,13 @@ if (!decoder || !ev) return -pte_internal; - /* This event can't be a status update. */ - if (ev->status_update) - return -pte_bad_context; + /* Use status update events to diagnose inconsistencies. */ + if (ev->status_update) { + if (!decoder->enabled) + return -pte_bad_status_update; + + return 0; + } /* We must have an IP in order to start decoding. */ if (ev->ip_suppressed) @@ -3094,7 +3665,6 @@ decoder->ip = ev->variant.enabled.ip; decoder->enabled = 1; - decoder->process_event = 0; return 0; } @@ -3109,9 +3679,13 @@ if (!decoder || !ev) return -pte_internal; - /* This event can't be a status update. */ - if (ev->status_update) - return -pte_bad_context; + /* Use status update events to diagnose inconsistencies. */ + if (ev->status_update) { + if (decoder->enabled) + return -pte_bad_status_update; + + return 0; + } /* We must currently be enabled. */ if (!decoder->enabled) @@ -3122,7 +3696,6 @@ * actually does resume from there. */ decoder->enabled = 0; - decoder->process_event = 0; return 0; } @@ -3149,7 +3722,6 @@ * next iteration. */ decoder->ip = ev->variant.async_branch.to; - decoder->process_event = 0; return 0; } @@ -3176,8 +3748,6 @@ decoder->asid.cr3 = cr3; } - decoder->process_event = 0; - return 0; } @@ -3203,8 +3773,6 @@ decoder->asid.vmcs = vmcs; } - decoder->process_event = 0; - return 0; } @@ -3248,7 +3816,6 @@ * instruction. */ decoder->speculative = 0; - decoder->process_event = 0; return 0; } @@ -3272,7 +3839,6 @@ return -pte_bad_status_update; decoder->mode = mode; - decoder->process_event = 0; return 0; } @@ -3288,7 +3854,6 @@ return -pte_internal; decoder->speculative = ev->variant.tsx.speculative; - decoder->process_event = 0; return 0; } @@ -3311,7 +3876,20 @@ if (decoder->enabled) return -pte_bad_context; - decoder->process_event = 0; + return 0; +} + +/* Process a cbr event. + * + * Returns zero on success, a negative error code otherwise. + */ +static int pt_blk_process_cbr(struct pt_block_decoder *decoder, + const struct pt_event *ev) +{ + if (!decoder || !ev) + return -pte_internal; + + decoder->cbr = ev->variant.cbr.ratio; return 0; } @@ -3320,17 +3898,68 @@ size_t size) { struct pt_event *ev; - int status; + int errcode; if (!decoder || !uevent) return -pte_invalid; - /* We must currently process an event. */ - if (!decoder->process_event) - return -pte_bad_query; + /* Report any deferred event decode errors. */ + errcode = decoder->status; + if (errcode < 0) + return errcode; + + /* Make sure we're not writing beyond the memory provided by the user. + * + * We might truncate details of an event but only for those events the + * user can't know about, anyway. + */ + if (sizeof(*ev) < size) + size = sizeof(*ev); ev = &decoder->event; switch (ev->type) { + case ptev_tnt: { + /* Synthesize a tick event on the first used TNT bit. */ + struct pt_event tick; + + if (!decoder->flags.variant.block.enable_tick_events) + return -pte_bad_query; + + if (!ev->has_tsc || (ev->tsc == decoder->tsc)) + return -pte_bad_query; + + memset(&tick, 0, sizeof(tick)); + tick.type = ptev_tick; + tick.has_tsc = 1; + tick.tsc = ev->tsc; + tick.lost_mtc = ev->lost_mtc; + tick.lost_cyc = ev->lost_cyc; + tick.variant.tick.ip = decoder->ip; + + /* We normally update the decoder's TSC when fetching the next + * event. In this case, however, we use the timestamp to + * ensure we send at most one tick event per TNT. Unlike other + * events, the TNT event remains active. + */ + decoder->has_tsc = 1; + decoder->tsc = tick.tsc; + decoder->lost_mtc = tick.lost_mtc; + decoder->lost_cyc = tick.lost_cyc; + + /* Copy the event to the user. */ + memcpy(uevent, &tick, size); + + /* Only fetch the next event if we used up all TNT bits. */ + if (!ev->variant.tnt.size) { + errcode = pt_blk_fetch_event(decoder); + if (errcode < 0) + return errcode; + } + + /* Indicate further events. */ + return pt_blk_proceed_trailing_event(decoder, NULL); + } + case ptev_enabled: /* Indicate that tracing resumes from the IP at which tracing * had been disabled before (with some special treatment for @@ -3339,9 +3968,9 @@ if (ev->variant.enabled.ip == decoder->ip) ev->variant.enabled.resumed = 1; - status = pt_blk_process_enabled(decoder, ev); - if (status < 0) - return status; + errcode = pt_blk_process_enabled(decoder, ev); + if (errcode < 0) + return errcode; break; @@ -3352,9 +3981,9 @@ fallthrough; case ptev_disabled: - status = pt_blk_process_disabled(decoder, ev); - if (status < 0) - return status; + errcode = pt_blk_process_disabled(decoder, ev); + if (errcode < 0) + return errcode; break; @@ -3362,9 +3991,9 @@ if (decoder->ip != ev->variant.async_branch.from) return -pte_bad_query; - status = pt_blk_process_async_branch(decoder, ev); - if (status < 0) - return status; + errcode = pt_blk_process_async_branch(decoder, ev); + if (errcode < 0) + return errcode; break; @@ -3375,9 +4004,9 @@ fallthrough; case ptev_paging: - status = pt_blk_process_paging(decoder, ev); - if (status < 0) - return status; + errcode = pt_blk_process_paging(decoder, ev); + if (errcode < 0) + return errcode; break; @@ -3388,27 +4017,27 @@ fallthrough; case ptev_vmcs: - status = pt_blk_process_vmcs(decoder, ev); - if (status < 0) - return status; + errcode = pt_blk_process_vmcs(decoder, ev); + if (errcode < 0) + return errcode; break; case ptev_overflow: - status = pt_blk_process_overflow(decoder, ev); - if (status < 0) - return status; + errcode = pt_blk_process_overflow(decoder, ev); + if (errcode < 0) + return errcode; break; case ptev_exec_mode: - if (!ev->ip_suppressed && + if (decoder->enabled && !ev->ip_suppressed && decoder->ip != ev->variant.exec_mode.ip) return -pte_bad_query; - status = pt_blk_process_exec_mode(decoder, ev); - if (status < 0) - return status; + errcode = pt_blk_process_exec_mode(decoder, ev); + if (errcode < 0) + return errcode; break; @@ -3416,16 +4045,16 @@ if (!ev->ip_suppressed && decoder->ip != ev->variant.tsx.ip) return -pte_bad_query; - status = pt_blk_process_tsx(decoder, ev); - if (status < 0) - return status; + errcode = pt_blk_process_tsx(decoder, ev); + if (errcode < 0) + return errcode; break; case ptev_stop: - status = pt_blk_process_stop(decoder, ev); - if (status < 0) - return status; + errcode = pt_blk_process_stop(decoder, ev); + if (errcode < 0) + return errcode; break; @@ -3434,7 +4063,6 @@ decoder->ip != ev->variant.exstop.ip) return -pte_bad_query; - decoder->process_event = 0; break; case ptev_mwait: @@ -3442,30 +4070,98 @@ decoder->ip != ev->variant.mwait.ip) return -pte_bad_query; - decoder->process_event = 0; break; case ptev_pwre: case ptev_pwrx: case ptev_ptwrite: case ptev_tick: - case ptev_cbr: case ptev_mnt: - decoder->process_event = 0; + case ptev_iret: + case ptev_vmentry: + case ptev_uiret: break; - } - /* Copy the event to the user. Make sure we're not writing beyond the - * memory provided by the user. - * - * We might truncate details of an event but only for those events the - * user can't know about, anyway. - */ - if (sizeof(*ev) < size) - size = sizeof(*ev); + case ptev_cbr: + errcode = pt_blk_process_cbr(decoder, ev); + if (errcode < 0) + return errcode; + + break; + + case ptev_tip: + return -pte_bad_query; + + case ptev_iflags: + if (decoder->enabled && !ev->ip_suppressed && + decoder->ip != ev->variant.iflags.ip) + return -pte_bad_query; + + break; + + case ptev_interrupt: + if (decoder->enabled && !ev->ip_suppressed && + decoder->ip != ev->variant.interrupt.ip) + return -pte_bad_query; + + break; + + case ptev_smi: + if (decoder->enabled && !ev->ip_suppressed && + decoder->ip != ev->variant.smi.ip) + return -pte_bad_query; + break; + + case ptev_rsm: + if (!ev->ip_suppressed) + return -pte_internal; + + break; + + case ptev_sipi: + if (!ev->ip_suppressed) + return -pte_internal; + + break; + + case ptev_init: + if (decoder->enabled && !ev->ip_suppressed && + decoder->ip != ev->variant.init.ip) + return -pte_bad_query; + + break; + + case ptev_vmexit: + if (decoder->enabled && !ev->ip_suppressed && + decoder->ip != ev->variant.vmexit.ip) + return -pte_bad_query; + + break; + + case ptev_shutdown: + if (decoder->enabled && !ev->ip_suppressed && + decoder->ip != ev->variant.shutdown.ip) + return -pte_bad_query; + + break; + + case ptev_uintr: + if (decoder->enabled && !ev->ip_suppressed && + decoder->ip != ev->variant.uintr.ip) + return -pte_bad_query; + + break; + } + + /* Copy the event to the user. */ memcpy(uevent, ev, size); + /* Fetch the next event. */ + errcode = pt_blk_fetch_event(decoder); + if (errcode < 0) + return errcode; + /* Indicate further events. */ return pt_blk_proceed_trailing_event(decoder, NULL); }
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/src/pt_config.c -> _service:tar_scm:v2.1.tar.gz/libipt/src/pt_config.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -75,6 +76,9 @@ case 0x6a: case 0x6c: case 0x8f: + case 0xad: + case 0xae: + case 0xcf: errata->bdm70 = 1; errata->skl014 = 1; errata->skd022 = 1; @@ -96,6 +100,12 @@ case 0x97: case 0x9a: case 0xbf: + case 0xb7: + case 0xb5: + case 0xaa: + case 0xac: + case 0xba: + case 0xcc: errata->bdm70 = 1; errata->skl014 = 1; errata->skd022 = 1; @@ -112,6 +122,9 @@ case 0x86: case 0x96: case 0x9c: + case 0xb6: + case 0xaf: + case 0xdd: errata->apl11 = 1; return 0; }
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/src/pt_cpu.c -> _service:tar_scm:v2.1.tar.gz/libipt/src/pt_cpu.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -27,7 +28,6 @@ */ #include "pt_cpu.h" -#include "pt_cpuid.h" #include "intel-pt.h" @@ -35,60 +35,6 @@ #include <stdlib.h> -static const char * const cpu_vendors = { - "", - "GenuineIntel" -}; - -enum { - pt_cpuid_vendor_size = 12 -}; - -union cpu_vendor { - /* The raw data returned from cpuid. */ - struct { - uint32_t ebx; - uint32_t edx; - uint32_t ecx; - } cpuid; - - /* The resulting vendor string. */ - char vendor_stringpt_cpuid_vendor_size; -}; - -static enum pt_cpu_vendor cpu_vendor(void) -{ - union cpu_vendor vendor; - uint32_t eax; - size_t i; - - memset(&vendor, 0, sizeof(vendor)); - eax = 0; - - pt_cpuid(0u, &eax, &vendor.cpuid.ebx, &vendor.cpuid.ecx, - &vendor.cpuid.edx); - - for (i = 0; i < sizeof(cpu_vendors)/sizeof(*cpu_vendors); i++) - if (strncmp(vendor.vendor_string, - cpu_vendorsi, pt_cpuid_vendor_size) == 0) - return (enum pt_cpu_vendor) i; - - return pcv_unknown; -} - -static uint32_t cpu_info(void) -{ - uint32_t eax, ebx, ecx, edx; - - eax = 0; - ebx = 0; - ecx = 0; - edx = 0; - pt_cpuid(1u, &eax, &ebx, &ecx, &edx); - - return eax; -} - int pt_cpu_parse(struct pt_cpu *cpu, const char *s) { const char sep = '/'; @@ -137,28 +83,3 @@ return 0; } - -int pt_cpu_read(struct pt_cpu *cpu) -{ - uint32_t info; - uint16_t family; - - if (!cpu) - return -pte_invalid; - - cpu->vendor = cpu_vendor(); - - info = cpu_info(); - - cpu->family = family = (info>>8) & 0xf; - if (family == 0xf) - cpu->family += (info>>20) & 0xf; - - cpu->model = (info>>4) & 0xf; - if (family == 0x6 || family == 0xf) - cpu->model += (info>>12) & 0xf0; - - cpu->stepping = (info>>0) & 0xf; - - return 0; -}
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/src/pt_encoder.c -> _service:tar_scm:v2.1.tar.gz/libipt/src/pt_encoder.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2014-2022, Intel Corporation + * Copyright (c) 2014-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -384,6 +385,9 @@ if (packet->payload.mode.bits.exec.csd) mode |= pt_mob_exec_csd; + + if (packet->payload.mode.bits.exec.iflag) + mode |= pt_mob_exec_iflag; break; case pt_mol_tsx: @@ -681,6 +685,42 @@ return (int) (pos - begin); } + case ppt_cfe: { + uint8_t type; + + errcode = pt_reserve(encoder, ptps_cfe); + if (errcode < 0) + return errcode; + + *pos++ = pt_opc_ext; + *pos++ = pt_ext_cfe; + + type = packet->payload.cfe.type & pt_pl_cfe_type; + if (packet->payload.cfe.ip) + type |= pt_pl_cfe_ip; + + *pos++ = type; + *pos++ = packet->payload.cfe.vector; + + encoder->pos = pos; + return (int) (pos - begin); + } + + case ppt_evd: + errcode = pt_reserve(encoder, ptps_evd); + if (errcode < 0) + return errcode; + + *pos++ = pt_opc_ext; + *pos++ = pt_ext_evd; + + *pos++ = packet->payload.evd.type & pt_pl_evd_type; + pos = pt_encode_int(pos, packet->payload.evd.payload, + pt_pl_evd_pl_size); + + encoder->pos = pos; + return (int) (pos - begin); + case ppt_unknown: case ppt_invalid: return -pte_bad_opc;
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/src/pt_error.c -> _service:tar_scm:v2.1.tar.gz/libipt/src/pt_error.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.1.tar.gz/libipt/src/pt_event_decoder.c
Added
@@ -0,0 +1,3877 @@ +/* + * Copyright (c) 2018-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "pt_event_decoder.h" +#include "pt_compiler.h" +#include "pt_opcodes.h" +#include "pt_config.h" + +#include <stdlib.h> +#include <string.h> +#include <limits.h> + + +/* Initialize the packet decoder flags based on our flags. */ + +static int pt_evt_init_pkt_flags(struct pt_conf_flags *pflags, + const struct pt_conf_flags *flags) +{ + if (!pflags || !flags) + return -pte_internal; + + memset(pflags, 0, sizeof(*pflags)); + + return 0; +} + +static int pt_evt_reset(struct pt_event_decoder *decoder) +{ + if (!decoder) + return -pte_internal; + + decoder->packet.type = ppt_invalid; + decoder->status = -pte_nosync; + decoder->event = NULL; + decoder->enabled = 0; + decoder->bound = 0; + decoder->mode_exec_valid = 0; + + pt_last_ip_init(&decoder->ip); + pt_time_init(&decoder->time); + pt_tcal_init(&decoder->tcal); + pt_evq_init(&decoder->evq); + + return 0; +} + +int pt_evt_decoder_init(struct pt_event_decoder *decoder, + const struct pt_config *uconfig) +{ + struct pt_config config; + int errcode; + + if (!decoder) + return -pte_internal; + + errcode = pt_config_from_user(&config, uconfig); + if (errcode < 0) + return errcode; + + /* The user supplied decoder flags. */ + decoder->flags = config.flags; + + /* Set the flags we need for the packet decoder we use. */ + errcode = pt_evt_init_pkt_flags(&config.flags, &decoder->flags); + if (errcode < 0) + return errcode; + + errcode = pt_pkt_decoder_init(&decoder->pacdec, &config); + if (errcode < 0) + return errcode; + + return pt_evt_reset(decoder); +} + +void pt_evt_decoder_fini(struct pt_event_decoder *decoder) +{ + if (!decoder) + return; + + pt_pkt_decoder_fini(&decoder->pacdec); +} + +struct pt_event_decoder *pt_evt_alloc_decoder(const struct pt_config *config) +{ + struct pt_event_decoder *decoder; + int errcode; + + decoder = malloc(sizeof(*decoder)); + if (!decoder) + return NULL; + + errcode = pt_evt_decoder_init(decoder, config); + if (errcode < 0) { + free(decoder); + return NULL; + } + + return decoder; +} + +void pt_evt_free_decoder(struct pt_event_decoder *decoder) +{ + if (!decoder) + return; + + pt_evt_decoder_fini(decoder); + free(decoder); +} + +/* Fetch the next packet and return zero. + * + * Fetch the next packet using the packet decoder and store away any error + * return for later. + * + * Can be used to return from a packet decode function to indicate that the + * current packet has been processed completely and resulted in an event. + * + * Returns zero on success, a negative pt_error_code otherwise. + */ +static int pt_evt_fetch_packet(struct pt_event_decoder *decoder) +{ + int status; + + if (!decoder) + return -pte_internal; + + /* Skip PAD packets right here. + * + * This isn't strictly necessary but it gives more useful offsets. + */ + do { + status = pt_pkt_next(&decoder->pacdec, &decoder->packet, + sizeof(decoder->packet)); + if (status < 0) { + /* Store any error to be delivered later. */ + decoder->packet.type = ppt_invalid; + decoder->packet.size = 0; + decoder->status = status; + + break; + } + } while (decoder->packet.type == ppt_pad); + + return 0; +} + +static int pt_evt_event_time(struct pt_event *ev, const struct pt_time *time) +{ + int errcode; + + if (!ev || !time) + return -pte_internal; + + errcode = pt_time_query_tsc(&ev->tsc, &ev->lost_mtc, &ev->lost_cyc, + time); + if (errcode < 0) { + if (errcode != -pte_no_time) + return errcode; + } else + ev->has_tsc = 1; + + return 0; +} + +static int pt_evt_event_ip(uint64_t *ip, struct pt_event *ev, + const struct pt_last_ip *last_ip) +{ + int errcode; + + if (!ev) + return -pte_internal; + + errcode = pt_last_ip_query(ip, last_ip); + if (errcode < 0) { + switch (pt_errcode(errcode)) { + case pte_noip: + case pte_ip_suppressed: + ev->ip_suppressed = 1; + break; + + default: + return errcode; + } + } + + return 0; +} + +/* Find a FUP in a PSB+ header. + * + * @pacdec must be synchronized onto the trace stream at the beginning or + * somewhere inside a PSB+ header. + * + * @packet holds trace packets during the search. If the search is successful, + * @packet will contain the first (and hopefully only) FUP packet in this PSB+. + * Otherwise, @packet may contain anything. + * + * Returns one if a FUP packet is found (@packet will contain it). + * Returns zero if no FUP packet is found (@packet is undefined). + * Returns a negative error code otherwise. + */ +static int pt_evt_find_header_fup(struct pt_packet *packet, + const struct pt_packet_decoder *pacdec) +{ + struct pt_packet_decoder decoder; + + if (!packet || !pacdec) + return -pte_internal; + + decoder = *pacdec; + for (;;) { + int errcode; + + errcode = pt_pkt_next(&decoder, packet, sizeof(*packet)); + if (errcode < 0) + return errcode; + + switch (packet->type) { + case ppt_fup: + /* Found it. */ + return 1; + + case ppt_mode: + case ppt_pip: + case ppt_vmcs: + case ppt_mnt: + case ppt_tsc: + case ppt_cbr: + case ppt_tma: + case ppt_mtc: + case ppt_cyc: + case ppt_pad: + case ppt_invalid: + /* Ignore the packet. */ + break; + + case ppt_psbend: + case ppt_ovf: + /* There's no FUP in here. */ + return 0; + + default: + return -pte_bad_context; + } + } +} + +static int pt_evt_apply_header_tsc(struct pt_time *time, + struct pt_time_cal *tcal, + const struct pt_packet_tsc *packet, + const struct pt_config *config) +{ + int errcode; + + /* We ignore configuration errors. They will result in imprecise + * calibration which will result in imprecise cycle-accurate timing. + */ + errcode = pt_tcal_header_tsc(tcal, packet, config); + if ((errcode < 0) && (errcode != -pte_bad_config)) + return errcode; + + /* We ignore configuration errors. They will result in imprecise + * timing and are tracked as packet losses in struct pt_time. + */ + errcode = pt_time_update_tsc(time, packet, config); + if ((errcode < 0) && (errcode != -pte_bad_config)) + return errcode; + + return 0; +} + +static int pt_evt_header_tsc(struct pt_event_decoder *decoder, + const struct pt_packet_tsc *packet) +{ + return pt_evt_apply_header_tsc(&decoder->time, &decoder->tcal, packet, + pt_evt_config(decoder)); +} + +static int pt_evt_apply_tsc(struct pt_time *time, struct pt_time_cal *tcal, + const struct pt_packet_tsc *packet, + const struct pt_config *config) +{ + int errcode; + + /* We ignore configuration errors. They will result in imprecise + * calibration which will result in imprecise cycle-accurate timing. + */ + errcode = pt_tcal_update_tsc(tcal, packet, config); + if ((errcode < 0) && (errcode != -pte_bad_config)) + return errcode; + + /* We ignore configuration errors. They will result in imprecise + * timing and are tracked as packet losses in struct pt_time. + */ + errcode = pt_time_update_tsc(time, packet, config); + if ((errcode < 0) && (errcode != -pte_bad_config)) + return errcode; + + return 0; +} + +static int pt_evt_decode_tsc(struct pt_event_decoder *decoder, + const struct pt_packet_tsc *packet) +{ + int errcode; + + errcode = pt_evt_apply_tsc(&decoder->time, &decoder->tcal, packet, + pt_evt_config(decoder)); + if (errcode < 0) + return errcode; + + return 1; +} + +static int pt_evt_apply_header_cbr(struct pt_time *time, + struct pt_time_cal *tcal, + const struct pt_packet_cbr *packet, + const struct pt_config *config) +{ + int errcode; + + if (!packet) + return -pte_internal; + + /* We ignore configuration errors. They will result in imprecise + * calibration which will result in imprecise cycle-accurate timing. + */ + errcode = pt_tcal_header_cbr(tcal, packet, config); + if ((errcode < 0) && (errcode != -pte_bad_config)) + return errcode; + + /* We ignore configuration errors. They will result in imprecise + * timing and are tracked as packet losses in struct pt_time. + */ + errcode = pt_time_update_cbr(time, packet, config); + if ((errcode < 0) && (errcode != -pte_bad_config)) + return errcode; + + return 0; +} + +static int pt_evt_header_cbr(struct pt_event_decoder *decoder, + const struct pt_packet_cbr *packet) +{ + struct pt_event *ev; + int errcode; + + if (!decoder) + return -pte_internal; + + errcode = pt_evt_apply_header_cbr(&decoder->time, &decoder->tcal, + packet, pt_evt_config(decoder)); + if (errcode < 0) + return errcode; + + ev = pt_evq_enqueue(&decoder->evq, evb_psbend); + if (!ev) + return -pte_nomem; + + ev->status_update = 1; + ev->type = ptev_cbr; + ev->variant.cbr.ratio = packet->ratio; + + return 0; +} + +static int pt_evt_apply_cbr(struct pt_time *time, struct pt_time_cal *tcal, + const struct pt_packet_cbr *packet, + const struct pt_config *config) +{ + int errcode; + + if (!packet) + return -pte_internal; + + /* We ignore configuration errors. They will result in imprecise + * calibration which will result in imprecise cycle-accurate timing. + */ + errcode = pt_tcal_update_cbr(tcal, packet, config); + if ((errcode < 0) && (errcode != -pte_bad_config)) + return errcode; + + /* We ignore configuration errors. They will result in imprecise + * timing and are tracked as packet losses in struct pt_time. + */ + errcode = pt_time_update_cbr(time, packet, config); + if ((errcode < 0) && (errcode != -pte_bad_config)) + return errcode; + + return 0; +} + +static int pt_evt_decode_cbr(struct pt_event_decoder *decoder, + const struct pt_packet_cbr *packet) +{ + struct pt_event *ev; + int errcode; + + if (!decoder) + return -pte_internal; + + errcode = pt_evt_apply_cbr(&decoder->time, &decoder->tcal, packet, + pt_evt_config(decoder)); + if (errcode < 0) + return errcode; + + decoder->event = ev = pt_evq_standalone(&decoder->evq); + if (!ev) + return -pte_internal; + + ev->type = ptev_cbr; + ev->variant.cbr.ratio = packet->ratio; + + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + return errcode; + + return pt_evt_fetch_packet(decoder); +} + +static int pt_evt_apply_tma(struct pt_time *time, struct pt_time_cal *tcal, + const struct pt_packet_tma *packet, + const struct pt_config *config) +{ + int errcode; + + /* We ignore configuration errors. They will result in imprecise + * calibration which will result in imprecise cycle-accurate timing. + */ + errcode = pt_tcal_update_tma(tcal, packet, config); + if ((errcode < 0) && (errcode != -pte_bad_config)) + return errcode; + + /* We ignore configuration errors. They will result in imprecise + * timing and are tracked as packet losses in struct pt_time. + */ + errcode = pt_time_update_tma(time, packet, config); + if ((errcode < 0) && (errcode != -pte_bad_config)) + return errcode; + + return 0; +} + +static int pt_evt_header_tma(struct pt_event_decoder *decoder, + const struct pt_packet_tma *packet) +{ + return pt_evt_apply_tma(&decoder->time, &decoder->tcal, packet, + pt_evt_config(decoder)); +} + +static int pt_evt_decode_tma(struct pt_event_decoder *decoder, + const struct pt_packet_tma *packet) +{ + int errcode; + + errcode = pt_evt_apply_tma(&decoder->time, &decoder->tcal, packet, + pt_evt_config(decoder)); + if (errcode < 0) + return errcode; + + return 1; +} + +static int pt_evt_apply_mtc(struct pt_time *time, struct pt_time_cal *tcal, + const struct pt_packet_mtc *packet, + const struct pt_config *config) +{ + int errcode; + + /* We ignore configuration errors. They will result in imprecise + * calibration which will result in imprecise cycle-accurate timing. + */ + errcode = pt_tcal_update_mtc(tcal, packet, config); + if ((errcode < 0) && (errcode != -pte_bad_config)) + return errcode; + + /* We ignore configuration errors. They will result in imprecise + * timing and are tracked as packet losses in struct pt_time. + */ + errcode = pt_time_update_mtc(time, packet, config); + if ((errcode < 0) && (errcode != -pte_bad_config)) + return errcode; + + return 0; +} + +static int pt_evt_header_mtc(struct pt_event_decoder *decoder, + const struct pt_packet_mtc *packet) +{ + return pt_evt_apply_mtc(&decoder->time, &decoder->tcal, packet, + pt_evt_config(decoder)); +} + +static int pt_evt_decode_mtc(struct pt_event_decoder *decoder, + const struct pt_packet_mtc *packet) +{ + int errcode; + + errcode = pt_evt_apply_mtc(&decoder->time, &decoder->tcal, packet, + pt_evt_config(decoder)); + if (errcode < 0) + return errcode; + + return 1; +} + +static int pt_evt_apply_cyc(struct pt_time *time, struct pt_time_cal *tcal, + const struct pt_packet_cyc *packet, + const struct pt_config *config) +{ + uint64_t fcr; + int errcode; + + /* We ignore configuration errors. They will result in imprecise + * calibration which will result in imprecise cycle-accurate timing. + */ + errcode = pt_tcal_update_cyc(tcal, packet, config); + if ((errcode < 0) && (errcode != -pte_bad_config)) + return errcode; + + /* We need the FastCounter to Cycles ratio below. Fall back to + * an invalid ratio of 0 if calibration has not kicked in, yet. + * + * This will be tracked as packet loss in struct pt_time. + */ + errcode = pt_tcal_fcr(&fcr, tcal); + if (errcode < 0) { + if (errcode == -pte_no_time) + fcr = 0ull; + else + return errcode; + } + + /* We ignore configuration errors. They will result in imprecise + * timing and are tracked as packet losses in struct pt_time. + */ + errcode = pt_time_update_cyc(time, packet, config, fcr); + if ((errcode < 0) && (errcode != -pte_bad_config)) + return errcode; + + return 0; +} + +static int pt_evt_header_cyc(struct pt_event_decoder *decoder, + const struct pt_packet_cyc *packet) +{ + return pt_evt_apply_cyc(&decoder->time, &decoder->tcal, packet, + pt_evt_config(decoder)); +} + +static int pt_evt_decode_cyc(struct pt_event_decoder *decoder, + const struct pt_packet_cyc *packet) +{ + int errcode; + + errcode = pt_evt_apply_cyc(&decoder->time, &decoder->tcal, packet, + pt_evt_config(decoder)); + if (errcode < 0) + return errcode; + + return 1; +} + +static int pt_evt_check_bdm70(struct pt_event_decoder *decoder) +{ + struct pt_packet_decoder pacdec; + + if (!decoder) + return -pte_internal; + + pacdec = decoder->pacdec; + for (;;) { + struct pt_packet packet; + int errcode; + + errcode = pt_pkt_next(&pacdec, &packet, sizeof(packet)); + if (errcode < 0) { + /* Running out of packets is not an error. */ + if (errcode == -pte_eos) + errcode = 0; + + return errcode; + } + + switch (packet.type) { + default: + /* All other packets cancel our search. + * + * We do not enumerate those packets since we also want + * to include new packets. + */ + return 0; + + case ppt_tip_pge: + /* We found it - the erratum applies. */ + return 1; + + case ppt_pad: + case ppt_tsc: + case ppt_cbr: + case ppt_psbend: + case ppt_pip: + case ppt_mode: + case ppt_vmcs: + case ppt_tma: + case ppt_mtc: + case ppt_cyc: + case ppt_mnt: + /* Intentionally skip a few packets. */ + break; + } + } +} + +static int pt_evt_header_fup(struct pt_event_decoder *decoder, + const struct pt_packet_ip *packet) +{ + const struct pt_config *config; + unsigned int enabled; + int errcode; + + if (!decoder || !packet) + return -pte_internal; + + enabled = (packet->ipc != pt_ipc_suppressed); + + config = pt_evt_config(decoder); + if (!config) + return -pte_internal; + + if (config->errata.bdm70) { + errcode = pt_evt_check_bdm70(decoder); + if (errcode < 0) + return errcode; + + if (errcode) + enabled = 0; + } + + decoder->enabled = enabled; + if (!enabled) + return 0; + + return pt_last_ip_update_ip(&decoder->ip, packet, config); +} + +static int pt_evt_header_mode(struct pt_event_decoder *decoder, + const struct pt_packet_mode *packet) +{ + struct pt_event *ev; + + if (!decoder || !packet) + return -pte_internal; + + switch (packet->leaf) { + case pt_mol_exec: + /* If our mode.exec state is already initialized, we can use + * the status update packet to diagnose inconsistencies. + * + * Use it to initialize our state, otherwise. + */ + if (decoder->mode_exec_valid) { + /* The iflag status may be inconsistent unless Event + * Tracing is enabled as we would not get all updates. + */ + if (decoder->flags.variant.event.enable_iflags_events && + (decoder->iflag != packet->bits.exec.iflag)) + return -pte_bad_status_update; + + if (decoder->csd != packet->bits.exec.csd) + return -pte_bad_status_update; + + if (decoder->csl != packet->bits.exec.csl) + return -pte_bad_status_update; + } else { + decoder->mode_exec_valid = 1; + decoder->iflag = packet->bits.exec.iflag; + decoder->csd = packet->bits.exec.csd; + decoder->csl = packet->bits.exec.csl; + } + + ev = pt_evq_enqueue(&decoder->evq, evb_psbend); + if (!ev) + return -pte_nomem; + + ev->status_update = 1; + ev->type = ptev_exec_mode; + ev->variant.exec_mode.mode = + pt_get_exec_mode(&packet->bits.exec); + + if (decoder->flags.variant.event.enable_iflags_events) { + ev = pt_evq_enqueue(&decoder->evq, evb_psbend); + if (!ev) + return -pte_nomem; + + ev->status_update = 1; + ev->type = ptev_iflags; + ev->variant.iflags.iflag = packet->bits.exec.iflag; + } + break; + + case pt_mol_tsx: + ev = pt_evq_enqueue(&decoder->evq, evb_psbend); + if (!ev) + return -pte_nomem; + + ev->status_update = 1; + ev->type = ptev_tsx; + ev->variant.tsx.speculative = packet->bits.tsx.intx; + ev->variant.tsx.aborted = packet->bits.tsx.abrt; + break; + } + + return 0; +} + +static int pt_evt_decode_mode_exec(struct pt_event_decoder *decoder, + const struct pt_packet_mode_exec *packet) +{ + struct pt_event *ev; + int nevents; + + if (!decoder || !packet) + return -pte_internal; + + /* Mode.exec contains two pieces of information: + * + * - the execution mode + * - the interrupt flag + * + * Split this into exec_mode or iflags events depending on which of the + * pieces was changed. + * + * If nothing changed, e.g. because the h/w did not suppress a + * mode.exec after a tracing pause, we may end up without an event. + * Since we still need to bind the mode.exec packet, add an + * internal-only ignore event that will be dropped at the binding + * packet. + */ + nevents = 0; + if (!decoder->mode_exec_valid || + (decoder->csl != packet->csl) || (decoder->csd != packet->csd)) { + ev = pt_evq_enqueue(&decoder->evq, evb_tip | evb_fup_bound); + if (!ev) + return -pte_nomem; + + ev->type = ptev_exec_mode; + ev->variant.exec_mode.mode = pt_get_exec_mode(packet); + + decoder->csl = packet->csl; + decoder->csd = packet->csd; + + nevents += 1; + } + + if (decoder->flags.variant.event.enable_iflags_events && + (!decoder->mode_exec_valid || (decoder->iflag != packet->iflag))) { + ev = pt_evq_enqueue(&decoder->evq, evb_tip | evb_fup_bound); + if (!ev) + return -pte_nomem; + + ev->type = ptev_iflags; + ev->variant.iflags.iflag = packet->iflag; + + decoder->iflag = packet->iflag; + + nevents += 1; + } + + if (!nevents) { + ev = pt_evq_enqueue(&decoder->evq, evb_tip | evb_fup_bound); + if (!ev) + return -pte_nomem; + + ev->type = ptev_ignore; + } + + decoder->mode_exec_valid = 1; + return 1; +} + +static int pt_evt_decode_mode_tsx(struct pt_event_decoder *decoder, + const struct pt_packet_mode_tsx *packet) +{ + struct pt_event *ev; + int errcode; + + if (!decoder || !packet) + return -pte_internal; + + if (decoder->enabled) { + uint32_t evb; + + evb = packet->abrt ? evb_fup : evb_fup_bound; + ev = pt_evq_enqueue(&decoder->evq, evb); + if (!ev) + return -pte_nomem; + + ev->type = ptev_tsx; + ev->variant.tsx.speculative = packet->intx; + ev->variant.tsx.aborted = packet->abrt; + + return 1; + } + + decoder->event = ev = pt_evq_standalone(&decoder->evq); + if (!ev) + return -pte_internal; + + ev->type = ptev_tsx; + ev->variant.tsx.speculative = packet->intx; + ev->variant.tsx.aborted = packet->abrt; + + ev->variant.tsx.ip = 0ull; + ev->ip_suppressed = 1; + + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + return errcode; + + return pt_evt_fetch_packet(decoder); +} + +static int pt_evt_decode_mode(struct pt_event_decoder *decoder, + const struct pt_packet_mode *packet) +{ + if (!packet) + return -pte_internal; + + switch (packet->leaf) { + case pt_mol_exec: + return pt_evt_decode_mode_exec(decoder, + &packet->bits.exec); + + case pt_mol_tsx: + return pt_evt_decode_mode_tsx(decoder, + &packet->bits.tsx); + } + + return -pte_bad_opc; +} + +static int pt_evt_header_pip(struct pt_event_decoder *decoder, + const struct pt_packet_pip *packet) +{ + struct pt_event *ev; + + if (!decoder || !packet) + return -pte_internal; + + ev = pt_evq_enqueue(&decoder->evq, evb_psbend); + if (!ev) + return -pte_nomem; + + ev->status_update = 1; + ev->type = ptev_async_paging; + ev->variant.async_paging.cr3 = packet->cr3; + ev->variant.async_paging.non_root = packet->nr; + + return 0; +} + +static int pt_evt_decode_pip(struct pt_event_decoder *decoder, + const struct pt_packet_pip *packet) +{ + struct pt_event *ev; + int errcode; + + if (!decoder || !packet) + return -pte_internal; + + /* PIP is standalone or binds to the same TIP as an unbound FUP. + * + * That unbound FUP will queue an async branch event at TIP. Let's + * search for that. + */ + ev = pt_evq_find(&decoder->evq, evb_tip, ptev_async_branch); + if (ev) { + ev = pt_evq_enqueue(&decoder->evq, evb_tip); + if (!ev) + return -pte_nomem; + + ev->type = ptev_async_paging; + ev->variant.async_paging.cr3 = packet->cr3; + ev->variant.async_paging.non_root = packet->nr; + + return 1; + } + + decoder->event = ev = pt_evq_standalone(&decoder->evq); + if (!ev) + return -pte_internal; + + ev->type = ptev_paging; + ev->variant.paging.cr3 = packet->cr3; + ev->variant.paging.non_root = packet->nr; + + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + return errcode; + + return pt_evt_fetch_packet(decoder); +} + +static int pt_evt_header_vmcs(struct pt_event_decoder *decoder, + const struct pt_packet_vmcs *packet) +{ + struct pt_event *ev; + + if (!decoder || !packet) + return -pte_internal; + + ev = pt_evq_enqueue(&decoder->evq, evb_psbend); + if (!ev) + return -pte_nomem; + + ev->status_update = 1; + ev->type = ptev_async_vmcs; + ev->variant.async_vmcs.base = packet->base; + + return 0; +} + +static int pt_evt_decode_vmcs(struct pt_event_decoder *decoder, + const struct pt_packet_vmcs *packet) +{ + struct pt_event *ev; + int errcode; + + if (!decoder || !packet) + return -pte_internal; + + /* When getting both PIP and VMCS between the FUP and TIP of an + * asynchronous branch, we order VMCS before PIP. + * + * A preceding PIP will queue an async paging event. Let's search for + * it. When we find one, we re-purpose that event slot to hold the + * VMCS and add nother entry for the original async paging event. + */ + ev = pt_evq_find(&decoder->evq, evb_tip, ptev_async_paging); + if (ev) { + struct pt_event *paging; + + paging = pt_evq_enqueue(&decoder->evq, evb_tip); + if (!paging) + return -pte_nomem; + + *paging = *ev; + + ev->type = ptev_async_vmcs; + ev->variant.async_vmcs.base = packet->base; + + return 1; + } + + /* VMCS is standalone or binds to the same TIP as an unbound FUP. + * + * That unbound FUP will queue an async branch event at TIP. Let's + * search for that. + * + * A standalone VMCS will bind to a VMPTRLD, VMRESUME, or VMLAUNCH + * instruction and will have to be bound by a higher-layer decoder. + */ + ev = pt_evq_find(&decoder->evq, evb_tip, ptev_async_branch); + if (ev) { + ev = pt_evq_enqueue(&decoder->evq, evb_tip); + if (!ev) + return -pte_nomem; + + ev->type = ptev_async_vmcs; + ev->variant.async_vmcs.base = packet->base; + + return 1; + } + + decoder->event = ev = pt_evq_standalone(&decoder->evq); + if (!ev) + return -pte_internal; + + ev->type = ptev_vmcs; + ev->variant.vmcs.base = packet->base; + + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + return errcode; + + return pt_evt_fetch_packet(decoder); +} + +static int pt_evt_header_mnt(struct pt_event_decoder *decoder, + const struct pt_packet_mnt *packet) +{ + struct pt_event *ev; + + if (!decoder || !packet) + return -pte_internal; + + ev = pt_evq_enqueue(&decoder->evq, evb_psbend); + if (!ev) + return -pte_nomem; + + ev->type = ptev_mnt; + ev->variant.mnt.payload = packet->payload; + + return 0; +} + +static int pt_evt_decode_mnt(struct pt_event_decoder *decoder, + const struct pt_packet_mnt *packet) +{ + struct pt_event *ev; + int errcode; + + if (!decoder || !packet) + return -pte_internal; + + decoder->event = ev = pt_evq_standalone(&decoder->evq); + if (!ev) + return -pte_internal; + + ev->type = ptev_mnt; + ev->variant.mnt.payload = packet->payload; + + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + return errcode; + + return pt_evt_fetch_packet(decoder); +} + +static int pt_evt_decode_stop(struct pt_event_decoder *decoder) +{ + struct pt_event *ev; + int errcode; + + if (!decoder) + return -pte_internal; + + decoder->event = ev = pt_evq_standalone(&decoder->evq); + if (!ev) + return -pte_internal; + + ev->type = ptev_stop; + + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + return errcode; + + return pt_evt_fetch_packet(decoder); +} + +static int pt_evt_decode_exstop(struct pt_event_decoder *decoder, + const struct pt_packet_exstop *packet) +{ + struct pt_event *ev; + int errcode; + + if (!decoder || !packet) + return -pte_internal; + + ev = pt_evq_dequeue(&decoder->evq, evb_exstop); + if (ev) { + switch (ev->type) { + case ptev_mwait: + /* If we have an IP, both MWAIT and EXSTOP bind to the + * same IP. + * + * Let's enqueue MWAIT; we'll enqueue EXSTOP below, as + * well, unless we have further events pending. In + * that case, enqueing EXSTOP will have to wait. + */ + if (packet->ip) { + struct pt_event *mwait; + + mwait = pt_evq_enqueue(&decoder->evq, + evb_fup_bound); + if (!mwait) + return -pte_nomem; + + *mwait = *ev; + break; + } + + /* If we do not have an IP, both MWAIT and EXSTOP are + * standalone. + * + * Let's publish the MWAIT; on the next call, we'll + * publish the EXSTOP. + */ + ev->variant.mwait.ip = 0ull; + ev->ip_suppressed = 1; + + decoder->event = ev; + + return pt_evt_event_time(ev, &decoder->time); + + default: + return -pte_internal; + } + } + + /* If EXSTOP.IP is set, it binds to a subsequent FUP. */ + if (packet->ip) { + ev = pt_evq_enqueue(&decoder->evq, evb_fup_bound); + if (!ev) + return -pte_nomem; + + ev->type = ptev_exstop; + + return 1; + } + + decoder->event = ev = pt_evq_standalone(&decoder->evq); + if (!ev) + return -pte_internal; + + ev->type = ptev_exstop; + + ev->variant.exstop.ip = 0ull; + ev->ip_suppressed = 1; + + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + return errcode; + + return pt_evt_fetch_packet(decoder); +} + +static int pt_evt_decode_mwait(struct pt_event_decoder *decoder, + const struct pt_packet_mwait *packet) +{ + struct pt_event *ev; + + if (!decoder || !packet) + return -pte_internal; + + ev = pt_evq_enqueue(&decoder->evq, evb_exstop); + if (!ev) + return -pte_nomem; + + ev->type = ptev_mwait; + ev->variant.mwait.hints = packet->hints; + ev->variant.mwait.ext = packet->ext; + + return 1; +} + +static int pt_evt_decode_pwre(struct pt_event_decoder *decoder, + const struct pt_packet_pwre *packet) +{ + struct pt_event *ev; + int errcode; + + if (!decoder || !packet) + return -pte_internal; + + decoder->event = ev = pt_evq_standalone(&decoder->evq); + if (!ev) + return -pte_internal; + + ev->type = ptev_pwre; + ev->variant.pwre.state = packet->state; + ev->variant.pwre.sub_state = packet->sub_state; + + if (packet->hw) + ev->variant.pwre.hw = 1; + + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + return errcode; + + return pt_evt_fetch_packet(decoder); +} + +static int pt_evt_decode_pwrx(struct pt_event_decoder *decoder, + const struct pt_packet_pwrx *packet) +{ + struct pt_event *ev; + int errcode; + + if (!decoder || !packet) + return -pte_internal; + + decoder->event = ev = pt_evq_standalone(&decoder->evq); + if (!ev) + return -pte_internal; + + ev->type = ptev_pwrx; + ev->variant.pwrx.last = packet->last; + ev->variant.pwrx.deepest = packet->deepest; + + if (packet->interrupt) + ev->variant.pwrx.interrupt = 1; + if (packet->store) + ev->variant.pwrx.store = 1; + if (packet->autonomous) + ev->variant.pwrx.autonomous = 1; + + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + return errcode; + + return pt_evt_fetch_packet(decoder); +} + +static int pt_evt_decode_ptw(struct pt_event_decoder *decoder, + const struct pt_packet_ptw *packet) +{ + struct pt_event *ev; + int errcode, size; + + if (!decoder || !packet) + return -pte_internal; + + size = pt_ptw_size(packet->plc); + if (size < 0) + return size; + + /* If PTW.IP is set, it binds to a subsequent FUP. */ + if (packet->ip) { + ev = pt_evq_enqueue(&decoder->evq, evb_fup_bound); + if (!ev) + return -pte_nomem; + + ev->type = ptev_ptwrite; + ev->variant.ptwrite.size = (uint8_t) size; + ev->variant.ptwrite.payload = packet->payload; + + return 1; + } + + decoder->event = ev = pt_evq_standalone(&decoder->evq); + if (!ev) + return -pte_internal; + + ev->type = ptev_ptwrite; + ev->variant.ptwrite.size = (uint8_t) size; + ev->variant.ptwrite.payload = packet->payload; + + ev->variant.ptwrite.ip = 0ull; + ev->ip_suppressed = 1; + + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + return errcode; + + return pt_evt_fetch_packet(decoder); +} + +/* Decode packets in the PSB+ header. + * + * Packets in PSB+ give the current state. When starting to decode, they can + * be used to initialize a decoder's state. When encountered during decode, + * they can be used to check the decoder's state for consistency. + * + * Inside PSB+ packets observe different binding rules. The order in which + * packets appear in PSB+ is undefined. We model this by binding all packets + * to PSBEND (or OVF in its place). + * + * By then, we should have gotten the current IP and TSC, so we can use them + * when reporting PSB+ events. We mark all PSB+ events as status events. + * + * Header packet decode functions return: + * + * zero.......the packet was processed successfully + * negative...an error occurred during packet processing + * + * They are not required or expected to fetch the next packet. This will be + * done by this functions. + * + * Returns one on success, a negative pt_error_code otherwise. + */ +static int pt_evt_decode_psb(struct pt_event_decoder *decoder) +{ + const struct pt_packet *packet; + struct pt_event *ev; + int errcode; + + if (!decoder) + return -pte_internal; + + /* We must not carry partial events across PSB. */ + if (pt_evq_pending(&decoder->evq, UINT32_MAX)) + return -pte_bad_context; + + pt_last_ip_init(&decoder->ip); + decoder->enabled = 0; + + /* Create an event that will represent the enabled/disabled status. + * + * We do not know the status, yet, but we want the event to be first. + * We will fill in the details when we reach PSBEND. + */ + ev = pt_evq_enqueue(&decoder->evq, evb_psbend); + if (!ev) + return -pte_nomem; + + ev->status_update = 1; + + packet = &decoder->packet; + for (;;) { + errcode = pt_evt_fetch_packet(decoder); + if (errcode < 0) + return errcode; + + switch (packet->type) { + case ppt_fup: + errcode = pt_evt_header_fup(decoder, + &packet->payload.ip); + break; + + case ppt_mode: + errcode = pt_evt_header_mode(decoder, + &packet->payload.mode); + break; + + case ppt_pip: + errcode = pt_evt_header_pip(decoder, + &packet->payload.pip); + break; + + case ppt_vmcs: + errcode = pt_evt_header_vmcs(decoder, + &packet->payload.vmcs); + break; + + case ppt_mnt: + errcode = pt_evt_header_mnt(decoder, + &packet->payload.mnt); + break; + + case ppt_tsc: + errcode = pt_evt_header_tsc(decoder, + &packet->payload.tsc); + break; + + case ppt_cbr: + errcode = pt_evt_header_cbr(decoder, + &packet->payload.cbr); + break; + + case ppt_tma: + errcode = pt_evt_header_tma(decoder, + &packet->payload.tma); + break; + + case ppt_mtc: + errcode = pt_evt_header_mtc(decoder, + &packet->payload.mtc); + break; + + case ppt_cyc: + errcode = pt_evt_header_cyc(decoder, + &packet->payload.cyc); + break; + + case ppt_psbend: + if (decoder->enabled) + ev->type = ptev_enabled; + else { + ev->type = ptev_disabled; + ev->ip_suppressed = 1; + } + + return 1; + + case ppt_ovf: { + /* When PSB+ ends with an OVF, we remove the event we + * created initially if tracing is not enabled. + * + * We may have lost the FUP and end up with an invalid + * status update that might be diagnosed before we + * reach the overflow event. + */ + if (decoder->enabled) + ev->type = ptev_enabled; + else { + const struct pt_event *head; + + head = pt_evq_dequeue(&decoder->evq, + evb_psbend); + if (head != ev) + return -pte_internal; + } + + return 1; + } + + case ppt_pad: + break; + + case ppt_invalid: + errcode = decoder->status; + break; + + default: + errcode = -pte_bad_context; + break; + } + + if (errcode < 0) + return errcode; + } +} + +static int pt_evt_start(struct pt_event_decoder *decoder) +{ + int errcode; + + if (!decoder) + return -pte_internal; + + decoder->status = 0; + + errcode = pt_evt_fetch_packet(decoder); + if (errcode < 0) + return errcode; + + switch (decoder->packet.type) { + case ppt_psb: + errcode = pt_evt_decode_psb(decoder); + if (errcode < 0) + return errcode; + + return 0; + + case ppt_invalid: + /* We should have an error. */ + errcode = decoder->status; + if (0 <= errcode) + errcode = -pte_internal; + + return errcode; + + default: + return -pte_nosync; + } +} + +int pt_evt_sync_forward(struct pt_event_decoder *decoder) +{ + int errcode; + + if (!decoder) + return -pte_invalid; + + errcode = pt_evt_reset(decoder); + if (errcode < 0) + return errcode; + + errcode = pt_pkt_sync_forward(&decoder->pacdec); + if (errcode < 0) + return errcode; + + return pt_evt_start(decoder); +} + +int pt_evt_sync_backward(struct pt_event_decoder *decoder) +{ + const uint8_t *start, *sync, *pos; + int errcode; + + if (!decoder) + return -pte_invalid; + + start = pt_evt_pos(decoder); + if (!start) { + start = pt_evt_end(decoder); + if (!start) + return -pte_bad_config; + } + + sync = start; + for (;;) { + errcode = pt_evt_reset(decoder); + if (errcode < 0) + return errcode; + + do { + errcode = pt_pkt_sync_backward(&decoder->pacdec); + if (errcode < 0) + return errcode; + + pos = pt_evt_pos(decoder); + } while (sync <= pos); + + sync = pos; + + errcode = pt_evt_start(decoder); + + pos = pt_evt_pos(decoder); + if (pos < start) + return errcode; + } +} + +int pt_evt_sync_set(struct pt_event_decoder *decoder, uint64_t offset) +{ + int errcode; + + if (!decoder) + return -pte_invalid; + + errcode = pt_evt_reset(decoder); + if (errcode < 0) + return errcode; + + errcode = pt_pkt_sync_set(&decoder->pacdec, offset); + if (errcode < 0) + return errcode; + + return pt_evt_start(decoder); +} + +int pt_evt_get_offset(const struct pt_event_decoder *decoder, uint64_t *offset) +{ + uint64_t pktoff; + int errcode; + + if (!decoder || !offset) + return -pte_invalid; + + errcode = pt_pkt_get_offset(&decoder->pacdec, &pktoff); + if (errcode < 0) + return errcode; + + *offset = pktoff - decoder->packet.size; + + return 0; +} + +int pt_evt_get_sync_offset(const struct pt_event_decoder *decoder, + uint64_t *offset) +{ + if (!decoder) + return -pte_invalid; + + return pt_pkt_get_sync_offset(&decoder->pacdec, offset); +} + +const struct pt_config * +pt_evt_get_config(const struct pt_event_decoder *decoder) +{ + if (!decoder) + return NULL; + + return pt_pkt_get_config(&decoder->pacdec); +} + +static int pt_evt_decode_psbend(struct pt_event_decoder *decoder) +{ + struct pt_event *ev; + int errcode; + + if (!decoder) + return -pte_internal; + + ev = pt_evq_dequeue(&decoder->evq, evb_psbend); + if (!ev) + return 1; + + decoder->event = ev; + + switch (ev->type) { + case ptev_enabled: + errcode = pt_evt_event_ip(&ev->variant.enabled.ip, ev, + &decoder->ip); + break; + + case ptev_exec_mode: + errcode = pt_evt_event_ip(&ev->variant.exec_mode.ip, ev, + &decoder->ip); + break; + + case ptev_iflags: + errcode = pt_evt_event_ip(&ev->variant.iflags.ip, ev, + &decoder->ip); + break; + + case ptev_tsx: + errcode = pt_evt_event_ip(&ev->variant.tsx.ip, ev, + &decoder->ip); + break; + + case ptev_async_paging: + errcode = pt_evt_event_ip(&ev->variant.async_paging.ip, ev, + &decoder->ip); + break; + + case ptev_async_vmcs: + errcode = pt_evt_event_ip(&ev->variant.async_vmcs.ip, ev, + &decoder->ip); + break; + + case ptev_disabled: + case ptev_cbr: + case ptev_mnt: + errcode = 0; + break; + + default: + errcode = -pte_bad_context; + break; + } + + if (errcode < 0) + return errcode; + + return pt_evt_event_time(ev, &decoder->time); +} + +static int pt_evt_decode_fup(struct pt_event_decoder *decoder, + const struct pt_packet_ip *packet) +{ + struct pt_event *ev; + int errcode, status; + + if (!decoder || !packet) + return -pte_internal; + + errcode = pt_last_ip_update_ip(&decoder->ip, packet, + pt_evt_config(decoder)); + if (errcode < 0) + return errcode; + + status = pt_evq_pending(&decoder->evq, evb_fup_bound); + if (status != 0) { + if (status < 0) + return status; + + decoder->bound = 1; + } + + ev = pt_evq_dequeue(&decoder->evq, evb_fup | evb_fup_bound); + if (!ev) { + uint64_t from; + + if (decoder->bound) + return 1; + + /* We must have a from IP for asynchronous branches. + * + * The event's ip_suppressed field only applies to the to field + * so we cannot really express a suppressed from IP and leave + * it to our users to diagnose. + * + * Since this case isn't allowed, anyway, we diagnose it here. + */ + errcode = pt_last_ip_query(&from, &decoder->ip); + if (errcode < 0) + return errcode; + + ev = pt_evq_enqueue(&decoder->evq, evb_tip); + if (!ev) + return -pte_nomem; + + ev->type = ptev_async_branch; + ev->variant.async_branch.from = from; + + return 1; + } + + decoder->event = ev; + + switch (ev->type) { + case ptev_overflow: + /* We preserve the time at the OVF. + * + * This may give an indication as to how long the overflow + * lasted when comparing it with the time at the next event. + */ + errcode = pt_evt_event_ip(&ev->variant.overflow.ip, ev, + &decoder->ip); + + decoder->enabled = 1; + break; + + case ptev_tsx: + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + break; + + errcode = pt_evt_event_ip(&ev->variant.tsx.ip, ev, + &decoder->ip); + break; + + case ptev_exstop: + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + break; + + errcode = pt_evt_event_ip(&ev->variant.exstop.ip, ev, + &decoder->ip); + break; + + case ptev_mwait: + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + break; + + errcode = pt_evt_event_ip(&ev->variant.mwait.ip, ev, + &decoder->ip); + break; + + case ptev_ptwrite: + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + break; + + errcode = pt_evt_event_ip(&ev->variant.ptwrite.ip, ev, + &decoder->ip); + break; + + case ptev_exec_mode: + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + break; + + errcode = pt_evt_event_ip(&ev->variant.exec_mode.ip, ev, + &decoder->ip); + break; + + case ptev_iflags: + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + break; + + errcode = pt_evt_event_ip(&ev->variant.iflags.ip, ev, + &decoder->ip); + break; + + case ptev_interrupt: + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + break; + + errcode = pt_evt_event_ip(&ev->variant.interrupt.ip, ev, + &decoder->ip); + break; + + case ptev_iret: + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + break; + + errcode = pt_evt_event_ip(&ev->variant.iret.ip, ev, + &decoder->ip); + break; + + case ptev_smi: + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + break; + + errcode = pt_evt_event_ip(&ev->variant.smi.ip, ev, + &decoder->ip); + break; + + case ptev_rsm: + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + break; + + if (!ev->ip_suppressed) + return -pte_internal; + + break; + + case ptev_sipi: + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + break; + + if (!ev->ip_suppressed) + return -pte_internal; + + break; + + case ptev_init: + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + break; + + errcode = pt_evt_event_ip(&ev->variant.init.ip, ev, + &decoder->ip); + break; + + case ptev_vmentry: + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + break; + + errcode = pt_evt_event_ip(&ev->variant.vmentry.ip, ev, + &decoder->ip); + break; + + case ptev_vmexit: + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + break; + + errcode = pt_evt_event_ip(&ev->variant.vmexit.ip, ev, + &decoder->ip); + break; + + case ptev_shutdown: + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + break; + + errcode = pt_evt_event_ip(&ev->variant.shutdown.ip, ev, + &decoder->ip); + break; + + case ptev_uintr: + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + break; + + errcode = pt_evt_event_ip(&ev->variant.uintr.ip, ev, + &decoder->ip); + break; + + case ptev_uiret: + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + break; + + errcode = pt_evt_event_ip(&ev->variant.uiret.ip, ev, + &decoder->ip); + break; + + case ptev_ignore: + decoder->event = NULL; + + return pt_evt_decode_fup(decoder, packet); + + default: + errcode = -pte_bad_context; + break; + } + + if (errcode < 0) + return errcode; + + return 0; +} + +/* Search for a FUP or a non-PacketEn packet starting at @pacdec. + * + * Returns a positive offset to (one byte after) the found FUP packet. + * Returns zero if a non-PacketEn packet is found. + * Returns a negative pt_error_code otherwise. + */ +static int pt_evt_find_ovf_fup(const struct pt_packet_decoder *pacdec) +{ + struct pt_packet_decoder decoder; + int offset; + + if (!pacdec) + return -pte_internal; + + decoder = *pacdec; + offset = 0; + for (;;) { + struct pt_packet packet; + int errcode; + + errcode = pt_pkt_next(&decoder, &packet, sizeof(packet)); + if (errcode < 0) + return errcode; + + if (!packet.size) + return -pte_bad_packet; + + offset += packet.size; + if (offset < 0) + return -pte_overflow; + + switch (packet.type) { + case ppt_fup: + return offset; + + case ppt_unknown: + case ppt_pad: + case ppt_mnt: + case ppt_cbr: + case ppt_tsc: + case ppt_tma: + case ppt_mtc: + case ppt_cyc: + case ppt_invalid: + break; + + case ppt_psb: + case ppt_tip_pge: + case ppt_mode: + case ppt_pip: + case ppt_vmcs: + case ppt_stop: + case ppt_ovf: + case ppt_exstop: + case ppt_mwait: + case ppt_pwre: + case ppt_pwrx: + case ppt_ptw: + case ppt_cfe: + case ppt_evd: + return 0; + + case ppt_psbend: + case ppt_tip: + case ppt_tip_pgd: + case ppt_tnt_8: + case ppt_tnt_64: + return -pte_bad_context; + } + } +} + +static int pt_evt_recover_ovf_at_ip(struct pt_event_decoder *decoder, + const struct pt_packet_decoder *pacdec, + const struct pt_packet *packet, + const struct pt_packet_ip *ip, + const struct pt_time *time, + const struct pt_time_cal *tcal) +{ + const struct pt_config *config; + struct pt_event *ev; + int errcode; + + if (!decoder || !pacdec || !packet || !time || !tcal) + return -pte_internal; + + config = pt_evt_config(decoder); + + errcode = pt_last_ip_update_ip(&decoder->ip, ip, config); + if (errcode < 0) + return errcode; + + decoder->event = ev = pt_evq_standalone(&decoder->evq); + if (!ev) + return -pte_internal; + + ev->type = ptev_overflow; + + /* We use the decoder's original time for this event. */ + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + return errcode; + + decoder->pacdec = *pacdec; + decoder->packet = *packet; + decoder->time = *time; + decoder->tcal = *tcal; + decoder->enabled = 1; + + return pt_evt_event_ip(&ev->variant.overflow.ip, ev, &decoder->ip); +} + +static int pt_evt_recover_ovf_disabled(struct pt_event_decoder *decoder, + const struct pt_packet_decoder *pacdec, + const struct pt_packet *packet, + const struct pt_time *time, + const struct pt_time_cal *tcal) +{ + struct pt_event *ev; + int errcode; + + if (!decoder || !pacdec || !packet || !time || !tcal) + return -pte_internal; + + decoder->event = ev = pt_evq_standalone(&decoder->evq); + if (!ev) + return -pte_internal; + + ev->type = ptev_overflow; + ev->ip_suppressed = 1; + + /* We use the decoder's original time for this event. */ + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + return errcode; + + decoder->pacdec = *pacdec; + decoder->packet = *packet; + decoder->time = *time; + decoder->tcal = *tcal; + + return 0; +} + +static int pt_evt_recover_ovf_at_offset(struct pt_event_decoder *decoder, + uint64_t offset) +{ + const struct pt_packet *packet; + struct pt_event *ev; + int errcode; + + if (!decoder || !offset) + return -pte_internal; + + packet = &decoder->packet; + for (;;) { + errcode = pt_pkt_next(&decoder->pacdec, &decoder->packet, + sizeof(decoder->packet)); + if (errcode < 0) + return errcode; + + if (offset <= packet->size) { + if (offset < packet->size) + return -pte_internal; + + break; + } + + offset -= packet->size; + + switch (packet->type) { + case ppt_tsc: + /* Keep track of time. */ + errcode = pt_evt_apply_tsc(&decoder->time, + &decoder->tcal, + &packet->payload.tsc, + pt_evt_config(decoder)); + break; + + case ppt_cbr: + /* Keep track of time. */ + errcode = pt_evt_apply_cbr(&decoder->time, + &decoder->tcal, + &packet->payload.cbr, + pt_evt_config(decoder)); + break; + + case ppt_tma: + /* Keep track of time. */ + errcode = pt_evt_apply_tma(&decoder->time, + &decoder->tcal, + &packet->payload.tma, + pt_evt_config(decoder)); + break; + + case ppt_mtc: + /* Keep track of time. */ + errcode = pt_evt_apply_mtc(&decoder->time, + &decoder->tcal, + &packet->payload.mtc, + pt_evt_config(decoder)); + break; + + case ppt_cyc: + /* Keep track of time. */ + errcode = pt_evt_apply_cyc(&decoder->time, + &decoder->tcal, + &packet->payload.cyc, + pt_evt_config(decoder)); + break; + + case ppt_mode: + case ppt_pip: + case ppt_vmcs: + /* We should not encounter those. + * + * We should not encounter a lot of packets but those + * are state-relevant; let's check them explicitly. + */ + return -pte_internal; + + case ppt_invalid: + case ppt_unknown: + /* We should not encounter those. + * + * We shouldn't have gotten here with those packets in + * our path. + */ + return -pte_internal; + + default: + /* Skip other packets. */ + break; + } + + if (errcode < 0) + return errcode; + } + + decoder->event = ev = pt_evq_standalone(&decoder->evq); + if (!ev) + return -pte_internal; + + ev->type = ptev_overflow; + ev->ip_suppressed = 1; + + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + return errcode; + + return pt_evt_fetch_packet(decoder); +} + +/* Handle erratum SKD010. + * + * Scan ahead for a packet at which to resume after an overflow. + * + * This function is called after an OVF without a corresponding FUP. This + * normally means that the overflow resolved while tracing was disabled. + * + * With erratum SKD010 it might also mean that the FUP (or TIP.PGE) was dropped. + * The overflow thus resolved while tracing was enabled (or tracing was enabled + * after the overflow resolved). Search for an indication whether tracing is + * enabled or disabled by scanning upcoming packets. + * + * If we can confirm that tracing is disabled, the erratum does not apply and we + * can continue normally. + * + * If we can confirm that tracing is enabled, the erratum applies and we try to + * recover by synchronizing at a later packet and a different IP. We will + * generate an overflow event with that IP and fetch the next packet. + * + * If we can't recover, pretend the erratum didn't apply so we run into the + * error later. Since this assumes that tracing is disabled, no harm should be + * done, i.e. no bad trace should be generated. + * + * Returns zero if the erratum was handled and an overflow event was generated. + * Returns a positive value if the overflow is not yet handled. + * Returns a negative pt_error_code otherwise. + */ +static int pt_evt_handle_skd010(struct pt_event_decoder *decoder) +{ + struct pt_packet_decoder pacdec; + struct pt_time_cal tcal; + struct pt_time time; + struct { + uint32_t found:1; + uint32_t intx:1; + uint32_t abrt:1; + } mode_tsx; + int errcode; + + if (!decoder) + return -pte_internal; + + pacdec = decoder->pacdec; + + /* Keep track of time as we skip packets. */ + time = decoder->time; + tcal = decoder->tcal; + + /* Keep track of a potential recovery point at MODE.TSX. */ + memset(&mode_tsx, 0, sizeof(mode_tsx)); + + for (;;) { + struct pt_packet packet; + struct pt_event *ev; + + errcode = pt_pkt_next(&pacdec, &packet, sizeof(packet)); + if (errcode < 0) { + /* Let's assume the trace is correct if we run out + * of packets. + */ + if (errcode == -pte_eos) + errcode = 1; + + return errcode; + } + + switch (packet.type) { + case ppt_tip_pge: + /* Everything is fine. There is nothing to do. */ + return 1; + + case ppt_tip_pgd: + /* This is a clear indication that the erratum + * applies. + * + * We synchronize after the disable. + */ + errcode = pt_evt_recover_ovf_disabled(decoder, &pacdec, + &packet, &time, + &tcal); + if (errcode < 0) + return errcode; + + return pt_evt_fetch_packet(decoder); + + case ppt_tnt_8: + case ppt_tnt_64: + /* This is a clear indication that the erratum + * apllies. + * + * Yet, we can't recover from it as we wouldn't know how + * many TNT bits will have been used when we eventually + * find an IP packet at which to resume tracing. + */ + return 1; + + case ppt_pip: + case ppt_vmcs: + /* We could track those changes and synthesize extra + * events after the overflow event when recovering from + * the erratum. This requires infrastructure that we + * don't currently have, though, so we're not going to + * do it. + * + * Instead, we ignore those changes. We already don't + * know how many other changes were lost in the + * overflow. + */ + break; + + case ppt_mode: + switch (packet.payload.mode.leaf) { + case pt_mol_exec: + /* A MODE.EXEC packet binds to TIP, i.e. + * + * TIP.PGE: everything is fine + * TIP: the erratum applies + * + * In the TIP.PGE case, we may just follow the + * normal code flow. + * + * In the TIP case, we'd be able to re-sync at + * the TIP IP but have to skip packets up to + * and including the TIP. + * + * We'd need to synthesize the MODE.EXEC event + * after the overflow event when recovering at + * the TIP. We lack the infrastructure for + * this - it's getting too complicated. + * + * Instead, we ignore the execution mode + * change; we already don't know how many more + * such changes were lost in the overflow. + */ + break; + + case pt_mol_tsx: { + struct pt_packet_mode_tsx *tsx; + + /* A MODE.TSX packet may be standalone or bind + * to FUP. + * + * If this is the second MODE.TSX, we're sure + * that tracing is disabled and everything is + * fine. + */ + if (mode_tsx.found) + return 1; + + /* If we find the FUP this packet binds to, we + * may recover at the FUP IP and restart + * processing packets from here. Remember the + * current state. + */ + tsx = &packet.payload.mode.bits.tsx; + + mode_tsx.found = 1; + mode_tsx.intx = tsx->intx; + mode_tsx.abrt = tsx->abrt; + } + break; + } + + break; + + case ppt_fup: + /* This is a pretty good indication that tracing + * is indeed enabled and the erratum applies. + * + * We overwrite the current packet with this FUP packet + * so on the next iteration we will resume from there. + */ + decoder->packet = packet; + + /* If we got a MODE.TSX packet before, we enqueue the + * tsx event. We will process it after the overflow in + * the next iteration. + */ + if (mode_tsx.found) { + ev = pt_evq_enqueue(&decoder->evq, + evb_fup_bound); + if (!ev) + return -pte_nomem; + + ev->type = ptev_tsx; + ev->variant.tsx.speculative = mode_tsx.intx; + ev->variant.tsx.aborted = mode_tsx.abrt; + } + + return pt_evt_recover_ovf_at_ip(decoder, &pacdec, + &packet, + &packet.payload.ip, + &time, &tcal); + + case ppt_tip: + /* We syhchronize at the TIP IP and continue decoding + * packets after the TIP packet. + */ + errcode = pt_evt_recover_ovf_at_ip(decoder, &pacdec, + &packet, + &packet.payload.ip, + &time, &tcal); + if (errcode < 0) + return errcode; + + return pt_evt_fetch_packet(decoder); + + case ppt_psb: { + struct pt_packet fup; + + /* We reached a synchronization point. Tracing is + * enabled if and only if the PSB+ contains a FUP. + */ + errcode = pt_evt_find_header_fup(&fup, &pacdec); + if (errcode < 0) { + /* If we ran out of packets, we can't tell. + * Let's assume the trace is correct. + */ + if (errcode == -pte_eos) + errcode = 1; + + return errcode; + } + + /* If there is no FUP, tracing is disabled and + * everything is fine. + */ + if (!errcode) + return 1; + + /* We must have a FUP. */ + if (fup.type != ppt_fup) + return -pte_internal; + + return pt_evt_recover_ovf_at_ip(decoder, &pacdec, + &packet, + &fup.payload.ip, + &time, &tcal); + } + + case ppt_psbend: + /* We shouldn't see this. */ + return -pte_bad_context; + + case ppt_ovf: + case ppt_stop: + /* It doesn't matter if it had been enabled or disabled + * before. We may resume normally. + */ + return 1; + + case ppt_pad: + case ppt_mnt: + case ppt_pwre: + case ppt_pwrx: + case ppt_evd: + /* Ignore this packet. */ + break; + + case ppt_exstop: + /* We may skip a stand-alone EXSTOP. */ + if (!packet.payload.exstop.ip) + break; + + return 1; + + case ppt_mwait: + /* To skip this packet, we'd need to take care of the + * FUP it binds to. This is getting complicated. + */ + return 1; + + case ppt_ptw: + /* We may skip a stand-alone PTW. */ + if (!packet.payload.ptw.ip) + break; + + /* To skip this packet, we'd need to take care of the + * FUP it binds to. This is getting complicated. + */ + return 1; + + case ppt_tsc: + /* Keep track of time. */ + errcode = pt_evt_apply_tsc(&time, &tcal, + &packet.payload.tsc, + &pacdec.config); + if (errcode < 0) + return errcode; + + break; + + case ppt_cbr: + /* Keep track of time. */ + errcode = pt_evt_apply_cbr(&time, &tcal, + &packet.payload.cbr, + &pacdec.config); + if (errcode < 0) + return errcode; + + break; + + case ppt_tma: + /* Keep track of time. */ + errcode = pt_evt_apply_tma(&time, &tcal, + &packet.payload.tma, + &pacdec.config); + if (errcode < 0) + return errcode; + + break; + + case ppt_mtc: + /* Keep track of time. */ + errcode = pt_evt_apply_mtc(&time, &tcal, + &packet.payload.mtc, + &pacdec.config); + if (errcode < 0) + return errcode; + + break; + + case ppt_cyc: + /* Keep track of time. */ + errcode = pt_evt_apply_cyc(&time, &tcal, + &packet.payload.cyc, + &pacdec.config); + if (errcode < 0) + return errcode; + + break; + + case ppt_cfe: + /* We may skip a stand-alone CFE. */ + if (!packet.payload.cfe.ip) + break; + + /* To skip this packet, we'd need to take care of the + * FUP it binds to. This is getting complicated. + */ + return 1; + + case ppt_unknown: + case ppt_invalid: + /* We can't skip this packet. */ + return 1; + } + } +} + +/* Handle erratum APL11. + * + * We search for a TIP.PGD and, if we find one, resume from after that packet + * with tracing disabled. On our way to the resume location we process packets + * to update our state. + * + * If we don't find a TIP.PGD but instead some other packet that indicates that + * tracing is disabled, indicate that the erratum does not apply. + * + * Any event will be dropped. + * + * Returns zero if the erratum was handled and an overflow event was generated. + * Returns a positive value if the overflow is not yet handled. + * Returns a negative pt_error_code otherwise. + */ +static int pt_evt_handle_apl11(struct pt_event_decoder *decoder) +{ + struct pt_packet_decoder pacdec; + struct pt_time_cal tcal; + struct pt_time time; + + if (!decoder) + return -pte_internal; + + pacdec = decoder->pacdec; + time = decoder->time; + tcal = decoder->tcal; + for (;;) { + struct pt_packet packet; + int errcode; + + errcode = pt_pkt_next(&pacdec, &packet, sizeof(packet)); + if (errcode < 0) + return errcode; + + switch (packet.type) { + case ppt_tip_pgd: + /* We found a TIP.PGD. The erratum applies. + * + * Resume from here with tracing disabled. + */ + errcode = pt_evt_recover_ovf_disabled(decoder, &pacdec, + &packet, &time, + &tcal); + + return pt_evt_fetch_packet(decoder); + + case ppt_fup: + case ppt_psb: + case ppt_tip_pge: + case ppt_stop: + case ppt_ovf: + case ppt_mode: + case ppt_pip: + case ppt_vmcs: + case ppt_exstop: + case ppt_mwait: + case ppt_pwre: + case ppt_pwrx: + case ppt_ptw: + /* The erratum does not apply. */ + return 1; + + case ppt_psbend: + case ppt_tip: + case ppt_tnt_8: + case ppt_tnt_64: + /* Leave it to normal decode to diagnose those. */ + return 1; + + case ppt_tsc: + /* Keep track of time. */ + errcode = pt_evt_apply_tsc(&time, &tcal, + &packet.payload.tsc, + &pacdec.config); + if (errcode < 0) + return errcode; + + break; + + case ppt_cbr: + /* Keep track of time. */ + errcode = pt_evt_apply_cbr(&time, &tcal, + &packet.payload.cbr, + &pacdec.config); + if (errcode < 0) + return errcode; + + break; + + case ppt_tma: + /* Keep track of time. */ + errcode = pt_evt_apply_tma(&time, &tcal, + &packet.payload.tma, + &pacdec.config); + if (errcode < 0) + return errcode; + + break; + + case ppt_mtc: + /* Keep track of time. */ + errcode = pt_evt_apply_mtc(&time, &tcal, + &packet.payload.mtc, + &pacdec.config); + if (errcode < 0) + return errcode; + + break; + + case ppt_cyc: + /* Keep track of time. */ + errcode = pt_evt_apply_cyc(&time, &tcal, + &packet.payload.cyc, + &pacdec.config); + if (errcode < 0) + return errcode; + + break; + + case ppt_pad: + case ppt_mnt: + case ppt_cfe: + case ppt_evd: + /* Skip those packets. */ + break; + + case ppt_unknown: + case ppt_invalid: + /* We can't skip this packet. */ + return 1; + } + } +} + + +/* Handle erratum APL12. + * + * This function is called when a FUP is found after an OVF. The @offset + * argument gives the relative offset from @decoder's current position to after + * the FUP. + * + * A FUP after OVF normally indicates that the overflow resolved while tracing + * is enabled. Due to erratum APL12, however, the overflow may have resolved + * while tracing is disabled and still generate a FUP. + * + * We scan ahead for an indication whether tracing is actually disabled. If we + * find one, the erratum applies and we proceed from after the FUP with tracing + * disabled. + * + * This will drop any CBR events. We will update @decoder's timing state on + * CBR but drop the event. + * + * Returns zero if the erratum was handled and an overflow event was generated. + * Returns a positive value if the overflow is not yet handled. + * Returns a negative pt_error_code otherwise. + */ +static int pt_evt_handle_apl12(struct pt_event_decoder *decoder, + uint64_t offset) +{ + struct pt_packet_decoder pacdec; + + if (!decoder) + return -pte_internal; + + pacdec = decoder->pacdec; + pacdec.pos += offset; + if (pt_pkt_end(&pacdec) < pt_pkt_pos(&pacdec)) + return -pte_internal; + + for (;;) { + struct pt_packet packet; + int errcode; + + errcode = pt_pkt_next(&pacdec, &packet, sizeof(packet)); + if (errcode < 0) { + /* Running out of packets is not an error. */ + if (errcode == -pte_eos) + errcode = 1; + + return errcode; + } + + switch (packet.type) { + case ppt_tnt_8: + case ppt_tnt_64: + case ppt_tip: + case ppt_tip_pgd: + /* Those packets are only generated when tracing is + * enabled. We're done. + */ + return 1; + + case ppt_psb: + /* We reached a synchronization point. Tracing is + * enabled if and only if the PSB+ contains a FUP. + */ + errcode = pt_evt_find_header_fup(&packet, &pacdec); + if (errcode != 0) { + /* If we ran out of packets, we can't tell. */ + if (errcode == -pte_eos) + errcode = 1; + + return errcode; + } + + return pt_evt_recover_ovf_at_offset(decoder, offset); + + case ppt_stop: + /* Tracing is disabled before a stop. */ + + return pt_evt_recover_ovf_at_offset(decoder, offset); + + case ppt_tip_pge: + /* Tracing must have been disabled. */ + + return pt_evt_recover_ovf_at_offset(decoder, offset); + + case ppt_psbend: + /* Leave it to normal decode to diagnose. */ + return 1; + + case ppt_ovf: + /* It doesn't matter - we run into the next overflow. */ + return 1; + + case ppt_pad: + case ppt_fup: + case ppt_tsc: + case ppt_cbr: + case ppt_tma: + case ppt_mtc: + case ppt_cyc: + case ppt_exstop: + case ppt_mwait: + case ppt_pwre: + case ppt_pwrx: + case ppt_ptw: + case ppt_mnt: + case ppt_pip: + case ppt_vmcs: + case ppt_mode: + case ppt_cfe: + case ppt_evd: + /* Skip those packets. */ + break; + + case ppt_unknown: + case ppt_invalid: + /* We can't skip those packets. */ + return 1; + } + } +} + +static int pt_evt_decode_ovf(struct pt_event_decoder *decoder) +{ + const struct pt_config *config; + struct pt_time_cal tcal; + struct pt_time time; + struct pt_event *ev; + int errcode, offset; + + if (!decoder) + return -pte_internal; + + /* An OVF ends a PSB just like PSBEND. + * + * Publish any pending PSB+ events before we start handling the actual + * overflow event. + */ + errcode = pt_evt_decode_psbend(decoder); + if (errcode <= 0) + return errcode; + + config = pt_evt_config(decoder); + if (!config) + return -pte_internal; + + /* Reset the decoder state but preserve timing. */ + time = decoder->time; + tcal = decoder->tcal; + + errcode = pt_evt_reset(decoder); + if (errcode < 0) + return errcode; + + decoder->time = time; + if (decoder->flags.variant.event.keep_tcal_on_ovf) { + errcode = pt_tcal_update_ovf(&tcal, config); + if (errcode < 0) + return errcode; + + decoder->tcal = tcal; + } + + /* OVF binds to either FUP or TIP.PGE. + * + * If the overflow resolves while PacketEn=1 it binds to FUP. We can + * see timing packets between OVF and FUP but that's it. + * + * If the overflow resolves while PacketEn=0 it binds to TIP.PGE. We + * can see packets between OVF and TIP.PGE that do not depend on + * PacketEn. + * + * We don't need to decode everything until TIP.PGE, however. As soon + * as we see a non-timing non-FUP packet, we know that tracing has been + * disabled before the overflow resolves. We generate a standalone + * overflow event and continue decoding normally. + * + * We search for a FUP and, if we find one, return its offset from the + * current decoder position. An offset of zero means that we did not + * find a FUP and negative values indicate errors. + */ + offset = pt_evt_find_ovf_fup(&decoder->pacdec); + if (offset <= 0) { + /* Check for erratum SKD010. + * + * The FUP may have been dropped. If we can figure out that + * tracing is enabled and hence the FUP is missing, we resume + * at a later packet and a different IP. + */ + if (config->errata.skd010) { + errcode = pt_evt_handle_skd010(decoder); + if (errcode <= 0) + return errcode; + } + + /* Check for erratum APL11. + * + * We may have gotten an extra TIP.PGD, which should be + * diagnosed by our search for a subsequent FUP. + */ + if (config->errata.apl11 && + (offset == -pte_bad_context)) { + errcode = pt_evt_handle_apl11(decoder); + if (errcode <= 0) + return errcode; + } + + /* Report the original error from searching for the FUP packet + * if we were not able to fix the trace. + * + * We treat an overflow at the end of the trace as standalone. + */ + if ((offset < 0) && (offset != -pte_eos)) + return offset; + + decoder->event = ev = pt_evq_standalone(&decoder->evq); + if (!ev) + return -pte_internal; + + ev->type = ptev_overflow; + ev->ip_suppressed = 1; + + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + return errcode; + + return pt_evt_fetch_packet(decoder); + } + + /* Check for erratum APL12. + * + * We may get an extra FUP even though the overflow resolved with + * tracing disabled. + */ + if (config->errata.apl12) { + errcode = pt_evt_handle_apl12(decoder, (uint64_t) offset); + if (errcode <= 0) + return errcode; + } + + ev = pt_evq_enqueue(&decoder->evq, evb_fup_bound); + if (!ev) + return -pte_nomem; + + ev->type = ptev_overflow; + + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + return errcode; + + return 1; +} + +static int pt_evt_decode_tip_event(struct pt_event_decoder *decoder) +{ + struct pt_event *ev, *async; + int errcode; + + if (!decoder) + return -pte_internal; + + decoder->bound = 1; + + async = pt_evq_find(&decoder->evq, evb_tip, ptev_async_branch); + if (async) { + ev = pt_evq_dequeue(&decoder->evq, evb_tip); + if (!ev) + return -pte_internal; + + /* Swap the asynchronous branch event with the first event. */ + if (ev != async) { + struct pt_event tmp; + + tmp = *async; + *async = *ev; + *ev = tmp; + } + + if (ev->type != ptev_async_branch) + return -pte_internal; + + decoder->event = ev; + + errcode = pt_evt_event_ip(&ev->variant.async_branch.to, ev, + &decoder->ip); + if (errcode < 0) + return errcode; + + return pt_evt_event_time(ev, &decoder->time); + } + + decoder->event = ev = pt_evq_standalone(&decoder->evq); + if (!ev) + return -pte_internal; + + ev->type = ptev_tip; + + errcode = pt_evt_event_ip(&ev->variant.tip.ip, ev, &decoder->ip); + if (errcode < 0) + return errcode; + + return pt_evt_event_time(ev, &decoder->time); +} + +static int pt_evt_decode_tip(struct pt_event_decoder *decoder, + const struct pt_packet_ip *packet) +{ + struct pt_event *ev; + int errcode; + + if (!decoder || !packet) + return -pte_internal; + + if (!decoder->enabled) + return -pte_bad_context; + + errcode = pt_last_ip_update_ip(&decoder->ip, packet, + pt_evt_config(decoder)); + if (errcode < 0) + return errcode; + + /* Send the async or sync branch event first. + * + * That's a bit more complicated for us but it will help our users as + * non-async branch events bind to the branch IP, not to the + * instruction IP. + */ + if (!decoder->bound) + return pt_evt_decode_tip_event(decoder); + + ev = pt_evq_dequeue(&decoder->evq, evb_tip); + if (!ev) + return 1; + + decoder->event = ev; + + switch (ev->type) { + case ptev_async_branch: + return -pte_internal; + + case ptev_exec_mode: + errcode = pt_evt_event_ip(&ev->variant.exec_mode.ip, ev, + &decoder->ip); + break; + + case ptev_async_paging: + errcode = pt_evt_event_ip(&ev->variant.async_paging.ip, ev, + &decoder->ip); + break; + + case ptev_async_vmcs: + errcode = pt_evt_event_ip(&ev->variant.async_vmcs.ip, ev, + &decoder->ip); + break; + + case ptev_iflags: + errcode = pt_evt_event_ip(&ev->variant.iflags.ip, ev, + &decoder->ip); + break; + + case ptev_ignore: + decoder->event = NULL; + + return pt_evt_decode_tip(decoder, packet); + + default: + errcode = -pte_bad_context; + break; + } + + if (errcode < 0) + return errcode; + + return pt_evt_event_time(ev, &decoder->time); +} + +static int pt_evt_decode_tip_pge(struct pt_event_decoder *decoder, + const struct pt_packet_ip *packet) +{ + struct pt_event *ev; + int errcode; + + if (!decoder || !packet) + return -pte_internal; + + errcode = pt_last_ip_update_ip(&decoder->ip, packet, + pt_evt_config(decoder)); + if (errcode < 0) + return errcode; + + /* We send the enable event first. This is more convenient for our + * users and does not require them to either store or blindly apply + * other events that might be pending. + * + * We use the bound decoder flag to indicate this. + */ + if (!decoder->bound) { + decoder->event = ev = pt_evq_standalone(&decoder->evq); + if (!ev) + return -pte_internal; + + ev->type = ptev_enabled; + + errcode = pt_evt_event_ip(&ev->variant.enabled.ip, ev, + &decoder->ip); + if (errcode < 0) + return errcode; + + decoder->enabled = 1; + decoder->bound = 1; + + return pt_evt_event_time(ev, &decoder->time); + } + + ev = pt_evq_dequeue(&decoder->evq, evb_tip); + if (!ev) + return 1; + + decoder->event = ev; + + switch (ev->type) { + case ptev_exec_mode: + errcode = pt_evt_event_ip(&ev->variant.exec_mode.ip, ev, + &decoder->ip); + break; + + case ptev_iflags: + errcode = pt_evt_event_ip(&ev->variant.iflags.ip, ev, + &decoder->ip); + break; + + case ptev_ignore: + decoder->event = NULL; + + return pt_evt_decode_tip_pge(decoder, packet); + + default: + errcode = -pte_bad_context; + break; + } + + if (errcode < 0) + return errcode; + + return pt_evt_event_time(ev, &decoder->time); +} + +static int pt_evt_decode_tip_pgd(struct pt_event_decoder *decoder, + const struct pt_packet_ip *packet) +{ + struct pt_event *ev; + int errcode; + + if (!decoder || !packet) + return -pte_internal; + + errcode = pt_last_ip_update_ip(&decoder->ip, packet, + pt_evt_config(decoder)); + if (errcode < 0) + return errcode; + + ev = pt_evq_dequeue(&decoder->evq, evb_tip); + if (!ev) { + if (decoder->bound) + return 1; + + decoder->event = ev = pt_evq_standalone(&decoder->evq); + if (!ev) + return -pte_internal; + + ev->type = ptev_disabled; + + errcode = pt_evt_event_ip(&ev->variant.disabled.ip, ev, + &decoder->ip); + if (errcode < 0) + return errcode; + + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + return errcode; + + decoder->enabled = 0; + + return pt_evt_fetch_packet(decoder); + } + + decoder->event = ev; + + switch (ev->type) { + case ptev_async_branch: { + uint64_t at; + + /* Turn the async branch into an async disable. */ + at = ev->variant.async_branch.from; + + ev->type = ptev_async_disabled; + ev->variant.async_disabled.at = at; + + errcode = pt_evt_event_ip(&ev->variant.async_disabled.ip, ev, + &decoder->ip); + + decoder->enabled = 0; + decoder->bound = 1; + + break; + } + + case ptev_async_paging: + case ptev_async_vmcs: + /* The async paging and vmcs events are ordered after the async + * branch event that we turned into an async disable above. + */ + if (!decoder->bound) + return -pte_internal; + + fallthrough; + case ptev_exec_mode: + /* The MODE.EXEC might come with a standalone TIP.PGD or with a + * FUP + TIP.PGD pair. In both cases, we won't really reach + * the IP in the TIP.PGD's payload since tracing is disabled as + * part of the branch. In the synchronous case, we won't get a + * TIP event that would allow us to reach the MODE.EXEC's event + * location. + * + * It is not quite clear what IP to give those events. + * + * If we give them the async disable's source IP, we'd make an + * error if the IP is updated when applying the async disable + * event. + * + * If we give them the async disable's destination IP, we'd make + * an error if the IP is not updated when applying the async + * disable event. That's what our decoders do since tracing is + * likely to resume from there. + * + * In all cases, tracing will be disabled when those events are + * applied, so we may as well suppress the IP. + */ + ev->ip_suppressed = 1; + break; + + default: + errcode = -pte_bad_context; + break; + } + + if (errcode < 0) + return errcode; + + return pt_evt_event_time(ev, &decoder->time); +} + +static int pt_evt_decode_tnt(struct pt_event_decoder *decoder, + const struct pt_packet_tnt *packet) +{ + struct pt_event *ev; + int errcode; + + if (!decoder || !packet) + return -pte_internal; + + if (!decoder->enabled) + return -pte_bad_context; + + decoder->event = ev = pt_evq_standalone(&decoder->evq); + if (!ev) + return -pte_internal; + + ev->type = ptev_tnt; + ev->variant.tnt.bits = packet->payload; + ev->variant.tnt.size = packet->bit_size; + + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + return errcode; + + return pt_evt_fetch_packet(decoder); +} + +static int pt_evt_decode_cfe(struct pt_event_decoder *decoder, + const struct pt_packet_cfe *packet) +{ + struct pt_event *ev; + int errcode; + + if (!decoder || !packet) + return -pte_internal; + + /* Let's see if we already got an EVD and enqueued an expected CFE. */ + ev = pt_evq_dequeue(&decoder->evq, evb_cfe); + + switch (packet->type) { + case pt_cfe_intr: + if (!ev) { + ev = pt_evq_standalone(&decoder->evq); + if (!ev) + return -pte_internal; + + ev->type = ptev_interrupt; + } + + if (ev->type != ptev_interrupt) + return -pte_bad_context; + + ev->variant.interrupt.vector = packet->vector; + + if (packet->ip) { + ev = pt_evq_requeue(&decoder->evq, ev, evb_fup_bound); + if (!ev) + return -pte_nomem; + + return 1; + } + + if (decoder->enabled) { + ev = pt_evq_requeue(&decoder->evq, ev, evb_fup); + if (!ev) + return -pte_nomem; + + return 1; + } + + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + return errcode; + + ev->ip_suppressed = 1; + + decoder->event = ev; + return pt_evt_fetch_packet(decoder); + + case pt_cfe_iret: + if (ev) + return -pte_bad_context; + + if (packet->ip) { + ev = pt_evq_enqueue(&decoder->evq, evb_fup_bound); + if (!ev) + return -pte_nomem; + + ev->type = ptev_iret; + return 1; + } + + ev = pt_evq_standalone(&decoder->evq); + if (!ev) + return -pte_internal; + + ev->type = ptev_iret; + ev->ip_suppressed = 1; + + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + return errcode; + + decoder->event = ev; + return pt_evt_fetch_packet(decoder); + + case pt_cfe_smi: + if (ev) + return -pte_bad_context; + + if (packet->ip) { + ev = pt_evq_enqueue(&decoder->evq, evb_fup_bound); + if (!ev) + return -pte_nomem; + + ev->type = ptev_smi; + return 1; + } + + if (decoder->enabled) { + ev = pt_evq_enqueue(&decoder->evq, evb_fup); + if (!ev) + return -pte_nomem; + + ev->type = ptev_smi; + return 1; + } + + ev = pt_evq_standalone(&decoder->evq); + if (!ev) + return -pte_internal; + + ev->type = ptev_smi; + ev->ip_suppressed = 1; + + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + return errcode; + + decoder->event = ev; + return pt_evt_fetch_packet(decoder); + + case pt_cfe_rsm: + if (ev) + return -pte_bad_context; + + if (packet->ip) + return -pte_bad_packet; + + if (decoder->enabled) { + ev = pt_evq_enqueue(&decoder->evq, evb_fup); + if (!ev) + return -pte_nomem; + + ev->ip_suppressed = 1; + ev->type = ptev_rsm; + return 1; + } + + ev = pt_evq_standalone(&decoder->evq); + if (!ev) + return -pte_internal; + + ev->ip_suppressed = 1; + ev->type = ptev_rsm; + + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + return errcode; + + decoder->event = ev; + return pt_evt_fetch_packet(decoder); + + case pt_cfe_sipi: + if (ev) + return -pte_bad_context; + + if (packet->ip) + return -pte_bad_packet; + + if (decoder->enabled) { + ev = pt_evq_enqueue(&decoder->evq, evb_fup); + if (!ev) + return -pte_nomem; + + ev->ip_suppressed = 1; + ev->type = ptev_sipi; + ev->variant.sipi.vector = packet->vector; + return 1; + } + + ev = pt_evq_standalone(&decoder->evq); + if (!ev) + return -pte_internal; + + ev->ip_suppressed = 1; + ev->type = ptev_sipi; + ev->variant.sipi.vector = packet->vector; + + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + return errcode; + + decoder->event = ev; + return pt_evt_fetch_packet(decoder); + + case pt_cfe_init: + if (ev) + return -pte_bad_context; + + if (packet->ip) { + ev = pt_evq_enqueue(&decoder->evq, evb_fup_bound); + if (!ev) + return -pte_nomem; + + ev->type = ptev_init; + return 1; + } + + if (decoder->enabled) { + ev = pt_evq_enqueue(&decoder->evq, evb_fup); + if (!ev) + return -pte_nomem; + + ev->type = ptev_init; + return 1; + } + + ev = pt_evq_standalone(&decoder->evq); + if (!ev) + return -pte_internal; + + ev->type = ptev_init; + ev->ip_suppressed = 1; + + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + return errcode; + + decoder->event = ev; + return pt_evt_fetch_packet(decoder); + + case pt_cfe_vmentry: + if (ev) + return -pte_bad_context; + + if (packet->ip) { + ev = pt_evq_enqueue(&decoder->evq, evb_fup_bound); + if (!ev) + return -pte_nomem; + + ev->type = ptev_vmentry; + return 1; + } + + ev = pt_evq_standalone(&decoder->evq); + if (!ev) + return -pte_internal; + + ev->type = ptev_vmentry; + ev->ip_suppressed = 1; + + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + return errcode; + + decoder->event = ev; + return pt_evt_fetch_packet(decoder); + + case pt_cfe_vmexit: + case pt_cfe_vmexit_intr: + if (!ev) { + ev = pt_evq_standalone(&decoder->evq); + if (!ev) + return -pte_internal; + + ev->type = ptev_vmexit; + } + + if (ev->type != ptev_vmexit) + return -pte_bad_context; + + if (packet->type == pt_cfe_vmexit_intr) { + ev->variant.vmexit.has_vector = 1; + ev->variant.vmexit.vector = packet->vector; + } + + if (packet->ip) { + ev = pt_evq_requeue(&decoder->evq, ev, evb_fup_bound); + if (!ev) + return -pte_nomem; + + return 1; + } + + if (decoder->enabled) { + ev = pt_evq_requeue(&decoder->evq, ev, evb_fup); + if (!ev) + return -pte_nomem; + + return 1; + } + + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + return errcode; + + ev->ip_suppressed = 1; + + decoder->event = ev; + return pt_evt_fetch_packet(decoder); + + case pt_cfe_shutdown: + if (ev) + return -pte_bad_context; + + if (packet->ip) { + ev = pt_evq_enqueue(&decoder->evq, evb_fup_bound); + if (!ev) + return -pte_nomem; + + ev->type = ptev_shutdown; + return 1; + } + + ev = pt_evq_standalone(&decoder->evq); + if (!ev) + return -pte_internal; + + ev->type = ptev_shutdown; + ev->ip_suppressed = 1; + + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + return errcode; + + decoder->event = ev; + return pt_evt_fetch_packet(decoder); + + case pt_cfe_uintr: + if (ev) + return -pte_bad_context; + + if (packet->ip) { + ev = pt_evq_enqueue(&decoder->evq, evb_fup_bound); + if (!ev) + return -pte_nomem; + + ev->type = ptev_uintr; + ev->variant.uintr.vector = packet->vector; + return 1; + } + + if (decoder->enabled) { + ev = pt_evq_enqueue(&decoder->evq, evb_fup); + if (!ev) + return -pte_nomem; + + ev->type = ptev_uintr; + ev->variant.uintr.vector = packet->vector; + return 1; + } + + ev = pt_evq_standalone(&decoder->evq); + if (!ev) + return -pte_internal; + + ev->type = ptev_uintr; + ev->variant.uintr.vector = packet->vector; + ev->ip_suppressed = 1; + + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + return errcode; + + decoder->event = ev; + return pt_evt_fetch_packet(decoder); + + case pt_cfe_uiret: + if (ev) + return -pte_bad_context; + + if (packet->ip) { + ev = pt_evq_enqueue(&decoder->evq, evb_fup_bound); + if (!ev) + return -pte_nomem; + + ev->type = ptev_uiret; + return 1; + } + + ev = pt_evq_standalone(&decoder->evq); + if (!ev) + return -pte_internal; + + ev->type = ptev_uiret; + ev->ip_suppressed = 1; + + errcode = pt_evt_event_time(ev, &decoder->time); + if (errcode < 0) + return errcode; + + decoder->event = ev; + return pt_evt_fetch_packet(decoder); + } + + /* Decoding EVD is supposed to only enqueue supported CFE types. */ + if (ev) + return -pte_internal; + + /* Ignore unknown CFE types. + * + * They provide additional information but they are not essential for + * decoding the trace. It is better to continue without that + * information than to fail. + * + * Since CFE may consume a subsequent FUP, we need to ignore that, too. + */ + if (packet->ip) { + ev = pt_evq_enqueue(&decoder->evq, evb_fup_bound); + if (!ev) + return -pte_nomem; + + ev->type = ptev_ignore; + } + + return 1; +} + +static int pt_evt_decode_evd(struct pt_event_decoder *decoder, + const struct pt_packet_evd *packet) +{ + struct pt_event *ev; + + if (!decoder || !packet) + return -pte_internal; + + /* Let's see if we already got an EVD and enqueued an expected CFE. */ + ev = pt_evq_peek(&decoder->evq, evb_cfe); + + switch (packet->type) { + case pt_evd_cr2: + if (ev) + return -pte_bad_context; + + ev = pt_evq_enqueue(&decoder->evq, evb_cfe); + if (!ev) + return -pte_nomem; + + ev->type = ptev_interrupt; + ev->variant.interrupt.has_cr2 = 1; + ev->variant.interrupt.cr2 = packet->payload; + + return 1; + + case pt_evd_vmxq: + if (!ev) { + ev = pt_evq_enqueue(&decoder->evq, evb_cfe); + if (!ev) + return -pte_nomem; + + ev->type = ptev_vmexit; + } + + if (ev->type != ptev_vmexit) + return -pte_bad_context; + + if (ev->variant.vmexit.has_vmxq) + return -pte_bad_context; + + ev->variant.vmexit.has_vmxq = 1; + ev->variant.vmexit.vmxq = packet->payload; + + return 1; + + case pt_evd_vmxr: + if (!ev) { + ev = pt_evq_enqueue(&decoder->evq, evb_cfe); + if (!ev) + return -pte_nomem; + + ev->type = ptev_vmexit; + } + + if (ev->type != ptev_vmexit) + return -pte_bad_context; + + if (ev->variant.vmexit.has_vmxr) + return -pte_bad_context; + + ev->variant.vmexit.has_vmxr = 1; + ev->variant.vmexit.vmxr = packet->payload; + + return 1; + } + + /* Ignore unknown EVD types. + * + * They provide additional information but they are not essential for + * decoding the trace. It is better to continue without that + * information than to fail. + */ + return 1; +} + +static int pt_evt_decode_unknown(struct pt_event_decoder *decoder, + const struct pt_packet_unknown *packet) +{ + (void) decoder; + (void) packet; + + return 1; +} + +static int pt_evt_decode_packet(struct pt_event_decoder *decoder) +{ + const struct pt_packet *packet; + int errcode; + + if (!decoder) + return -pte_internal; + + packet = &decoder->packet; + switch (packet->type) { + case ppt_tnt_8: + case ppt_tnt_64: + return pt_evt_decode_tnt(decoder, &packet->payload.tnt); + + case ppt_cyc: + return pt_evt_decode_cyc(decoder, &packet->payload.cyc); + + case ppt_pad: + return 1; + + case ppt_fup: + return pt_evt_decode_fup(decoder, &packet->payload.ip); + + case ppt_tip: + return pt_evt_decode_tip(decoder, &packet->payload.ip); + + case ppt_mtc: + return pt_evt_decode_mtc(decoder, &packet->payload.mtc); + + case ppt_tsc: + return pt_evt_decode_tsc(decoder, &packet->payload.tsc); + + case ppt_cbr: + return pt_evt_decode_cbr(decoder, &packet->payload.cbr); + + case ppt_tma: + return pt_evt_decode_tma(decoder, &packet->payload.tma); + + case ppt_mode: + return pt_evt_decode_mode(decoder, &packet->payload.mode); + + case ppt_pip: + return pt_evt_decode_pip(decoder, &packet->payload.pip); + + case ppt_ptw: + return pt_evt_decode_ptw(decoder, &packet->payload.ptw); + + case ppt_psb: + errcode = pt_evt_decode_psb(decoder); + if (errcode <= 0) + return errcode; + + return pt_evt_decode_packet(decoder); + + case ppt_psbend: + return pt_evt_decode_psbend(decoder); + + case ppt_tip_pge: + return pt_evt_decode_tip_pge(decoder, &packet->payload.ip); + + case ppt_tip_pgd: + return pt_evt_decode_tip_pgd(decoder, &packet->payload.ip); + + case ppt_exstop: + return pt_evt_decode_exstop(decoder, &packet->payload.exstop); + + case ppt_pwre: + return pt_evt_decode_pwre(decoder, &packet->payload.pwre); + + case ppt_pwrx: + return pt_evt_decode_pwrx(decoder, &packet->payload.pwrx); + + case ppt_mwait: + return pt_evt_decode_mwait(decoder, &packet->payload.mwait); + + case ppt_vmcs: + return pt_evt_decode_vmcs(decoder, &packet->payload.vmcs); + + case ppt_ovf: + return pt_evt_decode_ovf(decoder); + + case ppt_stop: + return pt_evt_decode_stop(decoder); + + case ppt_mnt: + return pt_evt_decode_mnt(decoder, &packet->payload.mnt); + + case ppt_cfe: + return pt_evt_decode_cfe(decoder, &packet->payload.cfe); + + case ppt_evd: + return pt_evt_decode_evd(decoder, &packet->payload.evd); + + case ppt_invalid: + if (decoder->status < 0) + return decoder->status; + + return 1; + + case ppt_unknown: + return pt_evt_decode_unknown(decoder, + &packet->payload.unknown); + } + + return -pte_bad_opc; +} + +/* Fetch the next event. + * + * Calls packet decode functions until one signals that it reported an event by + * returning zero. + * + * Packet decode functions return: + * + * zero.......an event was created + * negative...an error occurred during packet processing + * positive...further packets are needed + * + * When indicating that an event was created, packet decode functions must + * fetch the next packet if they are done processing the current packet, + * e.g. by returning via: + * + * return pt_evt_fetch_packet(decoder); + * + * If they are not done processing the current packet, e.g. when more events + * have been enqueued for this packet, they must return via: + * + * return 0; + * + * Returns zero on success, a negative pt_error_code otherwise. + */ +static int pt_evt_fetch_event(struct pt_event_decoder *decoder) +{ + int errcode; + + if (!decoder) + return -pte_internal; + + for (;;) { + errcode = pt_evt_decode_packet(decoder); + if (errcode <= 0) + break; + + if (decoder->event) { + errcode = -pte_internal; + break; + } + + /* The packet decoder asked for a new packet without delivering + * an event. That new packet isn't bound. + * + * All flows involving bound packets must take this path since + * returning with zero, e.g. via pt_evt_fetch_packet(), without + * an event will be diagnosed by our caller. + */ + decoder->bound = 0; + + errcode = pt_evt_fetch_packet(decoder); + if (errcode < 0) + break; + } + + return errcode; +} + +static inline int pt_evt_to_user(struct pt_event *uev, size_t size, + const struct pt_event *ev) +{ + if (!uev || !ev) + return -pte_internal; + + /* Zero out any unknown bytes. */ + if (sizeof(*ev) < size) { + memset(((uint8_t *) uev) + sizeof(*ev), 0, size - sizeof(*ev)); + + size = sizeof(*ev); + } + + memcpy(uev, ev, size); + + return 0; +} + +int pt_evt_next(struct pt_event_decoder *decoder, struct pt_event *uev, + size_t size) +{ + struct pt_event *ev; + int errcode; + + if (!decoder || !uev) + return -pte_invalid; + + errcode = pt_evt_fetch_event(decoder); + if (errcode < 0) + return errcode; + + ev = decoder->event; + decoder->event = NULL; + + return pt_evt_to_user(uev, size, ev); +}
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/src/pt_event_queue.c -> _service:tar_scm:v2.1.tar.gz/libipt/src/pt_event_queue.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -39,6 +40,14 @@ return idx; } +static inline uint8_t pt_evq_dec(uint8_t idx) +{ + idx -= 1; + idx %= evq_max; + + return idx; +} + static struct pt_event *pt_event_init(struct pt_event *event) { if (event) @@ -63,19 +72,16 @@ return pt_event_init(&evq->standalone); } -struct pt_event *pt_evq_enqueue(struct pt_event_queue *evq, - enum pt_event_binding evb) +struct pt_event *pt_evq_enqueue(struct pt_event_queue *evq, uint32_t evb) { + struct pt_evq_entry *pentry; uint8_t begin, end, gap, idx; if (!evq) return NULL; - if (evb_max <= evb) - return NULL; - - begin = evq->beginevb; - idx = evq->endevb; + begin = evq->begin; + idx = evq->end; if (evq_max <= begin) return NULL; @@ -90,24 +96,23 @@ if (begin == gap) return NULL; - evq->endevb = end; + evq->end = end; - return pt_event_init(&evq->queueevbidx); + pentry = &evq->queueidx; + pentry->binding = evb; + return pt_event_init(&pentry->event); } -struct pt_event *pt_evq_dequeue(struct pt_event_queue *evq, - enum pt_event_binding evb) +struct pt_event *pt_evq_dequeue(struct pt_event_queue *evq, uint32_t evb) { - uint8_t begin, end; + struct pt_evq_entry entry, *pentry; + uint8_t begin, end, idx; if (!evq) return NULL; - if (evb_max <= evb) - return NULL; - - begin = evq->beginevb; - end = evq->endevb; + begin = evq->begin; + end = evq->end; if (evq_max <= begin) return NULL; @@ -118,37 +123,92 @@ if (begin == end) return NULL; - evq->beginevb = pt_evq_inc(begin); + /* Check the common and fast case first. */ + pentry = &evq->queuebegin; + if ((pentry->binding & evb) != 0) { + evq->begin = pt_evq_inc(begin); + return &pentry->event; + } + + /* Returning elements from the middle of the queue requires copying + * elements to not leave a hole. + * + * First, find the first element matching @evb. Once we found it, move + * it to the beginning of the queue by moving all preceding elements + * down by one position. + */ + idx = begin; + for (;;) { + idx = pt_evq_inc(idx); + if (idx == end) + return NULL; + + pentry = &evq->queueidx; + if ((pentry->binding & evb) != 0) + break; + } + + /* Take a temporary copy of the element we want to return and move down + * preceding elements one-by-one. + */ + entry = *pentry; + for (;;) { + uint8_t prev; - return &evq->queueevbbegin; + prev = pt_evq_dec(idx); + evq->queueidx = evq->queueprev; + + if (prev == begin) + break; + + idx = prev; + } + + /* We already copied the start element one down. Re-use its slot to + * hold the element we want to return. + */ + evq->begin = idx; + pentry = &evq->queuebegin; + *pentry = entry; + return &pentry->event; } -int pt_evq_clear(struct pt_event_queue *evq, enum pt_event_binding evb) +struct pt_event *pt_evq_requeue(struct pt_event_queue *evq, + struct pt_event *ev, uint32_t evb) { - if (!evq) - return -pte_internal; + struct pt_event *rev; + + if (!ev) + return NULL; + + rev = pt_evq_enqueue(evq, evb); + if (!rev) + return NULL; - if (evb_max <= evb) + *rev = *ev; + return rev; +} + +int pt_evq_clear(struct pt_event_queue *evq) +{ + if (!evq) return -pte_internal; - evq->beginevb = 0; - evq->endevb = 0; + evq->begin = 0; + evq->end = 0; return 0; } -int pt_evq_empty(const struct pt_event_queue *evq, enum pt_event_binding evb) +int pt_evq_empty(const struct pt_event_queue *evq, uint32_t evb) { uint8_t begin, end; if (!evq) return -pte_internal; - if (evb_max <= evb) - return -pte_internal; - - begin = evq->beginevb; - end = evq->endevb; + begin = evq->begin; + end = evq->end; if (evq_max <= begin) return -pte_internal; @@ -156,10 +216,15 @@ if (evq_max <= end) return -pte_internal; - return begin == end; + for (; begin != end; begin = pt_evq_inc(begin)) { + if ((evq->queuebegin.binding & evb) != 0) + return 0; + } + + return 1; } -int pt_evq_pending(const struct pt_event_queue *evq, enum pt_event_binding evb) +int pt_evq_pending(const struct pt_event_queue *evq, uint32_t evb) { int errcode; @@ -170,8 +235,7 @@ return !errcode; } -struct pt_event *pt_evq_find(struct pt_event_queue *evq, - enum pt_event_binding evb, +struct pt_event *pt_evq_find(struct pt_event_queue *evq, uint32_t evb, enum pt_event_type evt) { uint8_t begin, end; @@ -179,11 +243,8 @@ if (!evq) return NULL; - if (evb_max <= evb) - return NULL; - - begin = evq->beginevb; - end = evq->endevb; + begin = evq->begin; + end = evq->end; if (evq_max <= begin) return NULL; @@ -192,12 +253,46 @@ return NULL; for (; begin != end; begin = pt_evq_inc(begin)) { + struct pt_evq_entry *pentry; struct pt_event *ev; - ev = &evq->queueevbbegin; + pentry = &evq->queuebegin; + if ((pentry->binding & evb) == 0) + continue; + + ev = &pentry->event; if (ev->type == evt) return ev; } return NULL; } + +struct pt_event *pt_evq_peek(struct pt_event_queue *evq, uint32_t evb) +{ + uint8_t begin, end; + + if (!evq) + return NULL; + + begin = evq->begin; + end = evq->end; + + if (evq_max <= begin) + return NULL; + + if (evq_max <= end) + return NULL; + + for (; begin != end; begin = pt_evq_inc(begin)) { + struct pt_evq_entry *pentry; + + pentry = &evq->queuebegin; + if ((pentry->binding & evb) == 0) + continue; + + return &pentry->event; + } + + return NULL; +}
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/src/pt_ild.c -> _service:tar_scm:v2.1.tar.gz/libipt/src/pt_ild.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -1162,7 +1163,7 @@ switch (ild->nominal_opcode) { case 0x9A: - if (map == PTI_MAP_0) { + if ((map == PTI_MAP_0) && !mode_64b(ild)) { insn->iclass = ptic_far_call; iext->iclass = PTI_INST_CALL_9A; } @@ -1214,7 +1215,7 @@ return 0; case 0xCE: - if (map == PTI_MAP_0) { + if ((map == PTI_MAP_0) && !mode_64b(ild)) { insn->iclass = ptic_far_call; iext->iclass = PTI_INST_INTO; } @@ -1246,7 +1247,7 @@ return 0; case 0xEA: - if (map == PTI_MAP_0) { + if ((map == PTI_MAP_0) && !mode_64b(ild)) { /* Far jumps are treated as indirect jumps. */ insn->iclass = ptic_far_jump; iext->iclass = PTI_INST_JMP_EA;
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/src/pt_image.c -> _service:tar_scm:v2.1.tar.gz/libipt/src/pt_image.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -43,12 +44,16 @@ if (!str) return NULL; - len = strlen(str); + /* Silently truncate the name if it gets too big. */ + len = strnlen(str, 4096ul); + dup = malloc(len + 1); if (!dup) return NULL; - return strcpy(dup, str); + duplen = 0; + + return memcpy(dup, str, len); } static struct pt_section_list *pt_mk_section_list(struct pt_section *section, @@ -315,9 +320,10 @@ if (errcode < 0) return errcode; - section = pt_mk_section(filename, offset, size); - if (!section) - return -pte_invalid; + section = NULL; + errcode = pt_mk_section(§ion, filename, offset, size); + if (errcode < 0) + return errcode; errcode = pt_image_add(image, section, &asid, vaddr, 0); if (errcode < 0) {
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/src/pt_image_section_cache.c -> _service:tar_scm:v2.1.tar.gz/libipt/src/pt_image_section_cache.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2016-2022, Intel Corporation + * Copyright (c) 2016-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -42,12 +43,16 @@ if (!str) return NULL; - len = strlen(str); + /* Silently truncate the name if it gets too big. */ + len = strnlen(str, 4096ul); + dup = malloc(len + 1); if (!dup) return NULL; - return strcpy(dup, str); + duplen = 0; + + return memcpy(dup, str, len); } int pt_iscache_init(struct pt_image_section_cache *iscache, const char *name) @@ -975,9 +980,10 @@ if (errcode < 0) return errcode; - section = pt_mk_section(filename, offset, size); - if (!section) - return -pte_invalid; + section = NULL; + errcode = pt_mk_section(§ion, filename, offset, size); + if (errcode < 0) + return errcode; } /* We unlocked @iscache and hold a reference to @section. */
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/src/pt_insn.c -> _service:tar_scm:v2.1.tar.gz/libipt/src/pt_insn.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2016-2022, Intel Corporation + * Copyright (c) 2016-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -95,6 +96,7 @@ case ptic_far_call: case ptic_far_return: case ptic_far_jump: + case ptic_indirect: return 1; } } @@ -169,6 +171,60 @@ } } +int pt_insn_is_iret(const struct pt_insn *insn, + const struct pt_insn_ext *iext) +{ + (void) insn; + + if (!iext) + return 0; + + switch (iext->iclass) { + default: + return 0; + + case PTI_INST_IRET: + case PTI_INST_SYSRET: + case PTI_INST_SYSEXIT: + return 1; + } +} + +int pt_insn_is_vmentry(const struct pt_insn *insn, + const struct pt_insn_ext *iext) +{ + (void) insn; + + if (!iext) + return 0; + + switch (iext->iclass) { + default: + return 0; + + case PTI_INST_VMLAUNCH: + case PTI_INST_VMRESUME: + return 1; + } +} + +int pt_insn_is_uiret(const struct pt_insn *insn, + const struct pt_insn_ext *iext) +{ + (void) insn; + + if (!iext) + return 0; + + switch (iext->iclass) { + default: + return 0; + + case PTI_INST_UIRET: + return 1; + } +} + int pt_insn_next_ip(uint64_t *pip, const struct pt_insn *insn, const struct pt_insn_ext *iext) { @@ -196,7 +252,7 @@ default: return -pte_bad_query; - case ptic_error: + case ptic_unknown: return -pte_bad_insn; }
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/src/pt_insn_decoder.c -> _service:tar_scm:v2.1.tar.gz/libipt/src/pt_insn_decoder.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -58,6 +59,9 @@ decoder->bound_paging = 0; decoder->bound_vmcs = 0; decoder->bound_ptwrite = 0; + decoder->bound_iret = 0; + decoder->bound_vmentry = 0; + decoder->bound_uiret = 0; pt_retstack_init(&decoder->retstack); pt_asid_init(&decoder->asid); @@ -99,6 +103,10 @@ return -pte_internal; memset(qflags, 0, sizeof(*qflags)); + qflags->variant.query.keep_tcal_on_ovf = + flags->variant.insn.keep_tcal_on_ovf; + qflags->variant.query.enable_iflags_events = + flags->variant.insn.enable_iflags_events; return 0; } @@ -406,10 +414,7 @@ const struct pt_config * pt_insn_get_config(const struct pt_insn_decoder *decoder) { - if (!decoder) - return NULL; - - return pt_qry_get_config(&decoder->query); + return pt_insn_config(decoder); } int pt_insn_time(struct pt_insn_decoder *decoder, uint64_t *time, @@ -586,9 +591,10 @@ case ptic_far_call: case ptic_far_return: case ptic_far_jump: + case ptic_indirect: break; - case ptic_error: + case ptic_unknown: return -pte_bad_insn; } @@ -711,10 +717,11 @@ case ptic_far_call: case ptic_far_return: case ptic_far_jump: + case ptic_indirect: case ptic_cond_jump: return 1; - case ptic_error: + case ptic_unknown: return -pte_bad_insn; } } @@ -759,6 +766,9 @@ decoder->bound_paging = 0; decoder->bound_vmcs = 0; decoder->bound_ptwrite = 0; + decoder->bound_iret = 0; + decoder->bound_vmentry = 0; + decoder->bound_uiret = 0; return 0; } @@ -819,6 +829,10 @@ ev = &decoder->event; switch (ev->type) { + case ptev_tip: + case ptev_tnt: + return -pte_internal; + case ptev_enabled: case ptev_overflow: case ptev_async_paging: @@ -835,12 +849,24 @@ case ptev_tick: case ptev_cbr: case ptev_mnt: + case ptev_iflags: + case ptev_interrupt: + case ptev_smi: + case ptev_rsm: + case ptev_sipi: + case ptev_init: + case ptev_vmexit: + case ptev_shutdown: + case ptev_uintr: /* We're only interested in events that bind to instructions. */ return 0; case ptev_disabled: + if (ev->status_update) + return 0; + status = pt_insn_at_disabled_event(ev, insn, iext, - &decoder->query.config); + pt_insn_config(decoder)); if (status <= 0) return status; @@ -939,6 +965,99 @@ decoder->bound_ptwrite = 1; return pt_insn_postpone(decoder, insn, iext); + + case ptev_iret: + /* We bind at most one iret event to an instruction. */ + if (decoder->bound_iret) + return 0; + + if (ev->ip_suppressed) { + if (!pt_insn_is_iret(insn, iext)) + return 0; + + /* Fill in the event IP. */ + ev->variant.iret.ip = decoder->ip; + ev->ip_suppressed = 0; + } else { + /* The iret event contains the IP of the iret + * instruction (CLIP) unlike most events that contain + * the IP of the first instruction that did not + * complete (NLIP). + * + * It's easier to handle this case here, as well. + */ + if (decoder->ip != ev->variant.iret.ip) + return 0; + } + + /* We bound an iret event. Make sure we do not bind further + * iret events to this instruction. + */ + decoder->bound_iret = 1; + + return pt_insn_postpone(decoder, insn, iext); + + case ptev_vmentry: + /* We bind at most one vmentry event to an instruction. */ + if (decoder->bound_vmentry) + return 0; + + if (ev->ip_suppressed) { + if (!pt_insn_is_vmentry(insn, iext)) + return 0; + + /* Fill in the event IP. */ + ev->variant.vmentry.ip = decoder->ip; + ev->ip_suppressed = 0; + } else { + /* The vmentry event contains the IP of the vmentry + * instruction (CLIP) unlike most events that contain + * the IP of the first instruction that did not + * complete (NLIP). + * + * It's easier to handle this case here, as well. + */ + if (decoder->ip != ev->variant.vmentry.ip) + return 0; + } + + /* We bound a vmentry event. Make sure we do not bind further + * vmentry events to this instruction. + */ + decoder->bound_vmentry = 1; + + return pt_insn_postpone(decoder, insn, iext); + + case ptev_uiret: + /* We bind at most one uiret event to an instruction. */ + if (decoder->bound_uiret) + return 0; + + if (ev->ip_suppressed) { + if (!pt_insn_is_uiret(insn, iext)) + return 0; + + /* Fill in the event IP. */ + ev->variant.uiret.ip = decoder->ip; + ev->ip_suppressed = 0; + } else { + /* The uiret event contains the IP of the uiret + * instruction (CLIP) unlike most events that contain + * the IP of the first instruction that did not + * complete (NLIP). + * + * It's easier to handle this case here, as well. + */ + if (decoder->ip != ev->variant.uiret.ip) + return 0; + } + + /* We bound an uiret event. Make sure we do not bind further + * uiret events to this instruction. + */ + decoder->bound_uiret = 1; + + return pt_insn_postpone(decoder, insn, iext); } return pt_insn_status(decoder, pts_event_pending); @@ -1021,10 +1140,18 @@ if (ev->ip_suppressed) return 0; - if (insn && iext && decoder->query.config.errata.bdm64) { - status = handle_erratum_bdm64(decoder, ev, insn, iext); - if (status < 0) - return status; + if (insn && iext) { + const struct pt_config *config; + + config = pt_insn_config(decoder); + if (!config) + return -pte_internal; + + if (config->errata.bdm64) { + status = handle_erratum_bdm64(decoder, ev, insn, iext); + if (status < 0) + return status; + } } if (decoder->ip != ev->variant.tsx.ip) @@ -1062,18 +1189,26 @@ ev = &decoder->event; switch (ev->type) { case ptev_disabled: + if (ev->status_update) + return pt_insn_status(decoder, pts_event_pending); + break; case ptev_enabled: return pt_insn_status(decoder, pts_event_pending); - case ptev_async_disabled: + case ptev_async_disabled: { + const struct pt_config *config; + int errcode; + if (ev->variant.async_disabled.at != decoder->ip) break; - if (decoder->query.config.errata.skd022) { - int errcode; + config = pt_insn_config(decoder); + if (!config) + return -pte_internal; + if (config->errata.skd022) { errcode = handle_erratum_skd022(decoder); if (errcode != 0) { if (errcode < 0) @@ -1088,6 +1223,7 @@ } return pt_insn_status(decoder, pts_event_pending); + } case ptev_tsx: status = pt_insn_postpone_tsx(decoder, insn, iext, ev); @@ -1110,7 +1246,7 @@ return pt_insn_status(decoder, pts_event_pending); case ptev_exec_mode: - if (!ev->ip_suppressed && + if (decoder->enabled && !ev->ip_suppressed && ev->variant.exec_mode.ip != decoder->ip) break; @@ -1183,6 +1319,119 @@ case ptev_cbr: case ptev_mnt: return pt_insn_status(decoder, pts_event_pending); + + case ptev_tip: + case ptev_tnt: + return -pte_internal; + + case ptev_iflags: + if (decoder->enabled && !ev->ip_suppressed && + ev->variant.iflags.ip != decoder->ip) + break; + + return pt_insn_status(decoder, pts_event_pending); + + case ptev_interrupt: + if (decoder->enabled && !ev->ip_suppressed && + ev->variant.interrupt.ip != decoder->ip) + break; + + return pt_insn_status(decoder, pts_event_pending); + + case ptev_iret: + /* Any event binding to the current IRET instruction is handled + * in pt_insn_check_insn_event(). + * + * Any subsequent iret event binds to a different instruction + * and must wait until the next iteration - as long as tracing + * is enabled. + * + * When tracing is disabled, we forward all iret events + * immediately to the user. + */ + if (decoder->enabled) + break; + + return pt_insn_status(decoder, pts_event_pending); + + case ptev_smi: + if (decoder->enabled && !ev->ip_suppressed && + ev->variant.smi.ip != decoder->ip) + break; + + return pt_insn_status(decoder, pts_event_pending); + + case ptev_rsm: + if (!ev->ip_suppressed) + return -pte_internal; + + return pt_insn_status(decoder, pts_event_pending); + + case ptev_init: + if (decoder->enabled && !ev->ip_suppressed && + ev->variant.init.ip != decoder->ip) + break; + + return pt_insn_status(decoder, pts_event_pending); + + case ptev_sipi: + if (!ev->ip_suppressed) + return -pte_internal; + + return pt_insn_status(decoder, pts_event_pending); + + case ptev_vmentry: + /* Any event binding to the current vmentry instruction is + * handled in pt_insn_check_insn_event(). + * + * Any subsequent vmentry event binds to a different + * instruction and must wait until the next iteration - as long + * as tracing is enabled. + * + * When tracing is disabled, we forward all vmentry events + * immediately to the user. + */ + if (decoder->enabled) + break; + + return pt_insn_status(decoder, pts_event_pending); + + case ptev_vmexit: + if (decoder->enabled && !ev->ip_suppressed && + ev->variant.vmexit.ip != decoder->ip) + break; + + return pt_insn_status(decoder, pts_event_pending); + + case ptev_shutdown: + if (decoder->enabled && !ev->ip_suppressed && + ev->variant.shutdown.ip != decoder->ip) + break; + + return pt_insn_status(decoder, pts_event_pending); + + case ptev_uintr: + if (decoder->enabled && !ev->ip_suppressed && + ev->variant.uintr.ip != decoder->ip) + break; + + return pt_insn_status(decoder, pts_event_pending); + + case ptev_uiret: + /* Any event binding to the current UIRET instruction is + * handled in pt_insn_check_insn_event(). + * + * Any subsequent uiret event binds to a different instruction + * and must wait until the next iteration - as long as tracing + * is enabled. + * + * When tracing is disabled, we forward all uiret events + * immediately to the user. + */ + if (decoder->enabled) + break; + + return pt_insn_status(decoder, pts_event_pending); } return pt_insn_status(decoder, 0); @@ -1199,7 +1448,8 @@ /* Zero out any unknown bytes. */ if (sizeof(*insn) < size) { - memset(uinsn + sizeof(*insn), 0, size - sizeof(*insn)); + memset(((uint8_t *) uinsn) + sizeof(*insn), 0, + size - sizeof(*insn)); size = sizeof(*insn); } @@ -1385,9 +1635,13 @@ ev = &decoder->event; - /* This event can't be a status update. */ - if (ev->status_update) - return -pte_bad_context; + /* Use status update events to diagnose inconsistencies. */ + if (ev->status_update) { + if (!decoder->enabled) + return -pte_bad_status_update; + + return 0; + } /* We must have an IP in order to start decoding. */ if (ev->ip_suppressed) @@ -1412,9 +1666,13 @@ ev = &decoder->event; - /* This event can't be a status update. */ - if (ev->status_update) - return -pte_bad_context; + /* Use status update events to diagnose inconsistencies. */ + if (ev->status_update) { + if (decoder->enabled) + return -pte_bad_status_update; + + return 0; + } /* We must currently be enabled. */ if (!decoder->enabled) @@ -1721,6 +1979,74 @@ case ptev_tick: case ptev_cbr: case ptev_mnt: + case ptev_iret: + case ptev_vmentry: + case ptev_uiret: + break; + + case ptev_tip: + case ptev_tnt: + return -pte_internal; + + case ptev_iflags: + if (!ev->ip_suppressed && decoder->enabled && + decoder->ip != ev->variant.iflags.ip) + return -pte_bad_query; + + break; + + case ptev_interrupt: + if (!ev->ip_suppressed && decoder->enabled && + decoder->ip != ev->variant.interrupt.ip) + return -pte_bad_query; + + break; + + case ptev_smi: + if (!ev->ip_suppressed && decoder->enabled && + decoder->ip != ev->variant.smi.ip) + return -pte_bad_query; + + break; + + case ptev_rsm: + if (!ev->ip_suppressed) + return -pte_internal; + + break; + + + case ptev_sipi: + if (!ev->ip_suppressed) + return -pte_internal; + + break; + case ptev_init: + if (!ev->ip_suppressed && decoder->enabled && + decoder->ip != ev->variant.init.ip) + return -pte_bad_query; + + break; + + case ptev_vmexit: + if (!ev->ip_suppressed && decoder->enabled && + decoder->ip != ev->variant.vmexit.ip) + return -pte_bad_query; + + break; + + case ptev_shutdown: + if (!ev->ip_suppressed && decoder->enabled && + decoder->ip != ev->variant.shutdown.ip) + return -pte_bad_query; + + break; + + case ptev_uintr: + if (!ev->ip_suppressed && decoder->enabled && + decoder->ip != ev->variant.uintr.ip) + return -pte_bad_query; + break; }
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/src/pt_last_ip.c -> _service:tar_scm:v2.1.tar.gz/libipt/src/pt_last_ip.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/src/pt_msec_cache.c -> _service:tar_scm:v2.1.tar.gz/libipt/src/pt_msec_cache.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2017-2022, Intel Corporation + * Copyright (c) 2017-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/src/pt_packet.c -> _service:tar_scm:v2.1.tar.gz/libipt/src/pt_packet.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -268,6 +269,7 @@ packet->csl = (mode & pt_mob_exec_csl) != 0; packet->csd = (mode & pt_mob_exec_csd) != 0; + packet->iflag = (mode & pt_mob_exec_iflag) != 0; return ptps_mode; } @@ -574,3 +576,38 @@ return pt_opcs_ptw + size; } + +int pt_pkt_read_cfe(struct pt_packet_cfe *packet, const uint8_t *pos, + const struct pt_config *config) +{ + if (!packet || !pos || !config) + return -pte_internal; + + if (config->end < pos + ptps_cfe) + return -pte_eos; + + pos += pt_opcs_cfe; + + packet->type = pos0 & pt_pl_cfe_type; + packet->vector = pos1; + packet->ip = pos0 & pt_pl_cfe_ip ? 1 : 0; + + return ptps_cfe; +} + +int pt_pkt_read_evd(struct pt_packet_evd *packet, const uint8_t *pos, + const struct pt_config *config) +{ + if (!packet || !pos || !config) + return -pte_internal; + + if (config->end < pos + ptps_evd) + return -pte_eos; + + pos += pt_opcs_evd; + + packet->type = pos0 & pt_pl_evd_type; + packet->payload = pt_pkt_read_value(&pos1, pt_pl_evd_pl_size); + + return ptps_evd; +}
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/src/pt_packet_decoder.c -> _service:tar_scm:v2.1.tar.gz/libipt/src/pt_packet_decoder.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2014-2022, Intel Corporation + * Copyright (c) 2014-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -27,7 +28,6 @@ */ #include "pt_packet_decoder.h" -#include "pt_decoder_function.h" #include "pt_packet.h" #include "pt_sync.h" #include "pt_config.h" @@ -223,7 +223,8 @@ /* Zero out any unknown bytes. */ if (sizeof(*pkt) < size) { - memset(upkt + sizeof(*pkt), 0, size - sizeof(*pkt)); + memset(((uint8_t *) upkt) + sizeof(*pkt), 0, + size - sizeof(*pkt)); size = sizeof(*pkt); } @@ -233,43 +234,8 @@ return 0; } -int pt_pkt_next(struct pt_packet_decoder *decoder, struct pt_packet *packet, - size_t psize) -{ - const struct pt_decoder_function *dfun; - struct pt_packet pkt, *ppkt; - int errcode, size; - - if (!packet || !decoder) - return -pte_invalid; - - ppkt = psize == sizeof(pkt) ? packet : &pkt; - - errcode = pt_df_fetch(&dfun, decoder->pos, &decoder->config); - if (errcode < 0) - return errcode; - - if (!dfun) - return -pte_internal; - - if (!dfun->packet) - return -pte_internal; - - size = dfun->packet(decoder, ppkt); - if (size < 0) - return size; - - errcode = pkt_to_user(packet, psize, ppkt); - if (errcode < 0) - return errcode; - - decoder->pos += size; - - return size; -} - -int pt_pkt_decode_unknown(struct pt_packet_decoder *decoder, - struct pt_packet *packet) +static int pt_pkt_decode_unknown(struct pt_packet_decoder *decoder, + struct pt_packet *packet) { int size; @@ -283,8 +249,8 @@ return size; } -int pt_pkt_decode_pad(struct pt_packet_decoder *decoder, - struct pt_packet *packet) +static int pt_pkt_decode_pad(struct pt_packet_decoder *decoder, + struct pt_packet *packet) { (void) decoder; @@ -297,8 +263,8 @@ return ptps_pad; } -int pt_pkt_decode_psb(struct pt_packet_decoder *decoder, - struct pt_packet *packet) +static int pt_pkt_decode_psb(struct pt_packet_decoder *decoder, + struct pt_packet *packet) { int size; @@ -315,8 +281,8 @@ return size; } -int pt_pkt_decode_tip(struct pt_packet_decoder *decoder, - struct pt_packet *packet) +static int pt_pkt_decode_tip(struct pt_packet_decoder *decoder, + struct pt_packet *packet) { int size; @@ -334,8 +300,8 @@ return size; } -int pt_pkt_decode_tnt_8(struct pt_packet_decoder *decoder, - struct pt_packet *packet) +static int pt_pkt_decode_tnt_8(struct pt_packet_decoder *decoder, + struct pt_packet *packet) { int size; @@ -353,8 +319,8 @@ return size; } -int pt_pkt_decode_tnt_64(struct pt_packet_decoder *decoder, - struct pt_packet *packet) +static int pt_pkt_decode_tnt_64(struct pt_packet_decoder *decoder, + struct pt_packet *packet) { int size; @@ -372,8 +338,8 @@ return size; } -int pt_pkt_decode_tip_pge(struct pt_packet_decoder *decoder, - struct pt_packet *packet) +static int pt_pkt_decode_tip_pge(struct pt_packet_decoder *decoder, + struct pt_packet *packet) { int size; @@ -391,8 +357,8 @@ return size; } -int pt_pkt_decode_tip_pgd(struct pt_packet_decoder *decoder, - struct pt_packet *packet) +static int pt_pkt_decode_tip_pgd(struct pt_packet_decoder *decoder, + struct pt_packet *packet) { int size; @@ -410,8 +376,8 @@ return size; } -int pt_pkt_decode_fup(struct pt_packet_decoder *decoder, - struct pt_packet *packet) +static int pt_pkt_decode_fup(struct pt_packet_decoder *decoder, + struct pt_packet *packet) { int size; @@ -429,8 +395,8 @@ return size; } -int pt_pkt_decode_pip(struct pt_packet_decoder *decoder, - struct pt_packet *packet) +static int pt_pkt_decode_pip(struct pt_packet_decoder *decoder, + struct pt_packet *packet) { int size; @@ -448,8 +414,8 @@ return size; } -int pt_pkt_decode_ovf(struct pt_packet_decoder *decoder, - struct pt_packet *packet) +static int pt_pkt_decode_ovf(struct pt_packet_decoder *decoder, + struct pt_packet *packet) { (void) decoder; @@ -462,8 +428,8 @@ return ptps_ovf; } -int pt_pkt_decode_mode(struct pt_packet_decoder *decoder, - struct pt_packet *packet) +static int pt_pkt_decode_mode(struct pt_packet_decoder *decoder, + struct pt_packet *packet) { int size; @@ -481,8 +447,8 @@ return size; } -int pt_pkt_decode_psbend(struct pt_packet_decoder *decoder, - struct pt_packet *packet) +static int pt_pkt_decode_psbend(struct pt_packet_decoder *decoder, + struct pt_packet *packet) { (void) decoder; @@ -495,8 +461,8 @@ return ptps_psbend; } -int pt_pkt_decode_tsc(struct pt_packet_decoder *decoder, - struct pt_packet *packet) +static int pt_pkt_decode_tsc(struct pt_packet_decoder *decoder, + struct pt_packet *packet) { int size; @@ -514,8 +480,8 @@ return size; } -int pt_pkt_decode_cbr(struct pt_packet_decoder *decoder, - struct pt_packet *packet) +static int pt_pkt_decode_cbr(struct pt_packet_decoder *decoder, + struct pt_packet *packet) { int size; @@ -533,8 +499,8 @@ return size; } -int pt_pkt_decode_tma(struct pt_packet_decoder *decoder, - struct pt_packet *packet) +static int pt_pkt_decode_tma(struct pt_packet_decoder *decoder, + struct pt_packet *packet) { int size; @@ -567,8 +533,8 @@ return size; } -int pt_pkt_decode_mtc(struct pt_packet_decoder *decoder, - struct pt_packet *packet) +static int pt_pkt_decode_mtc(struct pt_packet_decoder *decoder, + struct pt_packet *packet) { int size; @@ -586,10 +552,55 @@ return size; } -int pt_pkt_decode_cyc(struct pt_packet_decoder *decoder, - struct pt_packet *packet) +static int pt_pkt_handle_skd007(struct pt_packet_decoder *decoder, + struct pt_packet *packet) { - int size; + const uint8_t *pos; + uint16_t payload; + uint8_t size; + + if (!decoder || !packet) + return -pte_internal; + + if (packet->type != ppt_cyc) + return -pte_internal; + + /* It must be a 2-byte CYC. */ + size = packet->size; + if (size != 2) + return 0; + + payload = (uint16_t) packet->payload.cyc.value; + + /* The 2nd byte of the CYC payload must look like an ext opcode. */ + if ((payload & ~0x1f) != 0x20) + return 0; + + /* Skip this CYC packet. */ + pos = decoder->pos + size; + if (decoder->config.end <= pos) + return 0; + + /* See if we got a second CYC that looks like an OVF ext opcode. */ + if (*pos != pt_ext_ovf) + return 0; + + /* We shouldn't get back-to-back CYCs unless they are sent when the + * counter wraps around. In this case, we'd expect a full payload. + * + * Since we got two non-full CYC packets, we assume the erratum hit. + * We ignore the CYC since we cannot provide its correct content, + * anyway, and report the OVF, instead. + */ + decoder->pos += 1; + + return pt_pkt_decode_ovf(decoder, packet); +} + +static int pt_pkt_decode_cyc(struct pt_packet_decoder *decoder, + struct pt_packet *packet) +{ + int size, errcode; if (!decoder || !packet) return -pte_internal; @@ -602,11 +613,17 @@ packet->type = ppt_cyc; packet->size = (uint8_t) size; + if (decoder->config.errata.skd007) { + errcode = pt_pkt_handle_skd007(decoder, packet); + if (errcode != 0) + return errcode; + } + return size; } -int pt_pkt_decode_stop(struct pt_packet_decoder *decoder, - struct pt_packet *packet) +static int pt_pkt_decode_stop(struct pt_packet_decoder *decoder, + struct pt_packet *packet) { (void) decoder; @@ -619,8 +636,8 @@ return ptps_stop; } -int pt_pkt_decode_vmcs(struct pt_packet_decoder *decoder, - struct pt_packet *packet) +static int pt_pkt_decode_vmcs(struct pt_packet_decoder *decoder, + struct pt_packet *packet) { int size; @@ -638,8 +655,8 @@ return size; } -int pt_pkt_decode_mnt(struct pt_packet_decoder *decoder, - struct pt_packet *packet) +static int pt_pkt_decode_mnt(struct pt_packet_decoder *decoder, + struct pt_packet *packet) { int size; @@ -657,8 +674,8 @@ return size; } -int pt_pkt_decode_exstop(struct pt_packet_decoder *decoder, - struct pt_packet *packet) +static int pt_pkt_decode_exstop(struct pt_packet_decoder *decoder, + struct pt_packet *packet) { int size; @@ -676,8 +693,8 @@ return size; } -int pt_pkt_decode_mwait(struct pt_packet_decoder *decoder, - struct pt_packet *packet) +static int pt_pkt_decode_mwait(struct pt_packet_decoder *decoder, + struct pt_packet *packet) { int size; @@ -695,8 +712,8 @@ return size; } -int pt_pkt_decode_pwre(struct pt_packet_decoder *decoder, - struct pt_packet *packet) +static int pt_pkt_decode_pwre(struct pt_packet_decoder *decoder, + struct pt_packet *packet) { int size; @@ -714,8 +731,8 @@ return size; } -int pt_pkt_decode_pwrx(struct pt_packet_decoder *decoder, - struct pt_packet *packet) +static int pt_pkt_decode_pwrx(struct pt_packet_decoder *decoder, + struct pt_packet *packet) { int size; @@ -733,8 +750,8 @@ return size; } -int pt_pkt_decode_ptw(struct pt_packet_decoder *decoder, - struct pt_packet *packet) +static int pt_pkt_decode_ptw(struct pt_packet_decoder *decoder, + struct pt_packet *packet) { int size; @@ -751,3 +768,196 @@ return size; } + +static int pt_pkt_decode_cfe(struct pt_packet_decoder *decoder, + struct pt_packet *packet) +{ + int size; + + if (!decoder || !packet) + return -pte_internal; + + size = pt_pkt_read_cfe(&packet->payload.cfe, decoder->pos, + &decoder->config); + if (size < 0) + return size; + + packet->type = ppt_cfe; + packet->size = (uint8_t) size; + + return size; +} + +static int pt_pkt_decode_evd(struct pt_packet_decoder *decoder, + struct pt_packet *packet) +{ + int size; + + if (!decoder || !packet) + return -pte_internal; + + size = pt_pkt_read_evd(&packet->payload.evd, decoder->pos, + &decoder->config); + if (size < 0) + return size; + + packet->type = ppt_evd; + packet->size = (uint8_t) size; + + return size; +} + +static int pt_pkt_decode(struct pt_packet_decoder *decoder, + struct pt_packet *packet) +{ + const struct pt_config *config; + const uint8_t *pos, *begin, *end; + uint8_t opc, ext, ext2; + + config = pt_pkt_config(decoder); + if (!config) + return -pte_internal; + + begin = config->begin; + pos = pt_pkt_pos(decoder); + if (pos < begin) + return -pte_nosync; + + end = config->end; + if (end <= pos) + return -pte_eos; + + opc = *pos++; + switch (opc) { + default: + /* Check opcodes that require masking. */ + if ((opc & pt_opm_cyc) == pt_opc_cyc) + return pt_pkt_decode_cyc(decoder, packet); + + if ((opc & pt_opm_tnt_8) == pt_opc_tnt_8) + return pt_pkt_decode_tnt_8(decoder, packet); + + if ((opc & pt_opm_fup) == pt_opc_fup) + return pt_pkt_decode_fup(decoder, packet); + + if ((opc & pt_opm_tip) == pt_opc_tip) + return pt_pkt_decode_tip(decoder, packet); + + if ((opc & pt_opm_tip) == pt_opc_tip_pge) + return pt_pkt_decode_tip_pge(decoder, packet); + + if ((opc & pt_opm_tip) == pt_opc_tip_pgd) + return pt_pkt_decode_tip_pgd(decoder, packet); + + return pt_pkt_decode_unknown(decoder, packet); + + case pt_opc_mode: + return pt_pkt_decode_mode(decoder, packet); + + case pt_opc_mtc: + return pt_pkt_decode_mtc(decoder, packet); + + case pt_opc_tsc: + return pt_pkt_decode_tsc(decoder, packet); + + case pt_opc_pad: + return pt_pkt_decode_pad(decoder, packet); + + case pt_opc_ext: + if (end <= pos) + return -pte_eos; + + ext = *pos++; + switch (ext) { + default: + /* Check opcodes that require masking. */ + if ((ext & pt_opm_ptw) == pt_ext_ptw) + return pt_pkt_decode_ptw(decoder, packet); + + return pt_pkt_decode_unknown(decoder, packet); + + case pt_ext_psb: + return pt_pkt_decode_psb(decoder, packet); + + case pt_ext_ovf: + return pt_pkt_decode_ovf(decoder, packet); + + case pt_ext_psbend: + return pt_pkt_decode_psbend(decoder, packet); + + case pt_ext_cbr: + return pt_pkt_decode_cbr(decoder, packet); + + case pt_ext_tma: + return pt_pkt_decode_tma(decoder, packet); + + case pt_ext_pip: + return pt_pkt_decode_pip(decoder, packet); + + case pt_ext_vmcs: + return pt_pkt_decode_vmcs(decoder, packet); + + case pt_ext_exstop: + case pt_ext_exstop_ip: + return pt_pkt_decode_exstop(decoder, packet); + + case pt_ext_mwait: + return pt_pkt_decode_mwait(decoder, packet); + + case pt_ext_pwre: + return pt_pkt_decode_pwre(decoder, packet); + + case pt_ext_pwrx: + return pt_pkt_decode_pwrx(decoder, packet); + + case pt_ext_stop: + return pt_pkt_decode_stop(decoder, packet); + + case pt_ext_tnt_64: + return pt_pkt_decode_tnt_64(decoder, packet); + + case pt_ext_cfe: + return pt_pkt_decode_cfe(decoder, packet); + + case pt_ext_evd: + return pt_pkt_decode_evd(decoder, packet); + + case pt_ext_ext2: + if (end <= pos) + return -pte_eos; + + ext2 = *pos++; + switch (ext2) { + default: + return pt_pkt_decode_unknown(decoder, packet); + + case pt_ext2_mnt: + return pt_pkt_decode_mnt(decoder, packet); + } + } + } +} + +int pt_pkt_next(struct pt_packet_decoder *decoder, struct pt_packet *packet, + size_t psize) +{ + struct pt_packet pkt, *ppkt; + int errcode, size; + + if (!packet || !decoder) + return -pte_invalid; + + ppkt = psize == sizeof(pkt) ? packet : &pkt; + + size = pt_pkt_decode(decoder, ppkt); + if (size < 0) + return size; + + errcode = pkt_to_user(packet, psize, ppkt); + if (errcode < 0) + return errcode; + + decoder->pos += size; + + return size; +}
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/src/pt_query_decoder.c -> _service:tar_scm:v2.1.tar.gz/libipt/src/pt_query_decoder.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2014-2022, Intel Corporation + * Copyright (c) 2014-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -27,10 +28,6 @@ */ #include "pt_query_decoder.h" -#include "pt_sync.h" -#include "pt_decoder_function.h" -#include "pt_packet.h" -#include "pt_packet_decoder.h" #include "pt_config.h" #include "pt_opcodes.h" #include "pt_compiler.h" @@ -43,70 +40,62 @@ #include <limits.h> -/* Find a FUP in a PSB+ header. - * - * The packet @decoder must be synchronized onto the trace stream at the - * beginning or somewhere inside a PSB+ header. - * - * It uses @packet to hold trace packets during its search. If the search is - * successful, @packet will contain the first (and hopefully only) FUP packet in - * this PSB+. Otherwise, @packet may contain anything. - * - * Returns one if a FUP packet is found (@packet will contain it). - * Returns zero if no FUP packet is found (@packet is undefined). - * Returns a negative error code otherwise. - */ -static int pt_qry_find_header_fup(struct pt_packet *packet, - struct pt_packet_decoder *decoder) +/* Initialize the event decoder flags based on our flags. */ + +static int pt_qry_init_evt_flags(struct pt_conf_flags *eflags, + const struct pt_conf_flags *flags) { - if (!packet || !decoder) + if (!eflags || !flags) return -pte_internal; - for (;;) { - int errcode; + memset(eflags, 0, sizeof(*eflags)); + eflags->variant.event.keep_tcal_on_ovf = + flags->variant.query.keep_tcal_on_ovf; + eflags->variant.event.enable_iflags_events = + flags->variant.query.enable_iflags_events; - errcode = pt_pkt_next(decoder, packet, sizeof(*packet)); - if (errcode < 0) - return errcode; + return 0; +} - switch (packet->type) { - default: - /* Ignore the packet. */ - break; +static int pt_qry_reset(struct pt_query_decoder *decoder) +{ + if (!decoder) + return -pte_internal; - case ppt_psbend: - /* There's no FUP in here. */ - return 0; + decoder->status = -pte_nosync; - case ppt_fup: - /* Found it. */ - return 1; - } - } + pt_tnt_cache_init(&decoder->tnt); + pt_time_init(&decoder->last_time); + + return 0; } int pt_qry_decoder_init(struct pt_query_decoder *decoder, - const struct pt_config *config) + const struct pt_config *uconfig) { + struct pt_config config; int errcode; if (!decoder) return -pte_invalid; - memset(decoder, 0, sizeof(*decoder)); + errcode = pt_config_from_user(&config, uconfig); + if (errcode < 0) + return errcode; + + /* The user supplied decoder flags. */ + decoder->flags = config.flags; - errcode = pt_config_from_user(&decoder->config, config); + /* Set the flags we need for the event decoder we use. */ + errcode = pt_qry_init_evt_flags(&config.flags, &decoder->flags); if (errcode < 0) return errcode; - pt_last_ip_init(&decoder->ip); - pt_tnt_cache_init(&decoder->tnt); - pt_time_init(&decoder->time); - pt_time_init(&decoder->last_time); - pt_tcal_init(&decoder->tcal); - pt_evq_init(&decoder->evq); + errcode = pt_evt_decoder_init(&decoder->evdec, &config); + if (errcode < 0) + return errcode; - return 0; + return pt_qry_reset(decoder); } struct pt_query_decoder *pt_qry_alloc_decoder(const struct pt_config *config) @@ -129,9 +118,10 @@ void pt_qry_decoder_fini(struct pt_query_decoder *decoder) { - (void) decoder; + if (!decoder) + return; - /* Nothing to do. */ + pt_evt_decoder_fini(&decoder->evdec); } void pt_qry_free_decoder(struct pt_query_decoder *decoder) @@ -140,79 +130,30 @@ free(decoder); } -static void pt_qry_reset(struct pt_query_decoder *decoder) +static int pt_qry_event_pending(const struct pt_event *ev) { - if (!decoder) - return; - - decoder->enabled = 0; - decoder->consume_packet = 0; - decoder->event = NULL; - - pt_last_ip_init(&decoder->ip); - pt_tnt_cache_init(&decoder->tnt); - pt_time_init(&decoder->time); - pt_time_init(&decoder->last_time); - pt_tcal_init(&decoder->tcal); - pt_evq_init(&decoder->evq); -} - -static int pt_qry_will_event(const struct pt_query_decoder *decoder) -{ - const struct pt_decoder_function *dfun; - - if (!decoder) + if (!ev) return -pte_internal; - dfun = decoder->next; - if (!dfun) + switch (ev->type) { + case ptev_tnt: + case ptev_tip: return 0; - if (dfun->flags & pdff_event) + default: return 1; - - if (dfun->flags & pdff_psbend) - return pt_evq_pending(&decoder->evq, evb_psbend); - - if (dfun->flags & pdff_tip) - return pt_evq_pending(&decoder->evq, evb_tip); - - if (dfun->flags & pdff_fup) - return pt_evq_pending(&decoder->evq, evb_fup); - - return 0; -} - -static int pt_qry_will_eos(const struct pt_query_decoder *decoder) -{ - const struct pt_decoder_function *dfun; - int errcode; - - if (!decoder) - return -pte_internal; - - dfun = decoder->next; - if (dfun) - return 0; - - /* The decoding function may be NULL for two reasons: - * - * - we ran out of trace - * - we ran into a fetch error such as -pte_bad_opc - * - * Let's fetch again. - */ - errcode = pt_df_fetch(&dfun, decoder->pos, &decoder->config); - return errcode == -pte_eos; + } } static int pt_qry_status_flags(const struct pt_query_decoder *decoder) { - int flags = 0; + int errcode, flags; if (!decoder) return -pte_internal; + flags = 0; + /* Some packets force out TNT and any deferred TIPs in order to * establish the correct context for the subsequent packet. * @@ -228,408 +169,184 @@ * not indicate the next event until the TNT cache is empty. */ if (pt_tnt_cache_is_empty(&decoder->tnt)) { - if (pt_qry_will_event(decoder)) - flags |= pts_event_pending; - - if (pt_qry_will_eos(decoder)) + if (decoder->status == -pte_eos) flags |= pts_eos; + else { + errcode = pt_qry_event_pending(&decoder->event); + if (errcode != 0) { + if (errcode < 0) + return errcode; + + flags |= pts_event_pending; + } + } } return flags; } -static int pt_qry_provoke_fetch_error(const struct pt_query_decoder *decoder) +static int pt_qry_fetch_event(struct pt_query_decoder *decoder) { - const struct pt_decoder_function *dfun; + struct pt_event *ev; int errcode; if (!decoder) return -pte_internal; - /* Repeat the decoder fetch to reproduce the error. */ - errcode = pt_df_fetch(&dfun, decoder->pos, &decoder->config); - if (errcode < 0) - return errcode; - - /* We must get some error or something's wrong. */ - return -pte_internal; -} - -static int pt_qry_read_ahead(struct pt_query_decoder *decoder) -{ - if (!decoder) - return -pte_internal; - - for (;;) { - const struct pt_decoder_function *dfun; - int errcode; - - errcode = pt_df_fetch(&decoder->next, decoder->pos, - &decoder->config); - if (errcode) - return errcode; - - dfun = decoder->next; - if (!dfun) - return -pte_internal; - - if (!dfun->decode) - return -pte_internal; - - /* We're done once we reach - * - * - a branching related packet. */ - if (dfun->flags & (pdff_tip | pdff_tnt)) - return 0; - - /* - an event related packet. */ - if (pt_qry_will_event(decoder)) - return 0; - - /* Decode status update packets. */ - errcode = dfun->decode(decoder); - if (errcode) { - /* Ignore truncated status packets at the end. - * - * Move beyond the packet and clear @decoder->next to - * indicate that we were not able to fetch the next - * packet. - */ - if (errcode == -pte_eos) { - decoder->pos = decoder->config.end; - decoder->next = NULL; - } - - return errcode; - } - } -} - -static int pt_qry_start(struct pt_query_decoder *decoder, const uint8_t *pos, - uint64_t *addr) -{ - const struct pt_decoder_function *dfun; - int status, errcode; - - if (!decoder || !pos) - return -pte_invalid; - - pt_qry_reset(decoder); - - decoder->sync = pos; - decoder->pos = pos; - - errcode = pt_df_fetch(&decoder->next, pos, &decoder->config); - if (errcode) - return errcode; - - dfun = decoder->next; - - /* We do need to start at a PSB in order to initialize the state. */ - if (dfun != &pt_decode_psb) - return -pte_nosync; - - /* Decode the PSB+ header to initialize the state. */ - errcode = dfun->decode(decoder); - if (errcode < 0) - return errcode; - - /* Fill in the start address. - * We do this before reading ahead since the latter may read an - * adjacent PSB+ that might change the decoder's IP, causing us - * to skip code. - */ - if (addr) { - status = pt_last_ip_query(addr, &decoder->ip); - - /* Make sure we don't clobber it later on. */ - if (!status) - addr = NULL; - } - - /* Read ahead until the first query-relevant packet. */ - errcode = pt_qry_read_ahead(decoder); - if (errcode < 0) - return errcode; + ev = &decoder->event; - /* We return the current decoder status. */ - status = pt_qry_status_flags(decoder); - if (status < 0) - return status; - - errcode = pt_last_ip_query(addr, &decoder->ip); + errcode = pt_evt_next(&decoder->evdec, ev, sizeof(*ev)); if (errcode < 0) { - /* Indicate the missing IP in the status. */ - if (addr) - status |= pts_ip_suppressed; + decoder->status = errcode; + memset(ev, 0xff, sizeof(*ev)); } - return status; -} - -static int pt_qry_apply_tsc(struct pt_time *time, struct pt_time_cal *tcal, - const struct pt_packet_tsc *packet, - const struct pt_config *config) -{ - int errcode; - - /* We ignore configuration errors. They will result in imprecise - * calibration which will result in imprecise cycle-accurate timing. - * - * We currently do not track them. - */ - errcode = pt_tcal_update_tsc(tcal, packet, config); - if (errcode < 0 && (errcode != -pte_bad_config)) - return errcode; - - /* We ignore configuration errors. They will result in imprecise - * timing and are tracked as packet losses in struct pt_time. - */ - errcode = pt_time_update_tsc(time, packet, config); - if (errcode < 0 && (errcode != -pte_bad_config)) - return errcode; - - return 0; -} - -static int pt_qry_apply_header_tsc(struct pt_time *time, - struct pt_time_cal *tcal, - const struct pt_packet_tsc *packet, - const struct pt_config *config) -{ - int errcode; - - /* We ignore configuration errors. They will result in imprecise - * calibration which will result in imprecise cycle-accurate timing. - * - * We currently do not track them. - */ - errcode = pt_tcal_header_tsc(tcal, packet, config); - if (errcode < 0 && (errcode != -pte_bad_config)) - return errcode; - - /* We ignore configuration errors. They will result in imprecise - * timing and are tracked as packet losses in struct pt_time. - */ - errcode = pt_time_update_tsc(time, packet, config); - if (errcode < 0 && (errcode != -pte_bad_config)) - return errcode; - return 0; } -static int pt_qry_apply_cbr(struct pt_time *time, struct pt_time_cal *tcal, - const struct pt_packet_cbr *packet, - const struct pt_config *config) +static int pt_qry_start(struct pt_query_decoder *decoder, uint64_t *ip) { - int errcode; - - /* We ignore configuration errors. They will result in imprecise - * calibration which will result in imprecise cycle-accurate timing. - * - * We currently do not track them. - */ - errcode = pt_tcal_update_cbr(tcal, packet, config); - if (errcode < 0 && (errcode != -pte_bad_config)) - return errcode; + struct pt_event_decoder evdec; + struct pt_event ev; + int errcode, flags, status; - /* We ignore configuration errors. They will result in imprecise - * timing and are tracked as packet losses in struct pt_time. - */ - errcode = pt_time_update_cbr(time, packet, config); - if (errcode < 0 && (errcode != -pte_bad_config)) - return errcode; - - return 0; -} - -static int pt_qry_apply_header_cbr(struct pt_time *time, - struct pt_time_cal *tcal, - const struct pt_packet_cbr *packet, - const struct pt_config *config) -{ - int errcode; + if (!decoder) + return -pte_invalid; - /* We ignore configuration errors. They will result in imprecise - * calibration which will result in imprecise cycle-accurate timing. + /* We need to process satus update events from PSB+ in order to + * provide the start IP. * - * We currently do not track them. - */ - errcode = pt_tcal_header_cbr(tcal, packet, config); - if (errcode < 0 && (errcode != -pte_bad_config)) - return errcode; - - /* We ignore configuration errors. They will result in imprecise - * timing and are tracked as packet losses in struct pt_time. + * On the other hand, we need to provide those same status events to + * our user. We do that by using a local copy of our event decoder, so + * when we're done, we rewind back to where we started. */ - errcode = pt_time_update_cbr(time, packet, config); - if (errcode < 0 && (errcode != -pte_bad_config)) - return errcode; + evdec = decoder->evdec; - return 0; -} + status = pts_ip_suppressed; -static int pt_qry_apply_tma(struct pt_time *time, struct pt_time_cal *tcal, - const struct pt_packet_tma *packet, - const struct pt_config *config) -{ - int errcode; + /* Process status update events from PSB+ to initialize our state. */ + for (;;) { + /* Check that we're still processing the initial events. + * + * When the event decoder moves ahead, we're done with the + * initial PSB+. We may get additional events from an adjacent + * PSB+, but we don't want to process them here. + */ + if (pt_evt_pos(&evdec) != pt_qry_pos(decoder)) + break; - /* We ignore configuration errors. They will result in imprecise - * calibration which will result in imprecise cycle-accurate timing. - * - * We currently do not track them. - */ - errcode = pt_tcal_update_tma(tcal, packet, config); - if (errcode < 0 && (errcode != -pte_bad_config)) - return errcode; + errcode = pt_evt_next(&evdec, &ev, sizeof(ev)); + if (errcode < 0) { + if (errcode != -pte_eos) + return errcode; - /* We ignore configuration errors. They will result in imprecise - * timing and are tracked as packet losses in struct pt_time. - */ - errcode = pt_time_update_tma(time, packet, config); - if (errcode < 0 && (errcode != -pte_bad_config)) - return errcode; + break; + } - return 0; -} + if (!ev.status_update) + break; -static int pt_qry_apply_mtc(struct pt_time *time, struct pt_time_cal *tcal, - const struct pt_packet_mtc *packet, - const struct pt_config *config) -{ - int errcode; + switch (ev.type) { + case ptev_enabled: + status &= ~pts_ip_suppressed; + if (ip) + *ip = ev.variant.enabled.ip; - /* We ignore configuration errors. They will result in imprecise - * calibration which will result in imprecise cycle-accurate timing. - * - * We currently do not track them. - */ - errcode = pt_tcal_update_mtc(tcal, packet, config); - if (errcode < 0 && (errcode != -pte_bad_config)) - return errcode; + break; - /* We ignore configuration errors. They will result in imprecise - * timing and are tracked as packet losses in struct pt_time. - */ - errcode = pt_time_update_mtc(time, packet, config); - if (errcode < 0 && (errcode != -pte_bad_config)) - return errcode; + default: + continue; + } - return 0; -} + break; + } -static int pt_qry_apply_cyc(struct pt_time *time, struct pt_time_cal *tcal, - const struct pt_packet_cyc *packet, - const struct pt_config *config) -{ - uint64_t fcr; - int errcode; + decoder->status = 0; - /* We ignore configuration errors. They will result in imprecise - * calibration which will result in imprecise cycle-accurate timing. - * - * We currently do not track them. - */ - errcode = pt_tcal_update_cyc(tcal, packet, config); - if (errcode < 0 && (errcode != -pte_bad_config)) + errcode = pt_qry_fetch_event(decoder); + if (errcode < 0) return errcode; - /* We need the FastCounter to Cycles ratio below. Fall back to - * an invalid ratio of 0 if calibration has not kicked in, yet. - * - * This will be tracked as packet loss in struct pt_time. - */ - errcode = pt_tcal_fcr(&fcr, tcal); - if (errcode < 0) { - if (errcode == -pte_no_time) - fcr = 0ull; - else - return errcode; - } + flags = pt_qry_status_flags(decoder); + if (flags < 0) + return flags; - /* We ignore configuration errors. They will result in imprecise - * timing and are tracked as packet losses in struct pt_time. - */ - errcode = pt_time_update_cyc(time, packet, config, fcr); - if (errcode < 0 && (errcode != -pte_bad_config)) - return errcode; + status |= flags; - return 0; + return status; } int pt_qry_sync_forward(struct pt_query_decoder *decoder, uint64_t *ip) { - const uint8_t *pos, *sync, *begin; - ptrdiff_t space; int errcode; if (!decoder) return -pte_invalid; - begin = decoder->config.begin; - sync = decoder->sync; - pos = decoder->pos; - if (!pos) - pos = begin; - - if (pos == sync) - pos += ptps_psb; - - if (pos < begin) - return -pte_internal; - - /* Start a bit earlier so we find PSB that have been partially consumed - * by a preceding packet. - */ - space = pos - begin; - if (ptps_psb <= space) - space = ptps_psb - 1; - - pos -= space; + errcode = pt_qry_reset(decoder); + if (errcode < 0) + return errcode; - errcode = pt_sync_forward(&sync, pos, &decoder->config); + errcode = pt_evt_sync_forward(&decoder->evdec); if (errcode < 0) return errcode; - return pt_qry_start(decoder, sync, ip); + return pt_qry_start(decoder, ip); } int pt_qry_sync_backward(struct pt_query_decoder *decoder, uint64_t *ip) { - const uint8_t *start, *sync; + const uint8_t *start, *sync, *pos; int errcode; if (!decoder) return -pte_invalid; - start = decoder->pos; - if (!start) - start = decoder->config.end; + start = pt_qry_pos(decoder); + if (!start) { + const struct pt_config *config; + + config = pt_qry_config(decoder); + if (!config) + return -pte_internal; + + start = config->end; + if (!start) + return -pte_bad_config; + } sync = start; for (;;) { - errcode = pt_sync_backward(&sync, sync, &decoder->config); + errcode = pt_qry_reset(decoder); if (errcode < 0) return errcode; - errcode = pt_qry_start(decoder, sync, ip); + do { + errcode = pt_evt_sync_backward(&decoder->evdec); + if (errcode < 0) + return errcode; + + pos = pt_qry_pos(decoder); + } while (sync <= pos); + + sync = pos; + + errcode = pt_qry_start(decoder, ip); if (errcode < 0) { - /* Ignore incomplete trace segments at the end. We need - * a full PSB+ to start decoding. + /* Ignore incomplete trace segments at the end. We + * need a full PSB+ to start decoding. */ - if (errcode == -pte_eos) - continue; + if (errcode != -pte_eos) + return errcode; - return errcode; + continue; } - /* An empty trace segment in the middle of the trace might bring - * us back to where we started. - * - * We're done when we reached a new position. + /* When starting inside or right after PSB+, we may end up at + * the same PSB again. Skip it. */ - if (decoder->pos != start) + pos = pt_qry_pos(decoder); + if (pos < start) break; } @@ -639,54 +356,37 @@ int pt_qry_sync_set(struct pt_query_decoder *decoder, uint64_t *ip, uint64_t offset) { - const uint8_t *sync, *pos; int errcode; if (!decoder) return -pte_invalid; - pos = decoder->config.begin + offset; + errcode = pt_qry_reset(decoder); + if (errcode < 0) + return errcode; - errcode = pt_sync_set(&sync, pos, &decoder->config); + errcode = pt_evt_sync_set(&decoder->evdec, offset); if (errcode < 0) return errcode; - return pt_qry_start(decoder, sync, ip); + return pt_qry_start(decoder, ip); } int pt_qry_get_offset(const struct pt_query_decoder *decoder, uint64_t *offset) { - const uint8_t *begin, *pos; - - if (!decoder || !offset) + if (!decoder) return -pte_invalid; - begin = decoder->config.begin; - pos = decoder->pos; - - if (!pos) - return -pte_nosync; - - *offset = (uint64_t) (int64_t) (pos - begin); - return 0; + return pt_evt_get_offset(&decoder->evdec, offset); } int pt_qry_get_sync_offset(const struct pt_query_decoder *decoder, uint64_t *offset) { - const uint8_t *begin, *sync; - - if (!decoder || !offset) + if (!decoder) return -pte_invalid; - begin = decoder->config.begin; - sync = decoder->sync; - - if (!sync) - return -pte_nosync; - - *offset = (uint64_t) (int64_t) (sync - begin); - return 0; + return pt_evt_get_sync_offset(&decoder->evdec, offset); } const struct pt_config * @@ -695,88 +395,77 @@ if (!decoder) return NULL; - return &decoder->config; + return pt_evt_get_config(&decoder->evdec); } static int pt_qry_cache_tnt(struct pt_query_decoder *decoder) { + const struct pt_event *ev; int errcode; if (!decoder) return -pte_internal; - for (;;) { - const struct pt_decoder_function *dfun; + /* Check if the current event is valid. */ + errcode = decoder->status; + if (errcode < 0) + return errcode; - dfun = decoder->next; - if (!dfun) - return pt_qry_provoke_fetch_error(decoder); + /* If we don't have a TNT event, there's nothing to do. */ + ev = &decoder->event; + if (ev->type != ptev_tnt) + return 0; - if (!dfun->decode) - return -pte_internal; + errcode = pt_tnt_cache_add(&decoder->tnt, ev->variant.tnt.bits, + ev->variant.tnt.size); + if (errcode < 0) + return errcode; - /* There's an event ahead of us. */ - if (pt_qry_will_event(decoder)) - return -pte_bad_query; - - /* Diagnose a TIP that has not been part of an event. */ - if (dfun->flags & pdff_tip) - return -pte_bad_query; - - /* Clear the decoder's current event so we know when we - * accidentally skipped an event. - */ - decoder->event = NULL; - - /* Apply the decoder function. */ - errcode = dfun->decode(decoder); - if (errcode) - return errcode; - - /* If we skipped an event, we're in trouble. */ - if (decoder->event) - return -pte_event_ignored; - - /* We're done when we decoded a TNT packet. */ - if (dfun->flags & pdff_tnt) - break; - - /* Read ahead until the next query-relevant packet. */ - errcode = pt_qry_read_ahead(decoder); - if (errcode) - return errcode; - } - - /* Preserve the time at the TNT packet. */ - decoder->last_time = decoder->time; - - /* Read ahead until the next query-relevant packet. */ - errcode = pt_qry_read_ahead(decoder); - if ((errcode < 0) && (errcode != -pte_eos)) - return errcode; - - return 0; + return pt_qry_fetch_event(decoder); } int pt_qry_cond_branch(struct pt_query_decoder *decoder, int *taken) { - int errcode, query; + int query; if (!decoder || !taken) return -pte_invalid; - /* We cache the latest tnt packet in the decoder. Let's re-fill the - * cache in case it is empty. - */ - if (pt_tnt_cache_is_empty(&decoder->tnt)) { + query = pt_tnt_cache_query(&decoder->tnt); + if (query < 0) { + int errcode; + + if (query != -pte_bad_query) + return query; + + /* If we ran out of TNT bits, check if the current event + * provides any. + * + * Preserve the time at the TNT event. + */ + decoder->last_time = decoder->evdec.time; + errcode = pt_qry_cache_tnt(decoder); if (errcode < 0) return errcode; - } - query = pt_tnt_cache_query(&decoder->tnt); - if (query < 0) - return query; + query = pt_tnt_cache_query(&decoder->tnt); + if (query < 0) { + if (query != -pte_bad_query) + return query; + + /* Report any deferred event decode errors. + * + * We deferred them until we consumed the last TNT bit + * in our cache. + */ + errcode = decoder->status; + if (errcode < 0) + return errcode; + + return query; + } + } *taken = query; @@ -785,93 +474,63 @@ int pt_qry_indirect_branch(struct pt_query_decoder *decoder, uint64_t *addr) { - int errcode, flags; + const struct pt_event *ev; + int errcode, status, flags; if (!decoder || !addr) return -pte_invalid; - flags = 0; - for (;;) { - const struct pt_decoder_function *dfun; - - dfun = decoder->next; - if (!dfun) - return pt_qry_provoke_fetch_error(decoder); - - if (!dfun->decode) - return -pte_internal; - - /* There's an event ahead of us. */ - if (pt_qry_will_event(decoder)) - return -pte_bad_query; - - /* Clear the decoder's current event so we know when we - * accidentally skipped an event. - */ - decoder->event = NULL; - - /* We may see a single TNT packet if the current tnt is empty. - * - * If we see a TNT while the current tnt is not empty, it means - * that our user got out of sync. Let's report no data and hope - * that our user is able to re-sync. - */ - if ((dfun->flags & pdff_tnt) && - !pt_tnt_cache_is_empty(&decoder->tnt)) - return -pte_bad_query; + /* Report any deferred error. */ + errcode = decoder->status; + if (errcode < 0) + return errcode; - /* Apply the decoder function. */ - errcode = dfun->decode(decoder); - if (errcode) + ev = &decoder->event; + if (ev->type != ptev_tip) { + /* Fill our TNT cache if we have a TNT packet. */ + errcode = pt_qry_cache_tnt(decoder); + if (errcode < 0) return errcode; - /* If we skipped an event, we're in trouble. */ - if (decoder->event) - return -pte_event_ignored; - - /* We're done when we found a TIP packet that isn't part of an - * event. - */ - if (dfun->flags & pdff_tip) { - uint64_t ip; - - /* We already decoded it, so the branch destination - * is stored in the decoder's last ip. - */ - errcode = pt_last_ip_query(&ip, &decoder->ip); + /* Check again. We may have fetched a new packet. */ + if (ev->type != ptev_tip) { + errcode = decoder->status; if (errcode < 0) - flags |= pts_ip_suppressed; - else - *addr = ip; + return errcode; - break; + return -pte_bad_query; } - - /* Read ahead until the next query-relevant packet. */ - errcode = pt_qry_read_ahead(decoder); - if (errcode) - return errcode; } - /* Preserve the time at the TIP packet. */ - decoder->last_time = decoder->time; + status = 0; + if (ev->ip_suppressed) + status |= pts_ip_suppressed; + else + *addr = ev->variant.tip.ip; + + /* Preserve the time at the TIP event. */ + decoder->last_time = decoder->evdec.time; - /* Read ahead until the next query-relevant packet. */ - errcode = pt_qry_read_ahead(decoder); - if ((errcode < 0) && (errcode != -pte_eos)) + errcode = pt_qry_fetch_event(decoder); + if (errcode < 0) return errcode; - flags |= pt_qry_status_flags(decoder); + flags = pt_qry_status_flags(decoder); + if (flags < 0) + return flags; - return flags; + status |= flags; + + return status; } -int pt_qry_event(struct pt_query_decoder *decoder, struct pt_event *event, +int pt_qry_event(struct pt_query_decoder *decoder, struct pt_event *uev, size_t size) { - int errcode, flags; + const struct pt_event *ev; + int errcode, status; - if (!decoder || !event) + if (!decoder || !uev) return -pte_invalid; if (size < offsetof(struct pt_event, variant)) @@ -883,69 +542,40 @@ if (!pt_tnt_cache_is_empty(&decoder->tnt)) return -pte_bad_query; - /* Do not provide more than we actually have. */ - if (sizeof(*event) < size) - size = sizeof(*event); - - flags = 0; - for (;;) { - const struct pt_decoder_function *dfun; - - dfun = decoder->next; - if (!dfun) - return pt_qry_provoke_fetch_error(decoder); - - if (!dfun->decode) - return -pte_internal; + /* Report any deferred error. */ + errcode = decoder->status; + if (errcode < 0) + return errcode; - /* We must not see a TIP or TNT packet unless it belongs - * to an event. - * - * If we see one, it means that our user got out of sync. - * Let's report no data and hope that our user is able - * to re-sync. - */ - if ((dfun->flags & (pdff_tip | pdff_tnt)) && - !pt_qry_will_event(decoder)) - return -pte_bad_query; + ev = &decoder->event; - /* Clear the decoder's current event so we know when decoding - * produces a new event. - */ - decoder->event = NULL; + status = pt_qry_event_pending(ev); + if (status <= 0) { + if (status < 0) + return status; - /* Apply any other decoder function. */ - errcode = dfun->decode(decoder); - if (errcode) - return errcode; + return -pte_bad_query; + } - /* Check if there has been an event. - * - * Some packets may result in events in some but not in all - * configurations. - */ - if (decoder->event) { - (void) memcpy(event, decoder->event, size); - break; - } + /* Copy the event to the user. Make sure we're not writing beyond the + * memory provided by the user. + * + * We might truncate details of an event but only for those events the + * user can't know about, anyway. + */ + if (sizeof(*uev) < size) + size = sizeof(*uev); - /* Read ahead until the next query-relevant packet. */ - errcode = pt_qry_read_ahead(decoder); - if (errcode) - return errcode; - } + memcpy(uev, ev, size); /* Preserve the time at the event. */ - decoder->last_time = decoder->time; + decoder->last_time = decoder->evdec.time; - /* Read ahead until the next query-relevant packet. */ - errcode = pt_qry_read_ahead(decoder); - if ((errcode < 0) && (errcode != -pte_eos)) + errcode = pt_qry_fetch_event(decoder); + if (errcode < 0) return errcode; - flags |= pt_qry_status_flags(decoder); - - return flags; + return pt_qry_status_flags(decoder); } int pt_qry_time(struct pt_query_decoder *decoder, uint64_t *time, @@ -964,2698 +594,3 @@ return pt_time_query_cbr(cbr, &decoder->last_time); } - -static int pt_qry_event_time(struct pt_event *event, - const struct pt_query_decoder *decoder) -{ - int errcode; - - if (!event || !decoder) - return -pte_internal; - - errcode = pt_time_query_tsc(&event->tsc, &event->lost_mtc, - &event->lost_cyc, &decoder->time); - if (errcode < 0) { - if (errcode != -pte_no_time) - return errcode; - } else - event->has_tsc = 1; - - return 0; -} - -int pt_qry_decode_unknown(struct pt_query_decoder *decoder) -{ - struct pt_packet packet; - int size; - - if (!decoder) - return -pte_internal; - - size = pt_pkt_read_unknown(&packet, decoder->pos, &decoder->config); - if (size < 0) - return size; - - decoder->pos += size; - return 0; -} - -int pt_qry_decode_pad(struct pt_query_decoder *decoder) -{ - if (!decoder) - return -pte_internal; - - decoder->pos += ptps_pad; - - return 0; -} - -static int pt_qry_read_psb_header(struct pt_query_decoder *decoder) -{ - if (!decoder) - return -pte_internal; - - pt_last_ip_init(&decoder->ip); - - for (;;) { - const struct pt_decoder_function *dfun; - int errcode; - - errcode = pt_df_fetch(&decoder->next, decoder->pos, - &decoder->config); - if (errcode) - return errcode; - - dfun = decoder->next; - if (!dfun) - return -pte_internal; - - /* We're done once we reach an psbend packet. */ - if (dfun->flags & pdff_psbend) - return 0; - - if (!dfun->header) - return -pte_bad_context; - - errcode = dfun->header(decoder); - if (errcode) - return errcode; - } -} - -int pt_qry_decode_psb(struct pt_query_decoder *decoder) -{ - const uint8_t *pos; - int size, errcode; - - if (!decoder) - return -pte_internal; - - pos = decoder->pos; - - size = pt_pkt_read_psb(pos, &decoder->config); - if (size < 0) - return size; - - errcode = pt_tcal_update_psb(&decoder->tcal, &decoder->config); - if (errcode < 0) - return errcode; - - decoder->pos += size; - - errcode = pt_qry_read_psb_header(decoder); - if (errcode < 0) { - /* Move back to the PSB so we have a chance to recover and - * continue decoding. - */ - decoder->pos = pos; - - /* Clear any PSB+ events that have already been queued. */ - (void) pt_evq_clear(&decoder->evq, evb_psbend); - - /* Reset the decoder's decode function. */ - decoder->next = &pt_decode_psb; - - return errcode; - } - - /* The next packet following the PSB header will be of type PSBEND. - * - * Decoding this packet will publish the PSB events what have been - * accumulated while reading the PSB header. - */ - return 0; -} - -static int pt_qry_event_ip(uint64_t *ip, struct pt_event *event, - const struct pt_query_decoder *decoder) -{ - int errcode; - - if (!decoder) - return -pte_internal; - - errcode = pt_last_ip_query(ip, &decoder->ip); - if (errcode < 0) { - switch (pt_errcode(errcode)) { - case pte_noip: - case pte_ip_suppressed: - event->ip_suppressed = 1; - break; - - default: - return errcode; - } - } - - return 0; -} - -/* Decode a generic IP packet. - * - * Returns the number of bytes read, on success. - * Returns -pte_eos if the ip does not fit into the buffer. - * Returns -pte_bad_packet if the ip compression is not known. - */ -static int pt_qry_decode_ip(struct pt_query_decoder *decoder) -{ - struct pt_packet_ip packet; - int errcode, size; - - if (!decoder) - return -pte_internal; - - size = pt_pkt_read_ip(&packet, decoder->pos, &decoder->config); - if (size < 0) - return size; - - errcode = pt_last_ip_update_ip(&decoder->ip, &packet, &decoder->config); - if (errcode < 0) - return errcode; - - /* We do not update the decoder's position, yet. */ - - return size; -} - -static int pt_qry_consume_tip(struct pt_query_decoder *decoder, int size) -{ - if (!decoder) - return -pte_internal; - - decoder->pos += size; - return 0; -} - -static int pt_qry_event_tip(struct pt_event *ev, - struct pt_query_decoder *decoder) -{ - if (!ev || !decoder) - return -pte_internal; - - switch (ev->type) { - case ptev_async_branch: - decoder->consume_packet = 1; - - return pt_qry_event_ip(&ev->variant.async_branch.to, ev, - decoder); - - case ptev_async_paging: - return pt_qry_event_ip(&ev->variant.async_paging.ip, ev, - decoder); - - case ptev_async_vmcs: - return pt_qry_event_ip(&ev->variant.async_vmcs.ip, ev, - decoder); - - case ptev_exec_mode: - return pt_qry_event_ip(&ev->variant.exec_mode.ip, ev, - decoder); - - default: - break; - } - - return -pte_bad_context; -} - -int pt_qry_decode_tip(struct pt_query_decoder *decoder) -{ - struct pt_event *ev; - int size, errcode; - - if (!decoder) - return -pte_internal; - - size = pt_qry_decode_ip(decoder); - if (size < 0) - return size; - - /* Process any pending events binding to TIP. */ - ev = pt_evq_dequeue(&decoder->evq, evb_tip); - if (ev) { - errcode = pt_qry_event_tip(ev, decoder); - if (errcode < 0) - return errcode; - - /* Publish the event. */ - decoder->event = ev; - - /* Process further pending events. */ - if (pt_evq_pending(&decoder->evq, evb_tip)) - return 0; - - /* No further events. - * - * If none of the events consumed the packet, we're done. - */ - if (!decoder->consume_packet) - return 0; - - /* We're done with this packet. Clear the flag we set previously - * and consume it. - */ - decoder->consume_packet = 0; - } - - return pt_qry_consume_tip(decoder, size); -} - -int pt_qry_decode_tnt_8(struct pt_query_decoder *decoder) -{ - struct pt_packet_tnt packet; - int size, errcode; - - if (!decoder) - return -pte_internal; - - size = pt_pkt_read_tnt_8(&packet, decoder->pos, &decoder->config); - if (size < 0) - return size; - - errcode = pt_tnt_cache_update_tnt(&decoder->tnt, &packet, - &decoder->config); - if (errcode < 0) - return errcode; - - decoder->pos += size; - return 0; -} - -int pt_qry_decode_tnt_64(struct pt_query_decoder *decoder) -{ - struct pt_packet_tnt packet; - int size, errcode; - - if (!decoder) - return -pte_internal; - - size = pt_pkt_read_tnt_64(&packet, decoder->pos, &decoder->config); - if (size < 0) - return size; - - errcode = pt_tnt_cache_update_tnt(&decoder->tnt, &packet, - &decoder->config); - if (errcode < 0) - return errcode; - - decoder->pos += size; - return 0; -} - -static int pt_qry_consume_tip_pge(struct pt_query_decoder *decoder, int size) -{ - if (!decoder) - return -pte_internal; - - decoder->pos += size; - return 0; -} - -static int pt_qry_event_tip_pge(struct pt_event *ev, - const struct pt_query_decoder *decoder) -{ - if (!ev) - return -pte_internal; - - switch (ev->type) { - case ptev_exec_mode: - return pt_qry_event_ip(&ev->variant.exec_mode.ip, ev, decoder); - - default: - break; - } - - return -pte_bad_context; -} - -int pt_qry_decode_tip_pge(struct pt_query_decoder *decoder) -{ - struct pt_event *ev; - int size, errcode; - - if (!decoder) - return -pte_internal; - - size = pt_qry_decode_ip(decoder); - if (size < 0) - return size; - - /* We send the enable event first. This is more convenient for our users - * and does not require them to either store or blindly apply other - * events that might be pending. - * - * We use the consume packet decoder flag to indicate this. - */ - if (!decoder->consume_packet) { - /* This packet signals a standalone enabled event. */ - ev = pt_evq_standalone(&decoder->evq); - if (!ev) - return -pte_internal; - - ev->type = ptev_enabled; - - /* We can't afford having a suppressed IP here. */ - errcode = pt_last_ip_query(&ev->variant.enabled.ip, - &decoder->ip); - if (errcode < 0) - return -pte_bad_packet; - - errcode = pt_qry_event_time(ev, decoder); - if (errcode < 0) - return errcode; - - /* Discard any cached TNT bits. - * - * They should have been consumed at the corresponding disable - * event. If they have not, for whatever reason, discard them - * now so our user does not get out of sync. - */ - pt_tnt_cache_init(&decoder->tnt); - - /* Process pending events next. */ - decoder->consume_packet = 1; - decoder->enabled = 1; - } else { - /* Process any pending events binding to TIP. */ - ev = pt_evq_dequeue(&decoder->evq, evb_tip); - if (ev) { - errcode = pt_qry_event_tip_pge(ev, decoder); - if (errcode < 0) - return errcode; - } - } - - /* We must have an event. Either the initial enable event or one of the - * queued events. - */ - if (!ev) - return -pte_internal; - - /* Publish the event. */ - decoder->event = ev; - - /* Process further pending events. */ - if (pt_evq_pending(&decoder->evq, evb_tip)) - return 0; - - /* We must consume the packet. */ - if (!decoder->consume_packet) - return -pte_internal; - - decoder->consume_packet = 0; - - return pt_qry_consume_tip_pge(decoder, size); -} - -static int pt_qry_consume_tip_pgd(struct pt_query_decoder *decoder, int size) -{ - if (!decoder) - return -pte_internal; - - decoder->enabled = 0; - decoder->pos += size; - return 0; -} - -static int pt_qry_event_tip_pgd(struct pt_event *ev, - const struct pt_query_decoder *decoder) -{ - if (!ev) - return -pte_internal; - - switch (ev->type) { - case ptev_async_branch: { - uint64_t at; - - /* Turn the async branch into an async disable. */ - at = ev->variant.async_branch.from; - - ev->type = ptev_async_disabled; - ev->variant.async_disabled.at = at; - - return pt_qry_event_ip(&ev->variant.async_disabled.ip, ev, - decoder); - } - - case ptev_async_paging: - case ptev_async_vmcs: - case ptev_exec_mode: - /* These events are ordered after the async disable event. It - * is not quite clear what IP to give them. - * - * If we give them the async disable's source IP, we'd make an - * error if the IP is updated when applying the async disable - * event. - * - * If we give them the async disable's destination IP, we'd make - * an error if the IP is not updated when applying the async - * disable event. That's what our decoders do since tracing is - * likely to resume from there. - * - * In all cases, tracing will be disabled when those events are - * applied, so we may as well suppress the IP. - */ - ev->ip_suppressed = 1; - - return 0; - - default: - break; - } - - return -pte_bad_context; -} - -int pt_qry_decode_tip_pgd(struct pt_query_decoder *decoder) -{ - struct pt_event *ev; - int size, errcode; - - if (!decoder) - return -pte_internal; - - size = pt_qry_decode_ip(decoder); - if (size < 0) - return size; - - /* Process any pending events binding to TIP. */ - ev = pt_evq_dequeue(&decoder->evq, evb_tip); - if (ev) { - errcode = pt_qry_event_tip_pgd(ev, decoder); - if (errcode < 0) - return errcode; - } else { - /* This packet signals a standalone disabled event. */ - ev = pt_evq_standalone(&decoder->evq); - if (!ev) - return -pte_internal; - ev->type = ptev_disabled; - - errcode = pt_qry_event_ip(&ev->variant.disabled.ip, ev, - decoder); - if (errcode < 0) - return errcode; - - errcode = pt_qry_event_time(ev, decoder); - if (errcode < 0) - return errcode; - } - - /* We must have an event. Either the initial enable event or one of the - * queued events. - */ - if (!ev) - return -pte_internal; - - /* Publish the event. */ - decoder->event = ev; - - /* Process further pending events. */ - if (pt_evq_pending(&decoder->evq, evb_tip)) - return 0; - - return pt_qry_consume_tip_pgd(decoder, size); -} - -static int pt_qry_consume_fup(struct pt_query_decoder *decoder, int size) -{ - if (!decoder) - return -pte_internal; - - decoder->pos += size; - return 0; -} - -static int scan_for_erratum_bdm70(struct pt_packet_decoder *decoder) -{ - for (;;) { - struct pt_packet packet; - int errcode; - - errcode = pt_pkt_next(decoder, &packet, sizeof(packet)); - if (errcode < 0) { - /* Running out of packets is not an error. */ - if (errcode == -pte_eos) - errcode = 0; - - return errcode; - } - - switch (packet.type) { - default: - /* All other packets cancel our search. - * - * We do not enumerate those packets since we also - * want to include new packets. - */ - return 0; - - case ppt_tip_pge: - /* We found it - the erratum applies. */ - return 1; - - case ppt_pad: - case ppt_tsc: - case ppt_cbr: - case ppt_psbend: - case ppt_pip: - case ppt_mode: - case ppt_vmcs: - case ppt_tma: - case ppt_mtc: - case ppt_cyc: - case ppt_mnt: - /* Intentionally skip a few packets. */ - continue; - } - } -} - -static int check_erratum_bdm70(const uint8_t *pos, - const struct pt_config *config) -{ - struct pt_packet_decoder decoder; - int errcode; - - if (!pos || !config) - return -pte_internal; - - errcode = pt_pkt_decoder_init(&decoder, config); - if (errcode < 0) - return errcode; - - errcode = pt_pkt_sync_set(&decoder, (uint64_t) (pos - config->begin)); - if (errcode >= 0) - errcode = scan_for_erratum_bdm70(&decoder); - - pt_pkt_decoder_fini(&decoder); - return errcode; -} - -int pt_qry_header_fup(struct pt_query_decoder *decoder) -{ - struct pt_packet_ip packet; - int errcode, size; - - if (!decoder) - return -pte_internal; - - size = pt_pkt_read_ip(&packet, decoder->pos, &decoder->config); - if (size < 0) - return size; - - if (decoder->config.errata.bdm70 && !decoder->enabled) { - errcode = check_erratum_bdm70(decoder->pos + size, - &decoder->config); - if (errcode < 0) - return errcode; - - if (errcode) - return pt_qry_consume_fup(decoder, size); - } - - errcode = pt_last_ip_update_ip(&decoder->ip, &packet, &decoder->config); - if (errcode < 0) - return errcode; - - /* Tracing is enabled if we have an IP in the header. */ - if (packet.ipc != pt_ipc_suppressed) - decoder->enabled = 1; - - return pt_qry_consume_fup(decoder, size); -} - -static int pt_qry_event_fup(struct pt_event *ev, - struct pt_query_decoder *decoder) -{ - if (!ev || !decoder) - return -pte_internal; - - switch (ev->type) { - case ptev_overflow: - decoder->consume_packet = 1; - - /* We can't afford having a suppressed IP here. */ - return pt_last_ip_query(&ev->variant.overflow.ip, - &decoder->ip); - - case ptev_tsx: - if (!(ev->variant.tsx.aborted)) - decoder->consume_packet = 1; - - return pt_qry_event_ip(&ev->variant.tsx.ip, ev, decoder); - - case ptev_exstop: - decoder->consume_packet = 1; - - return pt_qry_event_ip(&ev->variant.exstop.ip, ev, decoder); - - case ptev_mwait: - decoder->consume_packet = 1; - - return pt_qry_event_ip(&ev->variant.mwait.ip, ev, decoder); - - case ptev_ptwrite: - decoder->consume_packet = 1; - - return pt_qry_event_ip(&ev->variant.ptwrite.ip, ev, decoder); - - default: - break; - } - - return -pte_internal; -} - -int pt_qry_decode_fup(struct pt_query_decoder *decoder) -{ - struct pt_event *ev; - int size, errcode; - - if (!decoder) - return -pte_internal; - - size = pt_qry_decode_ip(decoder); - if (size < 0) - return size; - - /* Process any pending events binding to FUP. */ - ev = pt_evq_dequeue(&decoder->evq, evb_fup); - if (ev) { - errcode = pt_qry_event_fup(ev, decoder); - if (errcode < 0) - return errcode; - - /* Publish the event. */ - decoder->event = ev; - - /* Process further pending events. */ - if (pt_evq_pending(&decoder->evq, evb_fup)) - return 0; - - /* No further events. - * - * If none of the events consumed the packet, we're done. - */ - if (!decoder->consume_packet) - return 0; - - /* We're done with this packet. Clear the flag we set previously - * and consume it. - */ - decoder->consume_packet = 0; - } else { - /* FUP indicates an async branch event; it binds to TIP. - * - * We do need an IP in this case. - */ - uint64_t ip; - - errcode = pt_last_ip_query(&ip, &decoder->ip); - if (errcode < 0) - return errcode; - - ev = pt_evq_enqueue(&decoder->evq, evb_tip); - if (!ev) - return -pte_nomem; - - ev->type = ptev_async_branch; - ev->variant.async_branch.from = ip; - - errcode = pt_qry_event_time(ev, decoder); - if (errcode < 0) - return errcode; - } - - return pt_qry_consume_fup(decoder, size); -} - -int pt_qry_decode_pip(struct pt_query_decoder *decoder) -{ - struct pt_packet_pip packet; - struct pt_event *event; - int size, errcode; - - if (!decoder) - return -pte_internal; - - size = pt_pkt_read_pip(&packet, decoder->pos, &decoder->config); - if (size < 0) - return size; - - /* Paging events are either standalone or bind to the same TIP packet - * as an in-flight async branch event. - */ - event = pt_evq_find(&decoder->evq, evb_tip, ptev_async_branch); - if (!event) { - event = pt_evq_standalone(&decoder->evq); - if (!event) - return -pte_internal; - event->type = ptev_paging; - event->variant.paging.cr3 = packet.cr3; - event->variant.paging.non_root = packet.nr; - - decoder->event = event; - } else { - event = pt_evq_enqueue(&decoder->evq, evb_tip); - if (!event) - return -pte_nomem; - - event->type = ptev_async_paging; - event->variant.async_paging.cr3 = packet.cr3; - event->variant.async_paging.non_root = packet.nr; - } - - errcode = pt_qry_event_time(event, decoder); - if (errcode < 0) - return errcode; - - decoder->pos += size; - return 0; -} - -int pt_qry_header_pip(struct pt_query_decoder *decoder) -{ - struct pt_packet_pip packet; - struct pt_event *event; - int size; - - if (!decoder) - return -pte_internal; - - size = pt_pkt_read_pip(&packet, decoder->pos, &decoder->config); - if (size < 0) - return size; - - /* Paging events are reported at the end of the PSB. */ - event = pt_evq_enqueue(&decoder->evq, evb_psbend); - if (!event) - return -pte_nomem; - - event->type = ptev_async_paging; - event->variant.async_paging.cr3 = packet.cr3; - event->variant.async_paging.non_root = packet.nr; - - decoder->pos += size; - return 0; -} - -static int pt_qry_event_psbend(struct pt_event *ev, - struct pt_query_decoder *decoder) -{ - int errcode; - - if (!ev || !decoder) - return -pte_internal; - - /* PSB+ events are status updates. */ - ev->status_update = 1; - - errcode = pt_qry_event_time(ev, decoder); - if (errcode < 0) - return errcode; - - switch (ev->type) { - case ptev_async_paging: - return pt_qry_event_ip(&ev->variant.async_paging.ip, ev, - decoder); - - case ptev_exec_mode: - return pt_qry_event_ip(&ev->variant.exec_mode.ip, ev, decoder); - - case ptev_tsx: - return pt_qry_event_ip(&ev->variant.tsx.ip, ev, decoder); - - case ptev_async_vmcs: - return pt_qry_event_ip(&ev->variant.async_vmcs.ip, ev, - decoder); - - case ptev_cbr: - return 0; - - case ptev_mnt: - /* Maintenance packets may appear anywhere. Do not mark them as - * status updates even if they appear in PSB+. - */ - ev->status_update = 0; - return 0; - - default: - break; - } - - return -pte_internal; -} - -static int pt_qry_process_pending_psb_events(struct pt_query_decoder *decoder) -{ - struct pt_event *ev; - int errcode; - - if (!decoder) - return -pte_internal; - - ev = pt_evq_dequeue(&decoder->evq, evb_psbend); - if (!ev) - return 0; - - errcode = pt_qry_event_psbend(ev, decoder); - if (errcode < 0) - return errcode; - - /* Publish the event. */ - decoder->event = ev; - - /* Signal a pending event. */ - return 1; -} - -/* Create a standalone overflow event with tracing disabled. - * - * Creates and published the event and disables tracing in @decoder. - * - * Returns zero on success, a negative pt_error_code otherwise. - */ -static int pt_qry_event_ovf_disabled(struct pt_query_decoder *decoder) -{ - struct pt_event *ev; - - if (!decoder) - return -pte_internal; - - ev = pt_evq_standalone(&decoder->evq); - if (!ev) - return -pte_internal; - - ev->type = ptev_overflow; - - /* We suppress the IP to indicate that tracing has been disabled before - * the overflow resolved. There can be several events before tracing is - * enabled again. - */ - ev->ip_suppressed = 1; - - decoder->enabled = 0; - decoder->event = ev; - - return pt_qry_event_time(ev, decoder); -} - -/* Queues an overflow event with tracing enabled. - * - * Creates and enqueues the event and enables tracing in @decoder. - * - * Returns zero on success, a negative pt_error_code otherwise. - */ -static int pt_qry_event_ovf_enabled(struct pt_query_decoder *decoder) -{ - struct pt_event *ev; - - if (!decoder) - return -pte_internal; - - ev = pt_evq_enqueue(&decoder->evq, evb_fup); - if (!ev) - return -pte_internal; - - ev->type = ptev_overflow; - - decoder->enabled = 1; - - return pt_qry_event_time(ev, decoder); -} - -/* Recover from SKD010. - * - * Creates and publishes an overflow event at @packet's IP payload. - * - * Further updates @decoder as follows: - * - * - set time tracking to @time and @tcal - * - set the position to @offset - * - set ip to @packet's IP payload - * - set tracing to be enabled - * - * Returns zero on success, a negative error code otherwise. - */ -static int skd010_recover(struct pt_query_decoder *decoder, - const struct pt_packet_ip *packet, - const struct pt_time_cal *tcal, - const struct pt_time *time, uint64_t offset) -{ - struct pt_last_ip ip; - struct pt_event *ev; - int errcode; - - if (!decoder || !packet || !tcal || !time) - return -pte_internal; - - /* We use the decoder's IP. It should be newly initialized. */ - ip = decoder->ip; - - /* Extract the IP payload from the packet. */ - errcode = pt_last_ip_update_ip(&ip, packet, &decoder->config); - if (errcode < 0) - return errcode; - - /* Synthesize the overflow event. */ - ev = pt_evq_standalone(&decoder->evq); - if (!ev) - return -pte_internal; - - ev->type = ptev_overflow; - - /* We do need a full IP. */ - errcode = pt_last_ip_query(&ev->variant.overflow.ip, &ip); - if (errcode < 0) - return -pte_bad_context; - - /* We continue decoding at the given offset. */ - decoder->pos = decoder->config.begin + offset; - - /* Tracing is enabled. */ - decoder->enabled = 1; - decoder->ip = ip; - - decoder->time = *time; - decoder->tcal = *tcal; - - /* Publish the event. */ - decoder->event = ev; - - return pt_qry_event_time(ev, decoder); -} - -/* Recover from SKD010 with tracing disabled. - * - * Creates and publishes a standalone overflow event. - * - * Further updates @decoder as follows: - * - * - set time tracking to @time and @tcal - * - set the position to @offset - * - set tracing to be disabled - * - * Returns zero on success, a negative error code otherwise. - */ -static int skd010_recover_disabled(struct pt_query_decoder *decoder, - const struct pt_time_cal *tcal, - const struct pt_time *time, uint64_t offset) -{ - if (!decoder || !tcal || !time) - return -pte_internal; - - decoder->time = *time; - decoder->tcal = *tcal; - - /* We continue decoding at the given offset. */ - decoder->pos = decoder->config.begin + offset; - - return pt_qry_event_ovf_disabled(decoder); -} - -/* Scan ahead for a packet at which to resume after an overflow. - * - * This function is called after an OVF without a corresponding FUP. This - * normally means that the overflow resolved while tracing was disabled. - * - * With erratum SKD010 it might also mean that the FUP (or TIP.PGE) was dropped. - * The overflow thus resolved while tracing was enabled (or tracing was enabled - * after the overflow resolved). Search for an indication whether tracing is - * enabled or disabled by scanning upcoming packets. - * - * If we can confirm that tracing is disabled, the erratum does not apply and we - * can continue normally. - * - * If we can confirm that tracing is enabled, the erratum applies and we try to - * recover by synchronizing at a later packet and a different IP. If we can't - * recover, pretend the erratum didn't apply so we run into the error later. - * Since this assumes that tracing is disabled, no harm should be done, i.e. no - * bad trace should be generated. - * - * Returns zero if the overflow is handled. - * Returns a positive value if the overflow is not yet handled. - * Returns a negative error code otherwise. - */ -static int skd010_scan_for_ovf_resume(struct pt_packet_decoder *pkt, - struct pt_query_decoder *decoder) -{ - struct pt_time_cal tcal; - struct pt_time time; - struct { - struct pt_time_cal tcal; - struct pt_time time; - uint64_t offset; - } mode_tsx; - int errcode; - - if (!decoder) - return -pte_internal; - - /* Keep track of time as we skip packets. */ - time = decoder->time; - tcal = decoder->tcal; - - /* Keep track of a potential recovery point at MODE.TSX. */ - memset(&mode_tsx, 0, sizeof(mode_tsx)); - - for (;;) { - struct pt_packet packet; - uint64_t offset; - - errcode = pt_pkt_get_offset(pkt, &offset); - if (errcode < 0) - return errcode; - - errcode = pt_pkt_next(pkt, &packet, sizeof(packet)); - if (errcode < 0) { - /* Let's assume the trace is correct if we run out - * of packets. - */ - if (errcode == -pte_eos) - errcode = 1; - - return errcode; - } - - switch (packet.type) { - case ppt_tip_pge: - /* Everything is fine. There is nothing to do. */ - return 1; - - case ppt_tip_pgd: - /* This is a clear indication that the erratum - * applies. - * - * We synchronize after the disable. - */ - return skd010_recover_disabled(decoder, &tcal, &time, - offset + packet.size); - - case ppt_tnt_8: - case ppt_tnt_64: - /* This is a clear indication that the erratum - * apllies. - * - * Yet, we can't recover from it as we wouldn't know how - * many TNT bits will have been used when we eventually - * find an IP packet at which to resume tracing. - */ - return 1; - - case ppt_pip: - case ppt_vmcs: - /* We could track those changes and synthesize extra - * events after the overflow event when recovering from - * the erratum. This requires infrastructure that we - * don't currently have, though, so we're not going to - * do it. - * - * Instead, we ignore those changes. We already don't - * know how many other changes were lost in the - * overflow. - */ - break; - - case ppt_mode: - switch (packet.payload.mode.leaf) { - case pt_mol_exec: - /* A MODE.EXEC packet binds to TIP, i.e. - * - * TIP.PGE: everything is fine - * TIP: the erratum applies - * - * In the TIP.PGE case, we may just follow the - * normal code flow. - * - * In the TIP case, we'd be able to re-sync at - * the TIP IP but have to skip packets up to and - * including the TIP. - * - * We'd need to synthesize the MODE.EXEC event - * after the overflow event when recovering at - * the TIP. We lack the infrastructure for this - * - it's getting too complicated. - * - * Instead, we ignore the execution mode change; - * we already don't know how many more such - * changes were lost in the overflow. - */ - break; - - case pt_mol_tsx: - /* A MODE.TSX packet may be standalone or bind - * to FUP. - * - * If this is the second MODE.TSX, we're sure - * that tracing is disabled and everything is - * fine. - */ - if (mode_tsx.offset) - return 1; - - /* If we find the FUP this packet binds to, we - * may recover at the FUP IP and restart - * processing packets from here. Remember the - * current state. - */ - mode_tsx.offset = offset; - mode_tsx.time = time; - mode_tsx.tcal = tcal; - - break; - } - - break; - - case ppt_fup: - /* This is a pretty good indication that tracing - * is indeed enabled and the erratum applies. - */ - - /* If we got a MODE.TSX packet before, we synchronize at - * the FUP IP but continue decoding packets starting - * from the MODE.TSX. - */ - if (mode_tsx.offset) - return skd010_recover(decoder, - &packet.payload.ip, - &mode_tsx.tcal, - &mode_tsx.time, - mode_tsx.offset); - - /* Without a preceding MODE.TSX, this FUP is the start - * of an async branch or disable. We synchronize at the - * FUP IP and continue decoding packets from here. - */ - return skd010_recover(decoder, &packet.payload.ip, - &tcal, &time, offset); - - case ppt_tip: - /* We syhchronize at the TIP IP and continue decoding - * packets after the TIP packet. - */ - return skd010_recover(decoder, &packet.payload.ip, - &tcal, &time, - offset + packet.size); - - case ppt_psb: - /* We reached a synchronization point. Tracing is - * enabled if and only if the PSB+ contains a FUP. - */ - errcode = pt_qry_find_header_fup(&packet, pkt); - if (errcode < 0) { - /* If we ran out of packets, we can't tell. - * Let's assume the trace is correct. - */ - if (errcode == -pte_eos) - errcode = 1; - - return errcode; - } - - /* If there is no FUP, tracing is disabled and - * everything is fine. - */ - if (!errcode) - return 1; - - /* We should have a FUP. */ - if (packet.type != ppt_fup) - return -pte_internal; - - /* Otherwise, we may synchronize at the FUP IP and - * continue decoding packets at the PSB. - */ - return skd010_recover(decoder, &packet.payload.ip, - &tcal, &time, offset); - - case ppt_psbend: - /* We shouldn't see this. */ - return -pte_bad_context; - - case ppt_ovf: - case ppt_stop: - /* It doesn't matter if it had been enabled or disabled - * before. We may resume normally. - */ - return 1; - - case ppt_unknown: - case ppt_invalid: - /* We can't skip this packet. */ - return 1; - - case ppt_pad: - case ppt_mnt: - case ppt_pwre: - case ppt_pwrx: - /* Ignore this packet. */ - break; - - case ppt_exstop: - /* We may skip a stand-alone EXSTOP. */ - if (!packet.payload.exstop.ip) - break; - - fallthrough; - case ppt_mwait: - /* To skip this packet, we'd need to take care of the - * FUP it binds to. This is getting complicated. - */ - return 1; - - case ppt_ptw: - /* We may skip a stand-alone PTW. */ - if (!packet.payload.ptw.ip) - break; - - /* To skip this packet, we'd need to take care of the - * FUP it binds to. This is getting complicated. - */ - return 1; - - case ppt_tsc: - /* Keep track of time. */ - errcode = pt_qry_apply_tsc(&time, &tcal, - &packet.payload.tsc, - &decoder->config); - if (errcode < 0) - return errcode; - - break; - - case ppt_cbr: - /* Keep track of time. */ - errcode = pt_qry_apply_cbr(&time, &tcal, - &packet.payload.cbr, - &decoder->config); - if (errcode < 0) - return errcode; - - break; - - case ppt_tma: - /* Keep track of time. */ - errcode = pt_qry_apply_tma(&time, &tcal, - &packet.payload.tma, - &decoder->config); - if (errcode < 0) - return errcode; - - break; - - case ppt_mtc: - /* Keep track of time. */ - errcode = pt_qry_apply_mtc(&time, &tcal, - &packet.payload.mtc, - &decoder->config); - if (errcode < 0) - return errcode; - - break; - - case ppt_cyc: - /* Keep track of time. */ - errcode = pt_qry_apply_cyc(&time, &tcal, - &packet.payload.cyc, - &decoder->config); - if (errcode < 0) - return errcode; - - break; - } - } -} - -static int pt_qry_handle_skd010(struct pt_query_decoder *decoder) -{ - struct pt_packet_decoder pkt; - uint64_t offset; - int errcode; - - if (!decoder) - return -pte_internal; - - errcode = pt_qry_get_offset(decoder, &offset); - if (errcode < 0) - return errcode; - - errcode = pt_pkt_decoder_init(&pkt, &decoder->config); - if (errcode < 0) - return errcode; - - errcode = pt_pkt_sync_set(&pkt, offset); - if (errcode >= 0) - errcode = skd010_scan_for_ovf_resume(&pkt, decoder); - - pt_pkt_decoder_fini(&pkt); - return errcode; -} - -/* Scan ahead for an indication whether tracing is enabled or disabled. - * - * Returns zero if tracing is clearly disabled. - * Returns a positive integer if tracing is enabled or if we can't tell. - * Returns a negative error code otherwise. - */ -static int apl12_tracing_is_disabled(struct pt_packet_decoder *decoder) -{ - if (!decoder) - return -pte_internal; - - for (;;) { - struct pt_packet packet; - int status; - - status = pt_pkt_next(decoder, &packet, sizeof(packet)); - if (status < 0) { - /* Running out of packets is not an error. */ - if (status == -pte_eos) - status = 1; - - return status; - } - - switch (packet.type) { - default: - /* Skip other packets. */ - break; - - case ppt_stop: - /* Tracing is disabled before a stop. */ - return 0; - - case ppt_tip_pge: - /* Tracing gets enabled - it must have been disabled. */ - return 0; - - case ppt_tnt_8: - case ppt_tnt_64: - case ppt_tip: - case ppt_tip_pgd: - /* Those packets are only generated when tracing is - * enabled. We're done. - */ - return 1; - - case ppt_psb: - /* We reached a synchronization point. Tracing is - * enabled if and only if the PSB+ contains a FUP. - */ - status = pt_qry_find_header_fup(&packet, decoder); - - /* If we ran out of packets, we can't tell. */ - if (status == -pte_eos) - status = 1; - - return status; - - case ppt_psbend: - /* We shouldn't see this. */ - return -pte_bad_context; - - case ppt_ovf: - /* It doesn't matter - we run into the next overflow. */ - return 1; - - case ppt_unknown: - case ppt_invalid: - /* We can't skip this packet. */ - return 1; - } - } -} - -/* Apply workaround for erratum APL12. - * - * We resume from @offset (relative to @decoder->pos) with tracing disabled. On - * our way to the resume location we process packets to update our state. - * - * Any event will be dropped. - * - * Returns zero on success, a negative pt_error_code otherwise. - */ -static int apl12_resume_disabled(struct pt_query_decoder *decoder, - struct pt_packet_decoder *pkt, - unsigned int offset) -{ - uint64_t begin, end; - int errcode; - - if (!decoder) - return -pte_internal; - - errcode = pt_qry_get_offset(decoder, &begin); - if (errcode < 0) - return errcode; - - errcode = pt_pkt_sync_set(pkt, begin); - if (errcode < 0) - return errcode; - - end = begin + offset; - for (;;) { - struct pt_packet packet; - uint64_t next; - - errcode = pt_pkt_next(pkt, &packet, sizeof(packet)); - if (errcode < 0) { - /* Running out of packets is not an error. */ - if (errcode == -pte_eos) - errcode = 0; - - return errcode; - } - - /* The offset is the start of the next packet. */ - errcode = pt_pkt_get_offset(pkt, &next); - if (errcode < 0) - return errcode; - - /* We're done when we reach @offset. - * - * The current @packet will be the FUP after which we started - * our search. We skip it. - * - * Check that we're not accidentally proceeding past @offset. - */ - if (end <= next) { - if (end < next) - return -pte_internal; - - break; - } - - switch (packet.type) { - default: - /* Skip other packets. */ - break; - - case ppt_mode: - case ppt_pip: - case ppt_vmcs: - /* We should not encounter those. - * - * We should not encounter a lot of packets but those - * are state-relevant; let's check them explicitly. - */ - return -pte_internal; - - case ppt_tsc: - /* Keep track of time. */ - errcode = pt_qry_apply_tsc(&decoder->time, - &decoder->tcal, - &packet.payload.tsc, - &decoder->config); - if (errcode < 0) - return errcode; - - break; - - case ppt_cbr: - /* Keep track of time. */ - errcode = pt_qry_apply_cbr(&decoder->time, - &decoder->tcal, - &packet.payload.cbr, - &decoder->config); - if (errcode < 0) - return errcode; - - break; - - case ppt_tma: - /* Keep track of time. */ - errcode = pt_qry_apply_tma(&decoder->time, - &decoder->tcal, - &packet.payload.tma, - &decoder->config); - if (errcode < 0) - return errcode; - - break; - - case ppt_mtc: - /* Keep track of time. */ - errcode = pt_qry_apply_mtc(&decoder->time, - &decoder->tcal, - &packet.payload.mtc, - &decoder->config); - if (errcode < 0) - return errcode; - - break; - - case ppt_cyc: - /* Keep track of time. */ - errcode = pt_qry_apply_cyc(&decoder->time, - &decoder->tcal, - &packet.payload.cyc, - &decoder->config); - if (errcode < 0) - return errcode; - - break; - } - } - - decoder->pos += offset; - - return pt_qry_event_ovf_disabled(decoder); -} - -/* Handle erratum APL12. - * - * This function is called when a FUP is found after an OVF. The @offset - * argument gives the relative offset from @decoder->pos to after the FUP. - * - * A FUP after OVF normally indicates that the overflow resolved while tracing - * is enabled. Due to erratum APL12, however, the overflow may have resolved - * while tracing is disabled and still generate a FUP. - * - * We scan ahead for an indication whether tracing is actually disabled. If we - * find one, the erratum applies and we proceed from after the FUP packet. - * - * This will drop any CBR or MTC events. We will update @decoder's timing state - * on CBR but drop the event. - * - * Returns zero if the erratum was handled. - * Returns a positive integer if the erratum was not handled. - * Returns a negative pt_error_code otherwise. - */ -static int pt_qry_handle_apl12(struct pt_query_decoder *decoder, - unsigned int offset) -{ - struct pt_packet_decoder pkt; - uint64_t here; - int status; - - if (!decoder) - return -pte_internal; - - status = pt_qry_get_offset(decoder, &here); - if (status < 0) - return status; - - status = pt_pkt_decoder_init(&pkt, &decoder->config); - if (status < 0) - return status; - - status = pt_pkt_sync_set(&pkt, here + offset); - if (status >= 0) { - status = apl12_tracing_is_disabled(&pkt); - if (!status) - status = apl12_resume_disabled(decoder, &pkt, offset); - } - - pt_pkt_decoder_fini(&pkt); - return status; -} - -/* Apply workaround for erratum APL11. - * - * We search for a TIP.PGD and, if we found one, resume from after that packet - * with tracing disabled. On our way to the resume location we process packets - * to update our state. - * - * If we don't find a TIP.PGD but instead some other packet that indicates that - * tracing is disabled, indicate that the erratum does not apply. - * - * Any event will be dropped. - * - * Returns zero if the erratum was handled. - * Returns a positive integer if the erratum was not handled. - * Returns a negative pt_error_code otherwise. - */ -static int apl11_apply(struct pt_query_decoder *decoder, - struct pt_packet_decoder *pkt) -{ - struct pt_time_cal tcal; - struct pt_time time; - - if (!decoder) - return -pte_internal; - - time = decoder->time; - tcal = decoder->tcal; - for (;;) { - struct pt_packet packet; - int errcode; - - errcode = pt_pkt_next(pkt, &packet, sizeof(packet)); - if (errcode < 0) - return errcode; - - switch (packet.type) { - case ppt_tip_pgd: { - uint64_t offset; - - /* We found a TIP.PGD. The erratum applies. - * - * Resume from here with tracing disabled. - */ - errcode = pt_pkt_get_offset(pkt, &offset); - if (errcode < 0) - return errcode; - - decoder->time = time; - decoder->tcal = tcal; - decoder->pos = decoder->config.begin + offset; - - return pt_qry_event_ovf_disabled(decoder); - } - - case ppt_invalid: - return -pte_bad_opc; - - case ppt_fup: - case ppt_psb: - case ppt_tip_pge: - case ppt_stop: - case ppt_ovf: - case ppt_mode: - case ppt_pip: - case ppt_vmcs: - case ppt_exstop: - case ppt_mwait: - case ppt_pwre: - case ppt_pwrx: - case ppt_ptw: - /* The erratum does not apply. */ - return 1; - - case ppt_unknown: - case ppt_pad: - case ppt_mnt: - /* Skip those packets. */ - break; - - case ppt_psbend: - case ppt_tip: - case ppt_tnt_8: - case ppt_tnt_64: - return -pte_bad_context; - - - case ppt_tsc: - /* Keep track of time. */ - errcode = pt_qry_apply_tsc(&time, &tcal, - &packet.payload.tsc, - &decoder->config); - if (errcode < 0) - return errcode; - - break; - - case ppt_cbr: - /* Keep track of time. */ - errcode = pt_qry_apply_cbr(&time, &tcal, - &packet.payload.cbr, - &decoder->config); - if (errcode < 0) - return errcode; - - break; - - case ppt_tma: - /* Keep track of time. */ - errcode = pt_qry_apply_tma(&time, &tcal, - &packet.payload.tma, - &decoder->config); - if (errcode < 0) - return errcode; - - break; - - case ppt_mtc: - /* Keep track of time. */ - errcode = pt_qry_apply_mtc(&time, &tcal, - &packet.payload.mtc, - &decoder->config); - if (errcode < 0) - return errcode; - - break; - - case ppt_cyc: - /* Keep track of time. */ - errcode = pt_qry_apply_cyc(&time, &tcal, - &packet.payload.cyc, - &decoder->config); - if (errcode < 0) - return errcode; - - break; - } - } -} - -/* Handle erratum APL11. - * - * This function is called when we diagnose a bad packet while searching for a - * FUP after an OVF. - * - * Due to erratum APL11 we may get an extra TIP.PGD after the OVF. Find that - * TIP.PGD and resume from there with tracing disabled. - * - * This will drop any CBR or MTC events. We will update @decoder's timing state - * on CBR but drop the event. - * - * Returns zero if the erratum was handled. - * Returns a positive integer if the erratum was not handled. - * Returns a negative pt_error_code otherwise. - */ -static int pt_qry_handle_apl11(struct pt_query_decoder *decoder) -{ - struct pt_packet_decoder pkt; - uint64_t offset; - int status; - - if (!decoder) - return -pte_internal; - - status = pt_qry_get_offset(decoder, &offset); - if (status < 0) - return status; - - status = pt_pkt_decoder_init(&pkt, &decoder->config); - if (status < 0) - return status; - - status = pt_pkt_sync_set(&pkt, offset); - if (status >= 0) - status = apl11_apply(decoder, &pkt); - - pt_pkt_decoder_fini(&pkt); - return status; -} - -static int pt_pkt_find_ovf_fup(struct pt_packet_decoder *decoder) -{ - for (;;) { - struct pt_packet packet; - int errcode; - - errcode = pt_pkt_next(decoder, &packet, sizeof(packet)); - if (errcode < 0) - return errcode; - - switch (packet.type) { - case ppt_fup: - return 1; - - case ppt_invalid: - return -pte_bad_opc; - - case ppt_unknown: - case ppt_pad: - case ppt_mnt: - case ppt_cbr: - case ppt_tsc: - case ppt_tma: - case ppt_mtc: - case ppt_cyc: - continue; - - case ppt_psb: - case ppt_tip_pge: - case ppt_mode: - case ppt_pip: - case ppt_vmcs: - case ppt_stop: - case ppt_ovf: - case ppt_exstop: - case ppt_mwait: - case ppt_pwre: - case ppt_pwrx: - case ppt_ptw: - return 0; - - case ppt_psbend: - case ppt_tip: - case ppt_tip_pgd: - case ppt_tnt_8: - case ppt_tnt_64: - return -pte_bad_context; - } - } -} - -/* Find a FUP to which the current OVF may bind. - * - * Scans the trace for a FUP or for a packet that indicates that tracing is - * disabled. - * - * Return the relative offset of the packet following the found FUP on success. - * Returns zero if no FUP is found and tracing is assumed to be disabled. - * Returns a negative pt_error_code otherwise. - */ -static int pt_qry_find_ovf_fup(const struct pt_query_decoder *decoder) -{ - struct pt_packet_decoder pkt; - uint64_t begin, end, offset; - int status; - - if (!decoder) - return -pte_internal; - - status = pt_qry_get_offset(decoder, &begin); - if (status < 0) - return status; - - status = pt_pkt_decoder_init(&pkt, &decoder->config); - if (status < 0) - return status; - - status = pt_pkt_sync_set(&pkt, begin); - if (status >= 0) { - status = pt_pkt_find_ovf_fup(&pkt); - if (status > 0) { - status = pt_pkt_get_offset(&pkt, &end); - if (status < 0) - return status; - - if (end <= begin) - return -pte_overflow; - - offset = end - begin; - if (INT_MAX < offset) - return -pte_overflow; - - status = (int) offset; - } - } - - pt_pkt_decoder_fini(&pkt); - return status; -} - -int pt_qry_decode_ovf(struct pt_query_decoder *decoder) -{ - struct pt_time time; - int status, offset; - - if (!decoder) - return -pte_internal; - - status = pt_qry_process_pending_psb_events(decoder); - if (status < 0) - return status; - - /* If we have any pending psbend events, we're done for now. */ - if (status) - return 0; - - /* Reset the decoder state but preserve timing. */ - time = decoder->time; - pt_qry_reset(decoder); - decoder->time = time; - - /* We must consume the OVF before we search for the binding packet. */ - decoder->pos += ptps_ovf; - - /* Overflow binds to either FUP or TIP.PGE. - * - * If the overflow can be resolved while PacketEn=1 it binds to FUP. We - * can see timing packets between OVF anf FUP but that's it. - * - * Otherwise, PacketEn will be zero when the overflow resolves and OVF - * binds to TIP.PGE. There can be packets between OVF and TIP.PGE that - * do not depend on PacketEn. - * - * We don't need to decode everything until TIP.PGE, however. As soon - * as we see a non-timing non-FUP packet, we know that tracing has been - * disabled before the overflow resolves. - */ - offset = pt_qry_find_ovf_fup(decoder); - if (offset <= 0) { - /* Check for erratum SKD010. - * - * The FUP may have been dropped. If we can figure out that - * tracing is enabled and hence the FUP is missing, we resume - * at a later packet and a different IP. - */ - if (decoder->config.errata.skd010) { - status = pt_qry_handle_skd010(decoder); - if (status <= 0) - return status; - } - - /* Check for erratum APL11. - * - * We may have gotten an extra TIP.PGD, which should be - * diagnosed by our search for a subsequent FUP. - */ - if (decoder->config.errata.apl11 && - (offset == -pte_bad_context)) { - status = pt_qry_handle_apl11(decoder); - if (status <= 0) - return status; - } - - /* Report the original error from searching for the FUP packet - * if we were not able to fix the trace. - * - * We treat an overflow at the end of the trace as standalone. - */ - if (offset < 0 && offset != -pte_eos) - return offset; - - return pt_qry_event_ovf_disabled(decoder); - } else { - /* Check for erratum APL12. - * - * We may get an extra FUP even though the overflow resolved - * with tracing disabled. - */ - if (decoder->config.errata.apl12) { - status = pt_qry_handle_apl12(decoder, - (unsigned int) offset); - if (status <= 0) - return status; - } - - return pt_qry_event_ovf_enabled(decoder); - } -} - -static int pt_qry_decode_mode_exec(struct pt_query_decoder *decoder, - const struct pt_packet_mode_exec *packet) -{ - struct pt_event *event; - - if (!decoder || !packet) - return -pte_internal; - - /* MODE.EXEC binds to TIP. */ - event = pt_evq_enqueue(&decoder->evq, evb_tip); - if (!event) - return -pte_nomem; - - event->type = ptev_exec_mode; - event->variant.exec_mode.mode = pt_get_exec_mode(packet); - - return pt_qry_event_time(event, decoder); -} - -static int pt_qry_decode_mode_tsx(struct pt_query_decoder *decoder, - const struct pt_packet_mode_tsx *packet) -{ - struct pt_event *event; - - if (!decoder || !packet) - return -pte_internal; - - /* MODE.TSX is standalone if tracing is disabled. */ - if (!decoder->enabled) { - event = pt_evq_standalone(&decoder->evq); - if (!event) - return -pte_internal; - - /* We don't have an IP in this case. */ - event->variant.tsx.ip = 0; - event->ip_suppressed = 1; - - /* Publish the event. */ - decoder->event = event; - } else { - /* MODE.TSX binds to FUP. */ - event = pt_evq_enqueue(&decoder->evq, evb_fup); - if (!event) - return -pte_nomem; - } - - event->type = ptev_tsx; - event->variant.tsx.speculative = packet->intx; - event->variant.tsx.aborted = packet->abrt; - - return pt_qry_event_time(event, decoder); -} - -int pt_qry_decode_mode(struct pt_query_decoder *decoder) -{ - struct pt_packet_mode packet; - int size, errcode; - - if (!decoder) - return -pte_internal; - - size = pt_pkt_read_mode(&packet, decoder->pos, &decoder->config); - if (size < 0) - return size; - - errcode = 0; - switch (packet.leaf) { - case pt_mol_exec: - errcode = pt_qry_decode_mode_exec(decoder, &packet.bits.exec); - break; - - case pt_mol_tsx: - errcode = pt_qry_decode_mode_tsx(decoder, &packet.bits.tsx); - break; - } - - if (errcode < 0) - return errcode; - - decoder->pos += size; - return 0; -} - -int pt_qry_header_mode(struct pt_query_decoder *decoder) -{ - struct pt_packet_mode packet; - struct pt_event *event; - int size; - - if (!decoder) - return -pte_internal; - - size = pt_pkt_read_mode(&packet, decoder->pos, &decoder->config); - if (size < 0) - return size; - - /* Inside the header, events are reported at the end. */ - event = pt_evq_enqueue(&decoder->evq, evb_psbend); - if (!event) - return -pte_nomem; - - switch (packet.leaf) { - case pt_mol_exec: - event->type = ptev_exec_mode; - event->variant.exec_mode.mode = - pt_get_exec_mode(&packet.bits.exec); - break; - - case pt_mol_tsx: - event->type = ptev_tsx; - event->variant.tsx.speculative = packet.bits.tsx.intx; - event->variant.tsx.aborted = packet.bits.tsx.abrt; - break; - } - - decoder->pos += size; - return 0; -} - -int pt_qry_decode_psbend(struct pt_query_decoder *decoder) -{ - int status; - - if (!decoder) - return -pte_internal; - - status = pt_qry_process_pending_psb_events(decoder); - if (status < 0) - return status; - - /* If we had any psb events, we're done for now. */ - if (status) - return 0; - - /* Skip the psbend extended opcode that we fetched before if no more - * psbend events are pending. - */ - decoder->pos += ptps_psbend; - return 0; -} - -int pt_qry_decode_tsc(struct pt_query_decoder *decoder) -{ - struct pt_packet_tsc packet; - int size, errcode; - - if (!decoder) - return -pte_internal; - - size = pt_pkt_read_tsc(&packet, decoder->pos, &decoder->config); - if (size < 0) - return size; - - errcode = pt_qry_apply_tsc(&decoder->time, &decoder->tcal, - &packet, &decoder->config); - if (errcode < 0) - return errcode; - - decoder->pos += size; - return 0; -} - -int pt_qry_header_tsc(struct pt_query_decoder *decoder) -{ - struct pt_packet_tsc packet; - int size, errcode; - - if (!decoder) - return -pte_internal; - - size = pt_pkt_read_tsc(&packet, decoder->pos, &decoder->config); - if (size < 0) - return size; - - errcode = pt_qry_apply_header_tsc(&decoder->time, &decoder->tcal, - &packet, &decoder->config); - if (errcode < 0) - return errcode; - - decoder->pos += size; - return 0; -} - -int pt_qry_decode_cbr(struct pt_query_decoder *decoder) -{ - struct pt_packet_cbr packet; - struct pt_event *event; - int size, errcode; - - if (!decoder) - return -pte_internal; - - size = pt_pkt_read_cbr(&packet, decoder->pos, &decoder->config); - if (size < 0) - return size; - - errcode = pt_qry_apply_cbr(&decoder->time, &decoder->tcal, - &packet, &decoder->config); - if (errcode < 0) - return errcode; - - event = pt_evq_standalone(&decoder->evq); - if (!event) - return -pte_internal; - - event->type = ptev_cbr; - event->variant.cbr.ratio = packet.ratio; - - decoder->event = event; - - errcode = pt_qry_event_time(event, decoder); - if (errcode < 0) - return errcode; - - decoder->pos += size; - return 0; -} - -int pt_qry_header_cbr(struct pt_query_decoder *decoder) -{ - struct pt_packet_cbr packet; - struct pt_event *event; - int size, errcode; - - if (!decoder) - return -pte_internal; - - size = pt_pkt_read_cbr(&packet, decoder->pos, &decoder->config); - if (size < 0) - return size; - - errcode = pt_qry_apply_header_cbr(&decoder->time, &decoder->tcal, - &packet, &decoder->config); - if (errcode < 0) - return errcode; - - event = pt_evq_enqueue(&decoder->evq, evb_psbend); - if (!event) - return -pte_nomem; - - event->type = ptev_cbr; - event->variant.cbr.ratio = packet.ratio; - - decoder->pos += size; - return 0; -} - -int pt_qry_decode_tma(struct pt_query_decoder *decoder) -{ - struct pt_packet_tma packet; - int size, errcode; - - if (!decoder) - return -pte_internal; - - size = pt_pkt_read_tma(&packet, decoder->pos, &decoder->config); - if (size < 0) { - /** SKZ84: Use of VMX TSC Scaling or TSC Offsetting Will Result - * in Corrupted Intel PT Packets - * - * We cannot detect all kinds of corruption but we can detect - * reserved bits being set. - */ - if (decoder->config.errata.skz84 && - (size == -pte_bad_packet)) { - decoder->pos += ptps_tma + 1; - return 0; - } - - return size; - } - - errcode = pt_qry_apply_tma(&decoder->time, &decoder->tcal, - &packet, &decoder->config); - if (errcode < 0) - return errcode; - - decoder->pos += size; - return 0; -} - -int pt_qry_decode_mtc(struct pt_query_decoder *decoder) -{ - struct pt_packet_mtc packet; - int size, errcode; - - if (!decoder) - return -pte_internal; - - size = pt_pkt_read_mtc(&packet, decoder->pos, &decoder->config); - if (size < 0) - return size; - - errcode = pt_qry_apply_mtc(&decoder->time, &decoder->tcal, - &packet, &decoder->config); - if (errcode < 0) - return errcode; - - decoder->pos += size; - return 0; -} - -static int check_erratum_skd007(struct pt_query_decoder *decoder, - const struct pt_packet_cyc *packet, int size) -{ - const uint8_t *pos; - uint16_t payload; - - if (!decoder || !packet || size < 0) - return -pte_internal; - - /* It must be a 2-byte CYC. */ - if (size != 2) - return 0; - - payload = (uint16_t) packet->value; - - /* The 2nd byte of the CYC payload must look like an ext opcode. */ - if ((payload & ~0x1f) != 0x20) - return 0; - - /* Skip this CYC packet. */ - pos = decoder->pos + size; - if (decoder->config.end <= pos) - return 0; - - /* See if we got a second CYC that looks like an OVF ext opcode. */ - if (*pos != pt_ext_ovf) - return 0; - - /* We shouldn't get back-to-back CYCs unless they are sent when the - * counter wraps around. In this case, we'd expect a full payload. - * - * Since we got two non-full CYC packets, we assume the erratum hit. - */ - - return 1; -} - -int pt_qry_decode_cyc(struct pt_query_decoder *decoder) -{ - struct pt_packet_cyc packet; - struct pt_config *config; - int size, errcode; - - if (!decoder) - return -pte_internal; - - config = &decoder->config; - - size = pt_pkt_read_cyc(&packet, decoder->pos, config); - if (size < 0) - return size; - - if (config->errata.skd007) { - errcode = check_erratum_skd007(decoder, &packet, size); - if (errcode < 0) - return errcode; - - /* If the erratum hits, we ignore the partial CYC and instead - * process the OVF following/overlapping it. - */ - if (errcode) { - /* We skip the first byte of the CYC, which brings us - * to the beginning of the OVF packet. - */ - decoder->pos += 1; - return 0; - } - } - - errcode = pt_qry_apply_cyc(&decoder->time, &decoder->tcal, - &packet, config); - if (errcode < 0) - return errcode; - - decoder->pos += size; - return 0; -} - -int pt_qry_decode_stop(struct pt_query_decoder *decoder) -{ - struct pt_event *event; - int errcode; - - if (!decoder) - return -pte_internal; - - /* Stop events are reported immediately. */ - event = pt_evq_standalone(&decoder->evq); - if (!event) - return -pte_internal; - - event->type = ptev_stop; - - decoder->event = event; - - errcode = pt_qry_event_time(event, decoder); - if (errcode < 0) - return errcode; - - decoder->pos += ptps_stop; - return 0; -} - -int pt_qry_header_vmcs(struct pt_query_decoder *decoder) -{ - struct pt_packet_vmcs packet; - struct pt_event *event; - int size; - - if (!decoder) - return -pte_internal; - - size = pt_pkt_read_vmcs(&packet, decoder->pos, &decoder->config); - if (size < 0) - return size; - - event = pt_evq_enqueue(&decoder->evq, evb_psbend); - if (!event) - return -pte_nomem; - - event->type = ptev_async_vmcs; - event->variant.async_vmcs.base = packet.base; - - decoder->pos += size; - return 0; -} - -int pt_qry_decode_vmcs(struct pt_query_decoder *decoder) -{ - struct pt_packet_vmcs packet; - struct pt_event *event; - int size, errcode; - - if (!decoder) - return -pte_internal; - - size = pt_pkt_read_vmcs(&packet, decoder->pos, &decoder->config); - if (size < 0) - return size; - - /* VMCS events bind to the same IP as an in-flight async paging event. - * - * In that case, the VMCS event should be applied first. We reorder - * events here to simplify the life of higher layers. - */ - event = pt_evq_find(&decoder->evq, evb_tip, ptev_async_paging); - if (event) { - struct pt_event *paging; - - paging = pt_evq_enqueue(&decoder->evq, evb_tip); - if (!paging) - return -pte_nomem; - - *paging = *event; - - event->type = ptev_async_vmcs; - event->variant.async_vmcs.base = packet.base; - - decoder->pos += size; - return 0; - } - - /* VMCS events bind to the same TIP packet as an in-flight async - * branch event. - */ - event = pt_evq_find(&decoder->evq, evb_tip, ptev_async_branch); - if (event) { - event = pt_evq_enqueue(&decoder->evq, evb_tip); - if (!event) - return -pte_nomem; - - event->type = ptev_async_vmcs; - event->variant.async_vmcs.base = packet.base; - - decoder->pos += size; - return 0; - } - - /* VMCS events that do not bind to an in-flight async event are - * stand-alone. - */ - event = pt_evq_standalone(&decoder->evq); - if (!event) - return -pte_internal; - - event->type = ptev_vmcs; - event->variant.vmcs.base = packet.base; - - decoder->event = event; - - errcode = pt_qry_event_time(event, decoder); - if (errcode < 0) - return errcode; - - decoder->pos += size; - return 0; -} - -int pt_qry_decode_mnt(struct pt_query_decoder *decoder) -{ - struct pt_packet_mnt packet; - struct pt_event *event; - int size, errcode; - - if (!decoder) - return -pte_internal; - - size = pt_pkt_read_mnt(&packet, decoder->pos, &decoder->config); - if (size < 0) - return size; - - event = pt_evq_standalone(&decoder->evq); - if (!event) - return -pte_internal; - - event->type = ptev_mnt; - event->variant.mnt.payload = packet.payload; - - decoder->event = event; - - errcode = pt_qry_event_time(event, decoder); - if (errcode < 0) - return errcode; - - decoder->pos += size; - - return 0; -} - -int pt_qry_header_mnt(struct pt_query_decoder *decoder) -{ - struct pt_packet_mnt packet; - struct pt_event *event; - int size; - - if (!decoder) - return -pte_internal; - - size = pt_pkt_read_mnt(&packet, decoder->pos, &decoder->config); - if (size < 0) - return size; - - event = pt_evq_enqueue(&decoder->evq, evb_psbend); - if (!event) - return -pte_nomem; - - event->type = ptev_mnt; - event->variant.mnt.payload = packet.payload; - - decoder->pos += size; - - return 0; -} - -int pt_qry_decode_exstop(struct pt_query_decoder *decoder) -{ - struct pt_packet_exstop packet; - struct pt_event *event; - int size; - - if (!decoder) - return -pte_internal; - - size = pt_pkt_read_exstop(&packet, decoder->pos, &decoder->config); - if (size < 0) - return size; - - if (packet.ip) { - event = pt_evq_enqueue(&decoder->evq, evb_fup); - if (!event) - return -pte_internal; - - event->type = ptev_exstop; - } else { - event = pt_evq_standalone(&decoder->evq); - if (!event) - return -pte_internal; - - event->type = ptev_exstop; - - event->ip_suppressed = 1; - event->variant.exstop.ip = 0ull; - - decoder->event = event; - } - - decoder->pos += size; - return 0; -} - -int pt_qry_decode_mwait(struct pt_query_decoder *decoder) -{ - struct pt_packet_mwait packet; - struct pt_event *event; - int size; - - if (!decoder) - return -pte_internal; - - size = pt_pkt_read_mwait(&packet, decoder->pos, &decoder->config); - if (size < 0) - return size; - - event = pt_evq_enqueue(&decoder->evq, evb_fup); - if (!event) - return -pte_internal; - - event->type = ptev_mwait; - event->variant.mwait.hints = packet.hints; - event->variant.mwait.ext = packet.ext; - - decoder->pos += size; - return 0; -} - -int pt_qry_decode_pwre(struct pt_query_decoder *decoder) -{ - struct pt_packet_pwre packet; - struct pt_event *event; - int size; - - if (!decoder) - return -pte_internal; - - size = pt_pkt_read_pwre(&packet, decoder->pos, &decoder->config); - if (size < 0) - return size; - - event = pt_evq_standalone(&decoder->evq); - if (!event) - return -pte_internal; - - event->type = ptev_pwre; - event->variant.pwre.state = packet.state; - event->variant.pwre.sub_state = packet.sub_state; - - if (packet.hw) - event->variant.pwre.hw = 1; - - decoder->event = event; - - decoder->pos += size; - return 0; -} - -int pt_qry_decode_pwrx(struct pt_query_decoder *decoder) -{ - struct pt_packet_pwrx packet; - struct pt_event *event; - int size; - - if (!decoder) - return -pte_internal; - - size = pt_pkt_read_pwrx(&packet, decoder->pos, &decoder->config); - if (size < 0) - return size; - - event = pt_evq_standalone(&decoder->evq); - if (!event) - return -pte_internal; - - event->type = ptev_pwrx; - event->variant.pwrx.last = packet.last; - event->variant.pwrx.deepest = packet.deepest; - - if (packet.interrupt) - event->variant.pwrx.interrupt = 1; - if (packet.store) - event->variant.pwrx.store = 1; - if (packet.autonomous) - event->variant.pwrx.autonomous = 1; - - decoder->event = event; - - decoder->pos += size; - return 0; -} - -int pt_qry_decode_ptw(struct pt_query_decoder *decoder) -{ - struct pt_packet_ptw packet; - struct pt_event *event; - int size, pls; - - if (!decoder) - return -pte_internal; - - size = pt_pkt_read_ptw(&packet, decoder->pos, &decoder->config); - if (size < 0) - return size; - - pls = pt_ptw_size(packet.plc); - if (pls < 0) - return pls; - - if (packet.ip) { - event = pt_evq_enqueue(&decoder->evq, evb_fup); - if (!event) - return -pte_internal; - } else { - event = pt_evq_standalone(&decoder->evq); - if (!event) - return -pte_internal; - - event->ip_suppressed = 1; - - decoder->event = event; - } - - event->type = ptev_ptwrite; - event->variant.ptwrite.size = (uint8_t) pls; - event->variant.ptwrite.payload = packet.payload; - - decoder->pos += size; - return 0; -}
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/src/pt_retstack.c -> _service:tar_scm:v2.1.tar.gz/libipt/src/pt_retstack.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/src/pt_section.c -> _service:tar_scm:v2.1.tar.gz/libipt/src/pt_section.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -37,37 +38,40 @@ #include <string.h> -static char *dupstr(const char *str) -{ - char *dup; - size_t len; - - if (!str) - return NULL; - - len = strlen(str); - dup = malloc(len + 1); - if (!dup) - return NULL; - - return strcpy(dup, str); -} - -struct pt_section *pt_mk_section(const char *filename, uint64_t offset, - uint64_t size) +int pt_mk_section(struct pt_section **psection, const char *filename, + uint64_t offset, uint64_t size) { struct pt_section *section; uint64_t fsize; + size_t flen; void *status; + char *fname; int errcode; - errcode = pt_section_mk_status(&status, &fsize, filename); + if (!psection) + return -pte_internal; + + flen = strnlen(filename, FILENAME_MAX); + if (FILENAME_MAX <= flen) + return -pte_invalid; + + flen += 1; + + fname = malloc(flen); + if (!fname) + return -pte_nomem; + + memcpy(fname, filename, flen); + + errcode = pt_section_mk_status(&status, &fsize, fname); if (errcode < 0) - return NULL; + goto out_fname; /* Fail if the requested @offset lies beyond the end of @file. */ - if (fsize <= offset) + if (fsize <= offset) { + errcode = -pte_invalid; goto out_status; + } /* Truncate @size so the entire range lies within @file. */ fsize -= offset; @@ -75,12 +79,14 @@ size = fsize; section = malloc(sizeof(*section)); - if (!section) + if (!section) { + errcode = -pte_nomem; goto out_status; + } memset(section, 0, sizeof(*section)); - section->filename = dupstr(filename); + section->filename = fname; section->status = status; section->offset = offset; section->size = size; @@ -90,26 +96,32 @@ errcode = mtx_init(§ion->lock, mtx_plain); if (errcode != thrd_success) { - free(section->filename); free(section); + + errcode = -pte_bad_lock; goto out_status; } errcode = mtx_init(§ion->alock, mtx_plain); if (errcode != thrd_success) { mtx_destroy(§ion->lock); - free(section->filename); free(section); + + errcode = -pte_bad_lock; goto out_status; } #endif /* defined(FEATURE_THREADS) */ - return section; + *psection = section; + return 0; out_status: free(status); - return NULL; + +out_fname: + free(fname); + return errcode; } int pt_section_lock(struct pt_section *section) @@ -257,7 +269,7 @@ int pt_section_attach(struct pt_section *section, struct pt_image_section_cache *iscache) { - uint16_t acount, ucount; + uint16_t acount; int errcode; if (!section || !iscache) @@ -267,10 +279,25 @@ if (errcode < 0) return errcode; - ucount = section->ucount; acount = section->acount; if (!acount) { - if (section->iscache || !ucount) + if (section->iscache) { + errcode = -pte_internal; + goto out_unlock; + } + + errcode = pt_section_lock(section); + if (errcode < 0) + goto out_unlock; + + if (!section->ucount) { + (void) pt_section_unlock(section); + errcode = -pte_internal; + goto out_unlock; + } + + errcode = pt_section_unlock(section); + if (errcode < 0) goto out_unlock; section->iscache = iscache; @@ -281,14 +308,27 @@ acount += 1; if (!acount) { - (void) pt_section_unlock_attach(section); - return -pte_overflow; + errcode = -pte_overflow; + goto out_unlock; + } + + if (section->iscache != iscache) { + errcode = -pte_internal; + goto out_unlock; } - if (ucount < acount) + errcode = pt_section_lock(section); + if (errcode < 0) goto out_unlock; - if (section->iscache != iscache) + if (section->ucount < acount) { + (void) pt_section_unlock(section); + errcode = -pte_internal; + goto out_unlock; + } + + errcode = pt_section_unlock(section); + if (errcode < 0) goto out_unlock; section->acount = acount; @@ -297,13 +337,13 @@ out_unlock: (void) pt_section_unlock_attach(section); - return -pte_internal; + return errcode; } int pt_section_detach(struct pt_section *section, struct pt_image_section_cache *iscache) { - uint16_t acount, ucount; + uint16_t acount; int errcode; if (!section || !iscache) @@ -313,16 +353,30 @@ if (errcode < 0) return errcode; - if (section->iscache != iscache) + if (section->iscache != iscache) { + errcode = -pte_internal; goto out_unlock; + } acount = section->acount; - if (!acount) + if (!acount) { + errcode = -pte_internal; goto out_unlock; - + } acount -= 1; - ucount = section->ucount; - if (ucount < acount) + + errcode = pt_section_lock(section); + if (errcode < 0) + goto out_unlock; + + if (section->ucount < acount) { + (void) pt_section_unlock(section); + errcode = -pte_internal; + goto out_unlock; + } + + errcode = pt_section_unlock(section); + if (errcode < 0) goto out_unlock; section->acount = acount; @@ -333,7 +387,7 @@ out_unlock: (void) pt_section_unlock_attach(section); - return -pte_internal; + return errcode; } const char *pt_section_filename(const struct pt_section *section) @@ -352,7 +406,7 @@ return section->size; } -static int pt_section_bcache_memsize(const struct pt_section *section, +static int pt_section_bcache_memsize(struct pt_section *section, uint64_t *psize) { struct pt_block_cache *bcache; @@ -360,7 +414,7 @@ if (!section || !psize) return -pte_internal; - bcache = section->bcache; + bcache = pt_section_bcache(section); if (!bcache) { *psize = 0ull; return 0; @@ -372,7 +426,7 @@ return 0; } -static int pt_section_memsize_locked(const struct pt_section *section, +static int pt_section_memsize_locked(struct pt_section *section, uint64_t *psize) { uint64_t msize, bcsize; @@ -429,6 +483,27 @@ return section->offset; } +static struct pt_block_cache * +pt_exchange_bcache(struct pt_section *section, struct pt_block_cache *bcache) +{ + if (!section) + return NULL; + +#if !defined(__STDC_NO_ATOMICS__) + return atomic_exchange(§ion->bcache, bcache); +#else + /* The section has been locked by the caller. */ + { + struct pt_block_cache *orig; + + orig = section->bcache; + section->bcache = bcache; + + return orig; + } +#endif +} + int pt_section_alloc_bcache(struct pt_section *section) { struct pt_image_section_cache *iscache; @@ -440,9 +515,6 @@ if (!section) return -pte_internal; - if (!section->mcount) - return -pte_internal; - ssize = pt_section_size(section); csize = (uint32_t) ssize; @@ -467,6 +539,11 @@ if (errcode < 0) goto out_alock; + if (!section->mcount) { + errcode = -pte_internal; + goto out_lock; + } + bcache = pt_section_bcache(section); if (bcache) { errcode = 0; @@ -485,7 +562,11 @@ * If we fail later on, we leave the block cache and report the error to * the allocating decoder thread. */ - section->bcache = bcache; + bcache = pt_exchange_bcache(section, bcache); + if (bcache) { + errcode = -pte_bad_lock; + goto out_lock; + } errcode = pt_section_memsize_locked(section, &memsize); if (errcode < 0) @@ -579,6 +660,7 @@ int pt_section_unmap(struct pt_section *section) { + struct pt_block_cache *bcache; uint16_t mcount; int errcode, status; @@ -605,8 +687,8 @@ status = section->unmap(section); - pt_bcache_free(section->bcache); - section->bcache = NULL; + bcache = pt_exchange_bcache(section, NULL); + pt_bcache_free(bcache); errcode = pt_section_unlock(section); if (errcode < 0)
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/src/pt_section_file.c -> _service:tar_scm:v2.1.tar.gz/libipt/src/pt_section_file.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/src/pt_sync.c -> _service:tar_scm:v2.1.tar.gz/libipt/src/pt_sync.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -191,7 +192,7 @@ continue; /* We found a 64bit word's worth of psb payload pattern. */ - current = pt_find_psb(pos, config); + current = pt_find_psb(current, config); if (!current) continue; @@ -238,7 +239,7 @@ continue; /* We found a 64bit word's worth of psb payload pattern. */ - next = pt_find_psb(next, config); + next = pt_find_psb(pos, config); if (!next) continue;
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/src/pt_time.c -> _service:tar_scm:v2.1.tar.gz/libipt/src/pt_time.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2014-2022, Intel Corporation + * Copyright (c) 2014-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -743,3 +744,18 @@ return 0; } + +int pt_tcal_update_ovf(struct pt_time_cal *tcal, + const struct pt_config *config) +{ + if (!tcal || !config) + return -pte_internal; + + tcal->tsc = 0ull; + tcal->cyc_tsc = 0ull; + tcal->cyc_mtc = 0ull; + tcal->ctc = 0; + tcal->have_mtc = 0; + + return 0; +}
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/src/pt_tnt_cache.c -> _service:tar_scm:v2.1.tar.gz/libipt/src/pt_tnt_cache.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -64,26 +65,28 @@ return taken; } -int pt_tnt_cache_update_tnt(struct pt_tnt_cache *cache, - const struct pt_packet_tnt *packet, - const struct pt_config *config) +int pt_tnt_cache_add(struct pt_tnt_cache *cache, uint64_t tnt, uint8_t size) { - uint8_t bit_size; + uint64_t index; - (void) config; - - if (!cache || !packet) + if (!cache) return -pte_invalid; - if (cache->index) - return -pte_bad_context; + if (!size) + return 0; + + index = cache->index; + if (index) + index <<= size; + else + index = 1ull << (size - 1); - bit_size = packet->bit_size; - if (!bit_size) - return -pte_bad_packet; + if (!index) + return -pte_overflow; - cache->tnt = packet->payload; - cache->index = 1ull << (bit_size - 1); + cache->index = index; + cache->tnt <<= size; + cache->tnt |= tnt & ((1ull << size) - 1); return 0; }
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/src/pt_version.c -> _service:tar_scm:v2.1.tar.gz/libipt/src/pt_version.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/src/windows/pt_section_windows.c -> _service:tar_scm:v2.1.tar.gz/libipt/src/windows/pt_section_windows.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2015-2022, Intel Corporation + * Copyright (c) 2015-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -47,14 +48,14 @@ fd = _open(filename, _O_RDONLY); if (fd == -1) - return -pte_bad_image; + return -pte_bad_file; errcode = _fstat(fd, stat); _close(fd); if (errcode) - return -pte_bad_image; + return -pte_bad_file; return 0; } @@ -98,7 +99,7 @@ errcode = _fstat(fd, &stat); if (errcode) - return -pte_bad_image; + return -pte_bad_file; status = section->status; if (!status) @@ -265,26 +266,24 @@ * We will detect changes to the file via fstat(). */ - fh = CreateFileA(filename, GENERIC_READ, FILE_SHARE_WRITE, - NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, - NULL); + fh = CreateFileA(filename, GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (fh == INVALID_HANDLE_VALUE) { - errcode = -pte_bad_image; + errcode = -pte_bad_file; goto out_unlock; } } fd = _open_osfhandle((intptr_t) fh, _O_RDONLY); if (fd == -1) { - errcode = -pte_bad_image; + errcode = -pte_bad_file; goto out_fh; } errcode = check_file_status(section, fd); - if (errcode < 0) { - errcode = -pte_bad_image; + if (errcode < 0) goto out_fd; - } /* We leave the file open on success. It will be closed when the * section is unmapped. @@ -298,7 +297,7 @@ */ file = _fdopen(fd, "rb"); if (!file) { - errcode = -pte_bad_image; + errcode = -pte_bad_file; goto out_fd; }
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/test/src/ptunit-asid.c -> _service:tar_scm:v2.1.tar.gz/libipt/test/src/ptunit-asid.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2014-2022, Intel Corporation + * Copyright (c) 2014-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/test/src/ptunit-block_cache.c -> _service:tar_scm:v2.1.tar.gz/libipt/test/src/ptunit-block_cache.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2016-2022, Intel Corporation + * Copyright (c) 2016-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.1.tar.gz/libipt/test/src/ptunit-block_decoder.c
Added
@@ -0,0 +1,354 @@ +/* + * Copyright (c) 2019-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "ptunit.h" + +#include "pt_block_decoder.h" + +#include "intel-pt.h" + + +/* A test fixture providing a decoder operating on a small buffer. */ +struct test_fixture { + /* The packet_decoder. */ + struct pt_block_decoder decoder; + + /* The configuration. */ + struct pt_config config; + + /* The buffer it operates on. */ + uint8_t buffer24; + + /* The test fixture initialization and finalization functions. */ + struct ptunit_result (*init)(struct test_fixture *tfix); + struct ptunit_result (*fini)(struct test_fixture *tfix); +}; + +static struct ptunit_result tfix_init(struct test_fixture *tfix) +{ + struct pt_config *config; + uint8_t *buffer; + int errcode; + + config = &tfix->config; + buffer = tfix->buffer; + + memset(buffer, 0, sizeof(tfix->buffer)); + + pt_config_init(config); + config->begin = buffer; + config->end = buffer + sizeof(tfix->buffer); + + errcode = pt_blk_decoder_init(&tfix->decoder, config); + ptu_int_eq(errcode, 0); + + return ptu_passed(); +} + +static struct ptunit_result decoder_init_null(void) +{ + struct pt_block_decoder decoder; + struct pt_config config; + int errcode; + + memset(&config, 0, sizeof(config)); + + errcode = pt_blk_decoder_init(NULL, &config); + ptu_int_eq(errcode, -pte_internal); + + errcode = pt_blk_decoder_init(&decoder, NULL); + ptu_int_eq(errcode, -pte_invalid); + + return ptu_passed(); +} + +static struct ptunit_result decoder_fini_null(void) +{ + pt_blk_decoder_fini(NULL); + + return ptu_passed(); +} + +static struct ptunit_result alloc_decoder_null(void) +{ + struct pt_block_decoder *decoder; + + decoder = pt_blk_alloc_decoder(NULL); + ptu_null(decoder); + + return ptu_passed(); +} + +static struct ptunit_result free_decoder_null(void) +{ + pt_blk_free_decoder(NULL); + + return ptu_passed(); +} + +static struct ptunit_result sync_forward_null(void) +{ + int errcode; + + errcode = pt_blk_sync_forward(NULL); + ptu_int_eq(errcode, -pte_invalid); + + return ptu_passed(); +} + +static struct ptunit_result sync_backward_null(void) +{ + int errcode; + + errcode = pt_blk_sync_backward(NULL); + ptu_int_eq(errcode, -pte_invalid); + + return ptu_passed(); +} + +static struct ptunit_result sync_set_null(void) +{ + int errcode; + + errcode = pt_blk_sync_set(NULL, 0ull); + ptu_int_eq(errcode, -pte_invalid); + + return ptu_passed(); +} + +static struct ptunit_result sync_set_eos(struct test_fixture *tfix) +{ + int errcode; + + errcode = pt_blk_sync_set(&tfix->decoder, sizeof(tfix->buffer) + 1); + ptu_int_eq(errcode, -pte_eos); + + return ptu_passed(); +} + +static struct ptunit_result get_offset_null(void) +{ + struct pt_block_decoder decoder; + uint64_t offset; + int errcode; + + errcode = pt_blk_get_offset(NULL, &offset); + ptu_int_eq(errcode, -pte_invalid); + + errcode = pt_blk_get_offset(&decoder, NULL); + ptu_int_eq(errcode, -pte_invalid); + + return ptu_passed(); +} + +static struct ptunit_result get_offset_init(struct test_fixture *tfix) +{ + uint64_t offset; + int errcode; + + errcode = pt_blk_get_offset(&tfix->decoder, &offset); + ptu_int_eq(errcode, -pte_nosync); + + return ptu_passed(); +} + +static struct ptunit_result get_sync_offset_null(void) +{ + struct pt_block_decoder decoder; + uint64_t offset; + int errcode; + + errcode = pt_blk_get_sync_offset(NULL, &offset); + ptu_int_eq(errcode, -pte_invalid); + + errcode = pt_blk_get_sync_offset(&decoder, NULL); + ptu_int_eq(errcode, -pte_invalid); + + return ptu_passed(); +} + +static struct ptunit_result get_image_null(void) +{ + const struct pt_image *image; + + image = pt_blk_get_image(NULL); + ptu_null(image); + + return ptu_passed(); +} + +static struct ptunit_result set_image_null(void) +{ + struct pt_image image; + int errcode; + + errcode = pt_blk_set_image(NULL, &image); + ptu_int_eq(errcode, -pte_invalid); + + errcode = pt_blk_set_image(NULL, NULL); + ptu_int_eq(errcode, -pte_invalid); + + return ptu_passed(); +} + +static struct ptunit_result get_config_null(void) +{ + const struct pt_config *config; + + config = pt_blk_get_config(NULL); + ptu_null(config); + + return ptu_passed(); +} + +static struct ptunit_result get_config(struct test_fixture *tfix) +{ + const struct pt_config *config; + + config = pt_blk_get_config(&tfix->decoder); + ptu_ptr(config); + + return ptu_passed(); +} + +static struct ptunit_result time_null(void) +{ + struct pt_block_decoder decoder; + uint64_t time; + uint32_t lost_mtc, lost_cyc; + int errcode; + + errcode = pt_blk_time(NULL, &time, &lost_mtc, &lost_cyc); + ptu_int_eq(errcode, -pte_invalid); + + errcode = pt_blk_time(&decoder, NULL, &lost_mtc, &lost_cyc); + ptu_int_eq(errcode, -pte_invalid); + + return ptu_passed(); +} + +static struct ptunit_result cbr_null(void) +{ + struct pt_block_decoder decoder; + uint32_t cbr; + int errcode; + + errcode = pt_blk_core_bus_ratio(NULL, &cbr); + ptu_int_eq(errcode, -pte_invalid); + + errcode = pt_blk_core_bus_ratio(&decoder, NULL); + ptu_int_eq(errcode, -pte_invalid); + + return ptu_passed(); +} + +static struct ptunit_result asid_null(void) +{ + struct pt_block_decoder decoder; + struct pt_asid asid; + int errcode; + + errcode = pt_blk_asid(NULL, &asid, sizeof(asid)); + ptu_int_eq(errcode, -pte_invalid); + + errcode = pt_blk_asid(&decoder, NULL, sizeof(asid)); + ptu_int_eq(errcode, -pte_invalid); + + return ptu_passed(); +} + +static struct ptunit_result next_null(void) +{ + struct pt_block_decoder decoder; + struct pt_block block; + int errcode; + + errcode = pt_blk_next(NULL, &block, sizeof(block)); + ptu_int_eq(errcode, -pte_invalid); + + errcode = pt_blk_next(&decoder, NULL, sizeof(block)); + ptu_int_eq(errcode, -pte_invalid); + + return ptu_passed(); +} + +static struct ptunit_result event_null(void) +{ + struct pt_block_decoder decoder; + struct pt_event event; + int errcode; + + errcode = pt_blk_event(NULL, &event, sizeof(event)); + ptu_int_eq(errcode, -pte_invalid); + + errcode = pt_blk_event(&decoder, NULL, sizeof(event)); + ptu_int_eq(errcode, -pte_invalid); + + return ptu_passed(); +} + +int main(int argc, char **argv) +{ + struct test_fixture tfix; + struct ptunit_suite suite; + + tfix.init = tfix_init; + tfix.fini = NULL; + + suite = ptunit_mk_suite(argc, argv); + + ptu_run(suite, decoder_init_null); + ptu_run(suite, decoder_fini_null); + ptu_run(suite, alloc_decoder_null); + ptu_run(suite, free_decoder_null); + + ptu_run(suite, sync_forward_null); + ptu_run(suite, sync_backward_null); + ptu_run(suite, sync_set_null); + ptu_run_f(suite, sync_set_eos, tfix); + + ptu_run(suite, get_offset_null); + ptu_run_f(suite, get_offset_init, tfix); + ptu_run(suite, get_sync_offset_null); + + ptu_run(suite, get_image_null); + ptu_run(suite, set_image_null); + + ptu_run(suite, get_config_null); + ptu_run_f(suite, get_config, tfix); + + ptu_run(suite, time_null); + ptu_run(suite, cbr_null); + ptu_run(suite, asid_null); + + ptu_run(suite, next_null); + ptu_run(suite, event_null); + + return ptunit_report(&suite); +}
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/test/src/ptunit-config.c -> _service:tar_scm:v2.1.tar.gz/libipt/test/src/ptunit-config.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2015-2022, Intel Corporation + * Copyright (c) 2015-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -466,6 +467,67 @@ return ptu_passed(); } +static struct ptunit_result cpu_errata_null(void) +{ + struct pt_errata errata; + struct pt_cpu cpu; + int errcode; + + errcode = pt_cpu_errata(&errata, NULL); + ptu_int_eq(errcode, -pte_invalid); + + errcode = pt_cpu_errata(NULL, &cpu); + ptu_int_eq(errcode, -pte_invalid); + + return ptu_passed(); +} + +static struct ptunit_result cpu_errata_unknown(void) +{ + struct pt_errata errata; + struct pt_cpu cpu; + int errcode; + + memset(&cpu, 0, sizeof(cpu)); + + errcode = pt_cpu_errata(&errata, &cpu); + ptu_int_eq(errcode, -pte_bad_cpu); + + return ptu_passed(); +} + +static struct ptunit_result cpu_errata_bad_vendor(void) +{ + struct pt_errata errata; + struct pt_cpu cpu; + int errcode; + + memset(&cpu, 0, sizeof(cpu)); + cpu.vendor = (enum pt_cpu_vendor) 0xffff; + + errcode = pt_cpu_errata(&errata, &cpu); + ptu_int_eq(errcode, -pte_bad_cpu); + + return ptu_passed(); +} + +static struct ptunit_result cpu_errata_bad_cpuid(void) +{ + struct pt_errata errata; + struct pt_cpu cpu; + int errcode; + + memset(&cpu, 0, sizeof(cpu)); + cpu.vendor = pcv_intel; + cpu.family = 6; + cpu.model = 63; + + errcode = pt_cpu_errata(&errata, &cpu); + ptu_int_eq(errcode, -pte_bad_cpu); + + return ptu_passed(); +} + int main(int argc, char **argv) { struct ptunit_suite suite; @@ -494,5 +556,10 @@ ptu_run(suite, addr_filter_ip_out_stop_in); ptu_run(suite, addr_filter_ip_in_stop_in); + ptu_run(suite, cpu_errata_null); + ptu_run(suite, cpu_errata_unknown); + ptu_run(suite, cpu_errata_bad_vendor); + ptu_run(suite, cpu_errata_bad_cpuid); + return ptunit_report(&suite); }
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/test/src/ptunit-cpp.cpp -> _service:tar_scm:v2.1.tar.gz/libipt/test/src/ptunit-cpp.cpp
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/test/src/ptunit-cpu.c -> _service:tar_scm:v2.1.tar.gz/libipt/test/src/ptunit-cpu.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -29,24 +30,12 @@ #include "ptunit.h" #include "pt_cpu.h" -#include "pt_cpuid.h" #include "intel-pt.h" #include <stdlib.h> -void pt_cpuid(uint32_t leaf, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, - uint32_t *edx) -{ - (void) leaf; - (void) eax; - (void) ebx; - (void) ecx; - (void) edx; -} - - static struct ptunit_result cpu_valid(void) { struct pt_cpu cpu;
View file
_service:tar_scm:v2.1.tar.gz/libipt/test/src/ptunit-encoder.c
Added
@@ -0,0 +1,242 @@ +/* + * Copyright (c) 2019-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "ptunit.h" + +#include "pt_encoder.h" + +#include "intel-pt.h" + + +/* A test fixture providing a decoder operating on a small buffer. */ +struct test_fixture { + /* The encoder. */ + struct pt_encoder encoder; + + /* The configuration. */ + struct pt_config config; + + /* The buffer it operates on. */ + uint8_t buffer24; + + /* The test fixture initialization and finalization functions. */ + struct ptunit_result (*init)(struct test_fixture *tfix); + struct ptunit_result (*fini)(struct test_fixture *tfix); +}; + +static struct ptunit_result tfix_init(struct test_fixture *tfix) +{ + struct pt_config *config; + uint8_t *buffer; + int errcode; + + config = &tfix->config; + buffer = tfix->buffer; + + memset(buffer, 0, sizeof(tfix->buffer)); + + pt_config_init(config); + config->begin = buffer; + config->end = buffer + sizeof(tfix->buffer); + + errcode = pt_encoder_init(&tfix->encoder, config); + ptu_int_eq(errcode, 0); + + return ptu_passed(); +} + +static struct ptunit_result encoder_init_null(void) +{ + struct pt_encoder encoder; + struct pt_config config; + int errcode; + + memset(&config, 0, sizeof(config)); + + errcode = pt_encoder_init(NULL, &config); + ptu_int_eq(errcode, -pte_invalid); + + errcode = pt_encoder_init(&encoder, NULL); + ptu_int_eq(errcode, -pte_invalid); + + return ptu_passed(); +} + +static struct ptunit_result encoder_fini_null(void) +{ + pt_encoder_fini(NULL); + + return ptu_passed(); +} + +static struct ptunit_result alloc_encoder_null(void) +{ + struct pt_encoder *encoder; + + encoder = pt_alloc_encoder(NULL); + ptu_null(encoder); + + return ptu_passed(); +} + +static struct ptunit_result free_encoder_null(void) +{ + pt_free_encoder(NULL); + + return ptu_passed(); +} + +static struct ptunit_result sync_set_null(void) +{ + int errcode; + + errcode = pt_enc_sync_set(NULL, 0ull); + ptu_int_eq(errcode, -pte_invalid); + + return ptu_passed(); +} + +static struct ptunit_result sync_set_eos(struct test_fixture *tfix) +{ + int errcode; + + errcode = pt_enc_sync_set(&tfix->encoder, sizeof(tfix->buffer) + 1); + ptu_int_eq(errcode, -pte_eos); + + return ptu_passed(); +} + +static struct ptunit_result get_offset_null(void) +{ + struct pt_encoder encoder; + uint64_t offset; + int errcode; + + errcode = pt_enc_get_offset(NULL, &offset); + ptu_int_eq(errcode, -pte_invalid); + + errcode = pt_enc_get_offset(&encoder, NULL); + ptu_int_eq(errcode, -pte_invalid); + + return ptu_passed(); +} + +static struct ptunit_result get_offset_init(struct test_fixture *tfix) +{ + uint64_t offset; + int errcode; + + errcode = pt_enc_get_offset(&tfix->encoder, &offset); + ptu_int_eq(errcode, 0); + ptu_uint_eq(offset, 0ull); + + return ptu_passed(); +} + +static struct ptunit_result sync_set_get_offset(struct test_fixture *tfix) +{ + uint64_t offset; + int errcode; + + errcode = pt_enc_sync_set(&tfix->encoder, 1ull); + ptu_int_eq(errcode, 0); + + errcode = pt_enc_get_offset(&tfix->encoder, &offset); + ptu_int_eq(errcode, 0); + ptu_uint_eq(offset, 1ull); + + return ptu_passed(); +} + +static struct ptunit_result get_config_null(void) +{ + const struct pt_config *config; + + config = pt_enc_get_config(NULL); + ptu_null(config); + + return ptu_passed(); +} + +static struct ptunit_result get_config(struct test_fixture *tfix) +{ + const struct pt_config *config; + + config = pt_enc_get_config(&tfix->encoder); + ptu_ptr(config); + + return ptu_passed(); +} + +static struct ptunit_result next_null(void) +{ + struct pt_encoder encoder; + struct pt_packet packet; + int errcode; + + memset(&packet, 0, sizeof(packet)); + + errcode = pt_enc_next(NULL, &packet); + ptu_int_eq(errcode, -pte_invalid); + + errcode = pt_enc_next(&encoder, NULL); + ptu_int_eq(errcode, -pte_invalid); + + return ptu_passed(); +} + +int main(int argc, char **argv) +{ + struct test_fixture tfix; + struct ptunit_suite suite; + + tfix.init = tfix_init; + tfix.fini = NULL; + + suite = ptunit_mk_suite(argc, argv); + + ptu_run(suite, encoder_init_null); + ptu_run(suite, encoder_fini_null); + ptu_run(suite, alloc_encoder_null); + ptu_run(suite, free_encoder_null); + + ptu_run(suite, sync_set_null); + ptu_run_f(suite, sync_set_eos, tfix); + + ptu_run(suite, get_offset_null); + ptu_run_f(suite, get_offset_init, tfix); + ptu_run_f(suite, sync_set_get_offset, tfix); + + ptu_run(suite, get_config_null); + ptu_run_f(suite, get_config, tfix); + + ptu_run(suite, next_null); + + return ptunit_report(&suite); +}
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/test/src/ptunit-event_queue.c -> _service:tar_scm:v2.1.tar.gz/libipt/test/src/ptunit-event_queue.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2014-2022, Intel Corporation + * Copyright (c) 2014-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -49,21 +50,6 @@ return ptu_passed(); } -static struct ptunit_result efix_init_pending(struct evq_fixture *efix) -{ - struct pt_event *ev; - int evb; - - pt_evq_init(&efix->evq); - - for (evb = 0; evb < evb_max; ++evb) { - ev = pt_evq_enqueue(&efix->evq, (enum pt_event_binding) evb); - ptu_ptr(ev); - } - - return ptu_passed(); -} - static struct ptunit_result standalone_null(void) { struct pt_event *ev; @@ -86,7 +72,7 @@ return ptu_passed(); } -static struct ptunit_result enqueue_null(enum pt_event_binding evb) +static struct ptunit_result enqueue_null(uint32_t evb) { struct pt_event *ev; @@ -96,7 +82,7 @@ return ptu_passed(); } -static struct ptunit_result dequeue_null(enum pt_event_binding evb) +static struct ptunit_result dequeue_null(uint32_t evb) { struct pt_event *ev; @@ -106,8 +92,22 @@ return ptu_passed(); } +static struct ptunit_result requeue_null(struct evq_fixture *efix, + uint32_t evb) +{ + struct pt_event *ev, lev; + + ev = pt_evq_requeue(NULL, &lev, evb); + ptu_null(ev); + + ev = pt_evq_requeue(&efix->evq, NULL, evb); + ptu_null(ev); + + return ptu_passed(); +} + static struct ptunit_result dequeue_empty(struct evq_fixture *efix, - enum pt_event_binding evb) + uint32_t evb) { struct pt_event *ev; @@ -117,8 +117,7 @@ return ptu_passed(); } -static struct ptunit_result evq_empty(struct evq_fixture *efix, - enum pt_event_binding evb) +static struct ptunit_result evq_empty(struct evq_fixture *efix, uint32_t evb) { int status; @@ -131,8 +130,7 @@ return ptu_passed(); } -static struct ptunit_result evq_pending(struct evq_fixture *efix, - enum pt_event_binding evb) +static struct ptunit_result evq_pending(struct evq_fixture *efix, uint32_t evb) { int status; @@ -145,73 +143,185 @@ return ptu_passed(); } -static struct ptunit_result evq_others_empty(struct evq_fixture *efix, - enum pt_event_binding evb) +static struct ptunit_result enqueue_all_dequeue(struct evq_fixture *efix, + uint32_t enqb, uint32_t deqb, + size_t num) { - int other; + struct pt_event *inevq_max, *outevq_max; + size_t idx; - for (other = 0; other < evb_max; ++other) { - enum pt_event_binding ob; + ptu_uint_le(num, evq_max); - ob = (enum pt_event_binding) other; - if (ob != evb) - ptu_test(evq_empty, efix, ob); + for (idx = 0; idx < num; ++idx) { + inidx = pt_evq_enqueue(&efix->evq, enqb); + ptu_ptr(inidx); + } + + ptu_test(evq_pending, efix, enqb); + ptu_test(evq_empty, efix, ~enqb); + + for (idx = 0; idx < num; ++idx) { + outidx = pt_evq_dequeue(&efix->evq, deqb); + ptu_ptr_eq(outidx, inidx); } + ptu_test(evq_empty, efix, deqb); + return ptu_passed(); } -static struct ptunit_result enqueue_all_dequeue(struct evq_fixture *efix, - enum pt_event_binding evb, - size_t num) +static struct ptunit_result dequeue_requeue_all(struct evq_fixture *efix, + uint32_t enqb, uint32_t reqb, + uint32_t deqb, size_t num) { struct pt_event *inevq_max, *outevq_max; size_t idx; - ptu_uint_le(num, evq_max - 2); + ptu_uint_le(num, evq_max); for (idx = 0; idx < num; ++idx) { - inidx = pt_evq_enqueue(&efix->evq, evb); + inidx = pt_evq_enqueue(&efix->evq, enqb); ptu_ptr(inidx); } - ptu_test(evq_pending, efix, evb); - ptu_test(evq_others_empty, efix, evb); + ptu_test(evq_pending, efix, enqb); + ptu_test(evq_empty, efix, ~enqb); for (idx = 0; idx < num; ++idx) { - outidx = pt_evq_dequeue(&efix->evq, evb); + outidx = pt_evq_dequeue(&efix->evq, enqb); + ptu_ptr_eq(outidx, inidx); + + inidx = pt_evq_requeue(&efix->evq, outidx, reqb); + ptu_ptr(inidx); + } + + ptu_test(evq_pending, efix, reqb); + ptu_test(evq_empty, efix, ~reqb); + + for (idx = 0; idx < num; ++idx) { + outidx = pt_evq_dequeue(&efix->evq, deqb); ptu_ptr_eq(outidx, inidx); } - ptu_test(evq_empty, efix, evb); + ptu_test(evq_empty, efix, deqb); return ptu_passed(); } -static struct ptunit_result enqueue_one_dequeue(struct evq_fixture *efix, - enum pt_event_binding evb, - size_t num) +static struct ptunit_result standalone_requeue_all(struct evq_fixture *efix, + uint32_t reqb, uint32_t deqb, + size_t num) { + struct pt_event *inevq_max, *outevq_max; size_t idx; + ptu_uint_le(num, evq_max); + for (idx = 0; idx < num; ++idx) { + struct pt_event *ev; + + ev = pt_evq_standalone(&efix->evq); + ptu_ptr(ev); + + inidx = pt_evq_requeue(&efix->evq, ev, reqb); + ptu_ptr(inidx); + ptu_ptr_ne(inidx, ev); + } + + ptu_test(evq_pending, efix, reqb); + ptu_test(evq_empty, efix, ~reqb); + + for (idx = 0; idx < num; ++idx) { + outidx = pt_evq_dequeue(&efix->evq, deqb); + ptu_ptr_eq(outidx, inidx); + } + + ptu_test(evq_empty, efix, deqb); + + return ptu_passed(); +} + +static struct ptunit_result enqueue_one_dequeue(struct evq_fixture *efix, + uint32_t enqb, uint32_t deqb) +{ + size_t idx; + + for (idx = 0; idx < evq_max * 2; ++idx) { struct pt_event *in, *out; - in = pt_evq_enqueue(&efix->evq, evb); + in = pt_evq_enqueue(&efix->evq, enqb); + ptu_ptr(in); + + out = pt_evq_dequeue(&efix->evq, deqb); + ptu_ptr_eq(out, in); + } + + ptu_test(evq_empty, efix, deqb); + + return ptu_passed(); +} + +static struct ptunit_result dequeue_requeue_one(struct evq_fixture *efix, + uint32_t enqb, uint32_t reqb, + uint32_t deqb) +{ + size_t idx; + + for (idx = 0; idx < evq_max * 2; ++idx) { + struct pt_event *in, *re, *out; + + in = pt_evq_enqueue(&efix->evq, enqb); ptu_ptr(in); + in->type = ptev_overflow; - out = pt_evq_dequeue(&efix->evq, evb); + out = pt_evq_dequeue(&efix->evq, enqb); ptu_ptr_eq(out, in); + ptu_int_eq(out->type, ptev_overflow); + + re = pt_evq_requeue(&efix->evq, out, reqb); + ptu_ptr(re); + ptu_int_eq(re->type, ptev_overflow); + + out = pt_evq_dequeue(&efix->evq, deqb); + ptu_ptr_eq(out, re); + ptu_int_eq(out->type, ptev_overflow); + } + + ptu_test(evq_empty, efix, deqb); + + return ptu_passed(); +} + +static struct ptunit_result standalone_requeue_one(struct evq_fixture *efix, + uint32_t reqb, uint32_t deqb) +{ + size_t idx; + + for (idx = 0; idx < evq_max * 2; ++idx) { + struct pt_event *in, *re, *out; + + in = pt_evq_standalone(&efix->evq); + ptu_ptr(in); + in->type = ptev_overflow; + + re = pt_evq_requeue(&efix->evq, in, reqb); + ptu_ptr(re); + ptu_int_eq(re->type, ptev_overflow); + + out = pt_evq_dequeue(&efix->evq, deqb); + ptu_ptr_eq(out, re); + ptu_int_eq(out->type, ptev_overflow); } + ptu_test(evq_empty, efix, deqb); + return ptu_passed(); } static struct ptunit_result overflow(struct evq_fixture *efix, - enum pt_event_binding evb, - size_t num) + uint32_t evb, size_t num) { - struct pt_event *inevq_max, *outevq_max, *ev; + struct pt_event *inevq_max, *outevq_max; size_t idx; ptu_uint_le(num, evq_max - 2); @@ -222,11 +332,23 @@ } for (idx = 0; idx < num; ++idx) { + struct pt_event *ev; + ev = pt_evq_enqueue(&efix->evq, evb); ptu_null(ev); } for (idx = 0; idx < num; ++idx) { + struct pt_event *ev, *re; + + ev = pt_evq_standalone(&efix->evq); + ptu_ptr(ev); + + re = pt_evq_requeue(&efix->evq, ev, evb); + ptu_null(re); + } + + for (idx = 0; idx < num; ++idx) { outidx = pt_evq_dequeue(&efix->evq, evb); ptu_ptr_eq(outidx, inidx); } @@ -234,30 +356,79 @@ return ptu_passed(); } -static struct ptunit_result clear_null(enum pt_event_binding evb) +static struct ptunit_result dequeue_requeue_full(struct evq_fixture *efix, + uint32_t evb) +{ + struct pt_event *ev; + size_t idx; + + for (idx = 0; idx < (evq_max - 2); ++idx) { + ev = pt_evq_enqueue(&efix->evq, evb); + ptu_ptr(ev); + + ev->type = ptev_overflow; + } + + ev = pt_evq_dequeue(&efix->evq, evb); + ptu_ptr(ev); + ptu_int_eq(ev->type, ptev_overflow); + ev->type = ptev_exstop; + + ev = pt_evq_requeue(&efix->evq, ev, evb); + ptu_ptr(ev); + ptu_int_eq(ev->type, ptev_exstop); + + return ptu_passed(); +} + +static struct ptunit_result clear_null(void) { int errcode; - errcode = pt_evq_clear(NULL, evb); + errcode = pt_evq_clear(NULL); ptu_int_eq(errcode, -pte_internal); return ptu_passed(); } -static struct ptunit_result clear(struct evq_fixture *efix, - enum pt_event_binding evb) +static struct ptunit_result clear_empty(struct evq_fixture *efix) +{ + int errcode; + + errcode = pt_evq_clear(&efix->evq); + ptu_int_eq(errcode, 0); + + ptu_test(evq_empty, efix, UINT32_MAX); + + return ptu_passed(); +} + +static struct ptunit_result clear(struct evq_fixture *efix) { + struct pt_event *ev; int errcode; - errcode = pt_evq_clear(&efix->evq, evb); + ev = pt_evq_enqueue(&efix->evq, evb_psbend); + ptu_ptr(ev); + + ev = pt_evq_enqueue(&efix->evq, evb_tip); + ptu_ptr(ev); + + ev = pt_evq_enqueue(&efix->evq, evb_fup); + ptu_ptr(ev); + + ev = pt_evq_enqueue(&efix->evq, evb_exstop); + ptu_ptr(ev); + + errcode = pt_evq_clear(&efix->evq); ptu_int_eq(errcode, 0); - ptu_test(evq_empty, efix, evb); + ptu_test(evq_empty, efix, UINT32_MAX); return ptu_passed(); } -static struct ptunit_result empty_null(enum pt_event_binding evb) +static struct ptunit_result empty_null(uint32_t evb) { int errcode; @@ -267,7 +438,7 @@ return ptu_passed(); } -static struct ptunit_result pending_null(enum pt_event_binding evb) +static struct ptunit_result pending_null(uint32_t evb) { int errcode; @@ -277,8 +448,7 @@ return ptu_passed(); } -static struct ptunit_result find_null(enum pt_event_binding evb, - enum pt_event_type evt) +static struct ptunit_result find_null(uint32_t evb, enum pt_event_type evt) { struct pt_event *ev; @@ -288,8 +458,7 @@ return ptu_passed(); } -static struct ptunit_result find_empty(struct evq_fixture *efix, - enum pt_event_binding evb, +static struct ptunit_result find_empty(struct evq_fixture *efix, uint32_t evb, enum pt_event_type evt) { struct pt_event *ev; @@ -301,84 +470,113 @@ } static struct ptunit_result find_none_evb(struct evq_fixture *efix, - enum pt_event_binding evb, - enum pt_event_type evt) + uint32_t enqb, uint32_t evb) { struct pt_event *ev; - size_t other; - for (other = 0; other < evb_max; ++other) { - enum pt_event_binding ob; + ev = pt_evq_enqueue(&efix->evq, enqb); + ptu_ptr(ev); + ev->type = ptev_overflow; - ob = (enum pt_event_binding) other; - if (ob != evb) { - ev = pt_evq_enqueue(&efix->evq, ob); - ptu_ptr(ev); + ev = pt_evq_find(&efix->evq, evb, ptev_overflow); + ptu_null(ev); - ev->type = evt; - } - } + return ptu_passed(); +} - ev = pt_evq_find(&efix->evq, evb, evt); +static struct ptunit_result find_none_evt(struct evq_fixture *efix, + uint32_t evb) +{ + struct pt_event *ev; + + ev = pt_evq_enqueue(&efix->evq, UINT32_MAX); + ptu_ptr(ev); + ev->type = ptev_overflow; + + ev = pt_evq_find(&efix->evq, evb, ptev_paging); ptu_null(ev); return ptu_passed(); } -static struct ptunit_result evq_enqueue_other(struct evq_fixture *efix, - enum pt_event_binding evb, - enum pt_event_type evt, - size_t num) +static struct ptunit_result find(struct evq_fixture *efix, uint32_t evb) +{ + struct pt_event *ev, *in, *out; + + ev = pt_evq_enqueue(&efix->evq, evb); + ptu_ptr(ev); + ev->type = ptev_overflow; + + ev = pt_evq_enqueue(&efix->evq, ~evb); + ptu_ptr(ev); + ev->type = ptev_paging; + + in = pt_evq_enqueue(&efix->evq, evb); + ptu_ptr(in); + in->type = ptev_paging; + + ev = pt_evq_enqueue(&efix->evq, evb); + ptu_ptr(ev); + ev->type = ptev_overflow; + + ev = pt_evq_enqueue(&efix->evq, ~evb); + ptu_ptr(ev); + ev->type = ptev_paging; + + out = pt_evq_find(&efix->evq, evb, ptev_paging); + ptu_ptr_eq(out, in); + + return ptu_passed(); +} + +static struct ptunit_result peek_null(uint32_t evb) { - enum pt_event_type ot; struct pt_event *ev; - size_t other; - for (other = 0; other < num; ++other) { - ot = (enum pt_event_type) other; - if (ot != evt) { - ev = pt_evq_enqueue(&efix->evq, evb); - ptu_ptr(ev); + ev = pt_evq_peek(NULL, evb); + ptu_null(ev); - ev->type = ot; - } - } + return ptu_passed(); +} + +static struct ptunit_result peek_empty(struct evq_fixture *efix, uint32_t evb) +{ + struct pt_event *ev; + + ev = pt_evq_peek(&efix->evq, evb); + ptu_null(ev); return ptu_passed(); } -static struct ptunit_result find_none_evt(struct evq_fixture *efix, - enum pt_event_binding evb, - enum pt_event_type evt, - size_t num) +static struct ptunit_result peek_none_evb(struct evq_fixture *efix, + uint32_t enqb, uint32_t evb) { struct pt_event *ev; - ptu_test(evq_enqueue_other, efix, evb, evt, num); + ev = pt_evq_enqueue(&efix->evq, enqb); + ptu_ptr(ev); - ev = pt_evq_find(&efix->evq, evb, evt); + ev = pt_evq_peek(&efix->evq, evb); ptu_null(ev); return ptu_passed(); } -static struct ptunit_result find(struct evq_fixture *efix, - enum pt_event_binding evb, - enum pt_event_type evt, - size_t before, size_t after) +static struct ptunit_result peek(struct evq_fixture *efix, uint32_t evb) { - struct pt_event *in, *out; + struct pt_event *ev, *in, *out; - ptu_test(evq_enqueue_other, efix, evb, evt, before); + ev = pt_evq_enqueue(&efix->evq, ~evb); + ptu_ptr(ev); in = pt_evq_enqueue(&efix->evq, evb); ptu_ptr(in); - in->type = evt; - - ptu_test(evq_enqueue_other, efix, evb, evt, after); + ev = pt_evq_enqueue(&efix->evq, evb); + ptu_ptr(ev); - out = pt_evq_find(&efix->evq, evb, evt); + out = pt_evq_peek(&efix->evq, evb); ptu_ptr_eq(out, in); return ptu_passed(); @@ -386,85 +584,113 @@ int main(int argc, char **argv) { - struct evq_fixture efix, pfix; + struct evq_fixture efix; struct ptunit_suite suite; efix.init = efix_init; efix.fini = NULL; - pfix.init = efix_init_pending; - pfix.fini = NULL; - suite = ptunit_mk_suite(argc, argv); ptu_run(suite, standalone_null); ptu_run_f(suite, standalone, efix); ptu_run_p(suite, enqueue_null, evb_psbend); - ptu_run_p(suite, enqueue_null, evb_tip); - ptu_run_p(suite, enqueue_null, evb_fup); + ptu_run_p(suite, enqueue_null, evb_tip | evb_fup); ptu_run_p(suite, dequeue_null, evb_psbend); - ptu_run_p(suite, dequeue_null, evb_tip); - ptu_run_p(suite, dequeue_null, evb_fup); - - ptu_run_fp(suite, dequeue_empty, efix, evb_psbend); - ptu_run_fp(suite, dequeue_empty, efix, evb_tip); - ptu_run_fp(suite, dequeue_empty, efix, evb_fup); + ptu_run_p(suite, dequeue_null, evb_tip | evb_fup); - ptu_run_fp(suite, enqueue_all_dequeue, efix, evb_psbend, 1); - ptu_run_fp(suite, enqueue_all_dequeue, efix, evb_psbend, 2); - ptu_run_fp(suite, enqueue_all_dequeue, efix, evb_tip, 1); - ptu_run_fp(suite, enqueue_all_dequeue, efix, evb_tip, 3); - ptu_run_fp(suite, enqueue_all_dequeue, efix, evb_fup, 1); - ptu_run_fp(suite, enqueue_all_dequeue, efix, evb_fup, 4); + ptu_run_fp(suite, requeue_null, efix, evb_psbend); + ptu_run_fp(suite, requeue_null, efix, evb_tip | evb_fup); - ptu_run_fp(suite, enqueue_one_dequeue, efix, evb_psbend, evb_max * 2); - ptu_run_fp(suite, enqueue_one_dequeue, efix, evb_tip, evb_max * 2); - ptu_run_fp(suite, enqueue_one_dequeue, efix, evb_fup, evb_max * 2); + ptu_run_fp(suite, dequeue_empty, efix, evb_psbend); + ptu_run_fp(suite, dequeue_empty, efix, evb_tip | evb_fup); + + ptu_run_fp(suite, enqueue_all_dequeue, efix, evb_psbend, evb_psbend, 1); + ptu_run_fp(suite, enqueue_all_dequeue, efix, evb_tip, + evb_tip | evb_fup, 2); + ptu_run_fp(suite, enqueue_all_dequeue, efix, evb_tip | evb_fup, + evb_tip, 1); + ptu_run_fp(suite, enqueue_all_dequeue, efix, evb_tip | evb_fup, + evb_fup, 4); + ptu_run_fp(suite, enqueue_all_dequeue, efix, evb_tip | evb_fup, + evb_fup | evb_exstop, 6); + + ptu_run_fp(suite, dequeue_requeue_all, efix, evb_psbend, evb_psbend, + evb_psbend, 1); + ptu_run_fp(suite, dequeue_requeue_all, efix, evb_tip, evb_fup, + evb_fup | evb_psbend, 6); + ptu_run_fp(suite, dequeue_requeue_all, efix, evb_tip, + evb_fup | evb_psbend, evb_fup, 6); + + ptu_run_fp(suite, standalone_requeue_all, efix, evb_psbend, + evb_psbend, 1); + ptu_run_fp(suite, standalone_requeue_all, efix, evb_fup, + evb_fup | evb_psbend, 6); + ptu_run_fp(suite, standalone_requeue_all, efix, evb_fup | evb_tip, + evb_tip, 6); + + ptu_run_fp(suite, enqueue_one_dequeue, efix, evb_psbend, evb_psbend); + ptu_run_fp(suite, enqueue_one_dequeue, efix, evb_tip, + evb_tip | evb_fup); + ptu_run_fp(suite, enqueue_one_dequeue, efix, evb_tip | evb_fup, + evb_fup); + ptu_run_fp(suite, enqueue_one_dequeue, efix, evb_tip | evb_fup, + evb_fup | evb_exstop); + + ptu_run_fp(suite, dequeue_requeue_one, efix, evb_fup, evb_fup, evb_fup); + ptu_run_fp(suite, dequeue_requeue_one, efix, evb_tip | evb_fup, + evb_exstop | evb_fup, evb_exstop); + + ptu_run_fp(suite, standalone_requeue_one, efix, evb_fup, evb_fup); + ptu_run_fp(suite, standalone_requeue_one, efix, evb_tip | evb_fup, + evb_exstop | evb_fup); ptu_run_fp(suite, overflow, efix, evb_psbend, 1); ptu_run_fp(suite, overflow, efix, evb_tip, 2); ptu_run_fp(suite, overflow, efix, evb_fup, 3); - ptu_run_p(suite, clear_null, evb_psbend); - ptu_run_p(suite, clear_null, evb_tip); - ptu_run_p(suite, clear_null, evb_fup); + ptu_run_fp(suite, dequeue_requeue_full, efix, evb_psbend); - ptu_run_fp(suite, clear, efix, evb_psbend); - ptu_run_fp(suite, clear, pfix, evb_psbend); - ptu_run_fp(suite, clear, efix, evb_tip); - ptu_run_fp(suite, clear, pfix, evb_tip); - ptu_run_fp(suite, clear, efix, evb_fup); - ptu_run_fp(suite, clear, pfix, evb_fup); + ptu_run(suite, clear_null); + ptu_run_f(suite, clear_empty, efix); + ptu_run_f(suite, clear, efix); ptu_run_p(suite, empty_null, evb_psbend); - ptu_run_p(suite, empty_null, evb_tip); - ptu_run_p(suite, empty_null, evb_fup); + ptu_run_p(suite, empty_null, evb_tip | evb_fup); ptu_run_p(suite, pending_null, evb_psbend); - ptu_run_p(suite, pending_null, evb_tip); - ptu_run_p(suite, pending_null, evb_fup); + ptu_run_p(suite, pending_null, evb_tip | evb_fup); ptu_run_p(suite, find_null, evb_psbend, ptev_enabled); - ptu_run_p(suite, find_null, evb_tip, ptev_disabled); - ptu_run_p(suite, find_null, evb_fup, ptev_paging); + ptu_run_p(suite, find_null, evb_tip | evb_fup, ptev_paging); ptu_run_fp(suite, find_empty, efix, evb_psbend, ptev_enabled); - ptu_run_fp(suite, find_empty, efix, evb_tip, ptev_disabled); - ptu_run_fp(suite, find_empty, efix, evb_fup, ptev_paging); + ptu_run_fp(suite, find_empty, efix, evb_tip | evb_fup, ptev_paging); + + ptu_run_fp(suite, find_none_evb, efix, evb_psbend, evb_tip | evb_fup); + ptu_run_fp(suite, find_none_evb, efix, evb_tip | evb_fup, evb_exstop); + ptu_run_fp(suite, find_none_evb, efix, evb_fup, evb_tip); + + ptu_run_fp(suite, find_none_evt, efix, evb_psbend); + ptu_run_fp(suite, find_none_evt, efix, evb_tip | evb_fup); + + ptu_run_fp(suite, find, efix, evb_psbend); + ptu_run_fp(suite, find, efix, evb_tip | evb_fup); + + ptu_run_p(suite, peek_null, evb_psbend); + ptu_run_p(suite, peek_null, evb_tip | evb_fup); - ptu_run_fp(suite, find_none_evb, efix, evb_psbend, ptev_enabled); - ptu_run_fp(suite, find_none_evb, efix, evb_tip, ptev_disabled); - ptu_run_fp(suite, find_none_evb, efix, evb_fup, ptev_paging); + ptu_run_fp(suite, peek_empty, efix, evb_psbend); + ptu_run_fp(suite, peek_empty, efix, evb_tip | evb_fup); - ptu_run_fp(suite, find_none_evt, efix, evb_psbend, ptev_enabled, 3); - ptu_run_fp(suite, find_none_evt, efix, evb_tip, ptev_disabled, 4); - ptu_run_fp(suite, find_none_evt, efix, evb_fup, ptev_paging, 2); + ptu_run_fp(suite, peek_none_evb, efix, evb_psbend, evb_tip | evb_fup); + ptu_run_fp(suite, peek_none_evb, efix, evb_tip | evb_fup, evb_exstop); + ptu_run_fp(suite, peek_none_evb, efix, evb_fup, evb_tip); - ptu_run_fp(suite, find, efix, evb_psbend, ptev_enabled, 0, 3); - ptu_run_fp(suite, find, efix, evb_tip, ptev_disabled, 2, 0); - ptu_run_fp(suite, find, efix, evb_fup, ptev_paging, 1, 4); + ptu_run_fp(suite, peek, efix, evb_psbend); + ptu_run_fp(suite, peek, efix, evb_tip | evb_fup); return ptunit_report(&suite); }
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/test/src/ptunit-ild.c -> _service:tar_scm:v2.1.tar.gz/libipt/test/src/ptunit-ild.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -61,7 +62,8 @@ /* Check that an instruction is decoded and classified correctly. */ static struct ptunit_result ptunit_ild_classify(uint8_t *raw, uint8_t size, enum pt_exec_mode mode, - pti_inst_enum_t iclass) + enum pt_insn_class iclass, + pti_inst_enum_t xclass) { struct pt_insn_ext iext; struct pt_insn insn; @@ -78,7 +80,8 @@ ptu_int_eq(errcode, 0); ptu_uint_eq(insn.size, size); - ptu_int_eq(iext.iclass, iclass); + ptu_int_eq(insn.iclass, iclass); + ptu_int_eq(iext.iclass, xclass); return ptu_passed(); } @@ -113,15 +116,15 @@ #define ptu_decode(insn, size, mode) \ ptu_check(ptunit_ild_decode, insn, size, mode) -#define ptu_classify(insn, size, mode, iclass) \ - ptu_check(ptunit_ild_classify, insn, size, mode, iclass) +#define ptu_classify(insn, size, mode, iclass, xclass) \ + ptu_check(ptunit_ild_classify, insn, size, mode, iclass, xclass) /* Macros to also automatically supply the instruction size. */ #define ptu_decode_s(insn, mode) \ ptu_decode(insn, sizeof(insn), mode) -#define ptu_classify_s(insn, mode, iclass) \ - ptu_classify(insn, sizeof(insn), mode, iclass) +#define ptu_classify_s(insn, mode, iclass, xclass) \ + ptu_classify(insn, sizeof(insn), mode, iclass, xclass) #define ptu_invalid_s(insn, mode) \ ptu_check(ptunit_ild_invalid, insn, sizeof(insn), mode) @@ -140,7 +143,7 @@ { uint8_t insn = { 0xE9, 0x60, 0xF9, 0xFF, 0xFF }; - ptu_classify_s(insn, ptem_64bit, PTI_INST_JMP_E9); + ptu_classify_s(insn, ptem_64bit, ptic_jump, PTI_INST_JMP_E9); return ptu_passed(); } @@ -253,7 +256,7 @@ { uint8_t insn = { 0x0f, 0x05 }; - ptu_classify_s(insn, ptem_64bit, PTI_INST_SYSCALL); + ptu_classify_s(insn, ptem_64bit, ptic_far_call, PTI_INST_SYSCALL); return ptu_passed(); } @@ -262,7 +265,7 @@ { uint8_t insn = { 0x0f, 0x07 }; - ptu_classify_s(insn, ptem_64bit, PTI_INST_SYSRET); + ptu_classify_s(insn, ptem_64bit, ptic_far_return, PTI_INST_SYSRET); return ptu_passed(); } @@ -271,7 +274,7 @@ { uint8_t insn = { 0x0f, 0x34 }; - ptu_classify_s(insn, ptem_64bit, PTI_INST_SYSENTER); + ptu_classify_s(insn, ptem_64bit, ptic_far_call, PTI_INST_SYSENTER); return ptu_passed(); } @@ -280,7 +283,7 @@ { uint8_t insn = { 0x0f, 0x35 }; - ptu_classify_s(insn, ptem_64bit, PTI_INST_SYSEXIT); + ptu_classify_s(insn, ptem_64bit, ptic_far_return, PTI_INST_SYSEXIT); return ptu_passed(); } @@ -289,7 +292,7 @@ { uint8_t insn = { 0xcc }; - ptu_classify_s(insn, ptem_64bit, PTI_INST_INT3); + ptu_classify_s(insn, ptem_64bit, ptic_far_call, PTI_INST_INT3); return ptu_passed(); } @@ -298,7 +301,7 @@ { uint8_t insn = { 0xcd, 0x06 }; - ptu_classify_s(insn, ptem_64bit, PTI_INST_INT); + ptu_classify_s(insn, ptem_64bit, ptic_far_call, PTI_INST_INT); return ptu_passed(); } @@ -307,7 +310,7 @@ { uint8_t insn = { 0xcf }; - ptu_classify_s(insn, ptem_64bit, PTI_INST_IRET); + ptu_classify_s(insn, ptem_64bit, ptic_far_return, PTI_INST_IRET); return ptu_passed(); } @@ -316,7 +319,7 @@ { uint8_t insn = { 0x9a, 0x00, 0x00, 0x00, 0x00 }; - ptu_classify_s(insn, ptem_16bit, PTI_INST_CALL_9A); + ptu_classify_s(insn, ptem_16bit, ptic_far_call, PTI_INST_CALL_9A); return ptu_passed(); } @@ -325,7 +328,7 @@ { uint8_t insn = { 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - ptu_classify_s(insn, ptem_32bit, PTI_INST_CALL_9A); + ptu_classify_s(insn, ptem_32bit, ptic_far_call, PTI_INST_CALL_9A); return ptu_passed(); } @@ -334,7 +337,7 @@ { uint8_t insn = { 0xff, 0x1c, 0x25, 0x00, 0x00, 0x00, 0x00 }; - ptu_classify_s(insn, ptem_64bit, PTI_INST_CALL_FFr3); + ptu_classify_s(insn, ptem_64bit, ptic_far_call, PTI_INST_CALL_FFr3); return ptu_passed(); } @@ -343,7 +346,7 @@ { uint8_t insn = { 0xff, 0x2c, 0x25, 0x00, 0x00, 0x00, 0x00 }; - ptu_classify_s(insn, ptem_64bit, PTI_INST_JMP_FFr5); + ptu_classify_s(insn, ptem_64bit, ptic_far_jump, PTI_INST_JMP_FFr5); return ptu_passed(); } @@ -352,7 +355,7 @@ { uint8_t insn = { 0xea, 0x00, 0x00, 0x00, 0x00 }; - ptu_classify_s(insn, ptem_16bit, PTI_INST_JMP_EA); + ptu_classify_s(insn, ptem_16bit, ptic_far_jump, PTI_INST_JMP_EA); return ptu_passed(); } @@ -361,7 +364,7 @@ { uint8_t insn = { 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - ptu_classify_s(insn, ptem_32bit, PTI_INST_JMP_EA); + ptu_classify_s(insn, ptem_32bit, ptic_far_jump, PTI_INST_JMP_EA); return ptu_passed(); } @@ -370,7 +373,7 @@ { uint8_t insn = { 0xca, 0x00, 0x00 }; - ptu_classify_s(insn, ptem_64bit, PTI_INST_RET_CA); + ptu_classify_s(insn, ptem_64bit, ptic_far_return, PTI_INST_RET_CA); return ptu_passed(); } @@ -379,7 +382,7 @@ { uint8_t insn = { 0x0f, 0x01, 0xc2 }; - ptu_classify_s(insn, ptem_64bit, PTI_INST_VMLAUNCH); + ptu_classify_s(insn, ptem_64bit, ptic_far_return, PTI_INST_VMLAUNCH); return ptu_passed(); } @@ -388,7 +391,7 @@ { uint8_t insn = { 0x0f, 0x01, 0xc3 }; - ptu_classify_s(insn, ptem_64bit, PTI_INST_VMRESUME); + ptu_classify_s(insn, ptem_64bit, ptic_far_return, PTI_INST_VMRESUME); return ptu_passed(); } @@ -397,7 +400,7 @@ { uint8_t insn = { 0x0f, 0x01, 0xc1 }; - ptu_classify_s(insn, ptem_64bit, PTI_INST_VMCALL); + ptu_classify_s(insn, ptem_64bit, ptic_far_call, PTI_INST_VMCALL); return ptu_passed(); } @@ -406,7 +409,7 @@ { uint8_t insn = { 0x0f, 0xc7, 0x30 }; - ptu_classify_s(insn, ptem_64bit, PTI_INST_VMPTRLD); + ptu_classify_s(insn, ptem_64bit, ptic_other, PTI_INST_VMPTRLD); return ptu_passed(); } @@ -415,7 +418,7 @@ { uint8_t insn = { 0xe3, 0x00 }; - ptu_classify_s(insn, ptem_64bit, PTI_INST_JrCXZ); + ptu_classify_s(insn, ptem_64bit, ptic_cond_jump, PTI_INST_JrCXZ); return ptu_passed(); } @@ -650,9 +653,9 @@ { uint8_t insn = { 0xf3, 0x0f, 0xae, 0xe7 }; - ptu_classify_s(insn, ptem_64bit, PTI_INST_PTWRITE); - ptu_classify_s(insn, ptem_32bit, PTI_INST_PTWRITE); - ptu_classify_s(insn, ptem_16bit, PTI_INST_PTWRITE); + ptu_classify_s(insn, ptem_64bit, ptic_ptwrite, PTI_INST_PTWRITE); + ptu_classify_s(insn, ptem_32bit, ptic_ptwrite, PTI_INST_PTWRITE); + ptu_classify_s(insn, ptem_16bit, ptic_ptwrite, PTI_INST_PTWRITE); return ptu_passed(); } @@ -661,9 +664,9 @@ { uint8_t insn = { 0xf3, 0x0f, 0xae, 0x67, 0xcc }; - ptu_classify_s(insn, ptem_64bit, PTI_INST_PTWRITE); - ptu_classify_s(insn, ptem_32bit, PTI_INST_PTWRITE); - ptu_classify_s(insn, ptem_16bit, PTI_INST_PTWRITE); + ptu_classify_s(insn, ptem_64bit, ptic_ptwrite, PTI_INST_PTWRITE); + ptu_classify_s(insn, ptem_32bit, ptic_ptwrite, PTI_INST_PTWRITE); + ptu_classify_s(insn, ptem_16bit, ptic_ptwrite, PTI_INST_PTWRITE); return ptu_passed(); } @@ -672,7 +675,7 @@ { uint8_t insn = { 0xf3, 0x48, 0x0f, 0xae, 0xe7 }; - ptu_classify_s(insn, ptem_64bit, PTI_INST_PTWRITE); + ptu_classify_s(insn, ptem_64bit, ptic_ptwrite, PTI_INST_PTWRITE); return ptu_passed(); } @@ -681,7 +684,7 @@ { uint8_t insn = { 0xf3, 0x48, 0x0f, 0xae, 0x67, 0xcc }; - ptu_classify_s(insn, ptem_64bit, PTI_INST_PTWRITE); + ptu_classify_s(insn, ptem_64bit, ptic_ptwrite, PTI_INST_PTWRITE); return ptu_passed(); } @@ -690,7 +693,17 @@ { uint8_t insn = { 0xf3, 0x0f, 0x01, 0xec }; - ptu_classify_s(insn, ptem_64bit, PTI_INST_UIRET); + ptu_classify_s(insn, ptem_64bit, ptic_far_return, PTI_INST_UIRET); + + return ptu_passed(); +} + +static struct ptunit_result into(void) +{ + uint8_t insn = { 0xce }; + + ptu_classify_s(insn, ptem_32bit, ptic_far_call, PTI_INST_INTO); + ptu_classify_s(insn, ptem_16bit, ptic_far_call, PTI_INST_INTO); return ptu_passed(); } @@ -762,6 +775,7 @@ ptu_run(suite, ptwrite_r64); ptu_run(suite, ptwrite_m64); ptu_run(suite, uiret); + ptu_run(suite, into); return ptunit_report(&suite); }
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/test/src/ptunit-image.c -> _service:tar_scm:v2.1.tar.gz/libipt/test/src/ptunit-image.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -208,15 +209,16 @@ return section->size; } -struct pt_section *pt_mk_section(const char *file, uint64_t offset, - uint64_t size) +int pt_mk_section(struct pt_section **psection, const char *filename, + uint64_t offset, uint64_t size) { - (void) file; + (void) psection; + (void) filename; (void) offset; (void) size; /* This function is not used by our tests. */ - return NULL; + return -pte_not_supported; } int pt_section_get(struct pt_section *section)
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/test/src/ptunit-image_section_cache.c -> _service:tar_scm:v2.1.tar.gz/libipt/test/src/ptunit-image_section_cache.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2016-2022, Intel Corporation + * Copyright (c) 2016-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -27,491 +28,40 @@ */ #include "pt_image_section_cache.h" +#include "pt_block_cache.h" +#include "pt_section.h" #include "ptunit_threads.h" +#include "ptunit_mkfile.h" #include "intel-pt.h" #include <stdlib.h> +#include <stdio.h> -struct pt_section { - /* The filename. We only support string literals for testing. */ - const char *filename; - - /* The file offset and size. */ - uint64_t offset; - uint64_t size; - - /* The bcache size. */ - uint64_t bcsize; - - /* The iscache back link. */ - struct pt_image_section_cache *iscache; - - /* The file content. */ - uint8_t content0x10; - - /* The use count. */ - int ucount; - - /* The attach count. */ - int acount; - - /* The map count. */ - int mcount; - -#if defined(FEATURE_THREADS) - /* A lock protecting this section. */ - mtx_t lock; - /* A lock protecting the iscache and acount fields. */ - mtx_t alock; -#endif /* defined(FEATURE_THREADS) */ -}; - -extern struct pt_section *pt_mk_section(const char *filename, uint64_t offset, - uint64_t size); - -extern int pt_section_get(struct pt_section *section); -extern int pt_section_put(struct pt_section *section); -extern int pt_section_attach(struct pt_section *section, - struct pt_image_section_cache *iscache); -extern int pt_section_detach(struct pt_section *section, - struct pt_image_section_cache *iscache); - -extern int pt_section_map(struct pt_section *section); -extern int pt_section_map_share(struct pt_section *section); -extern int pt_section_unmap(struct pt_section *section); -extern int pt_section_request_bcache(struct pt_section *section); - -extern const char *pt_section_filename(const struct pt_section *section); -extern uint64_t pt_section_offset(const struct pt_section *section); -extern uint64_t pt_section_size(const struct pt_section *section); -extern int pt_section_memsize(struct pt_section *section, uint64_t *size); - -extern int pt_section_read(const struct pt_section *section, uint8_t *buffer, - uint16_t size, uint64_t offset); - - -struct pt_section *pt_mk_section(const char *filename, uint64_t offset, - uint64_t size) -{ - struct pt_section *section; - - section = malloc(sizeof(*section)); - if (section) { - uint8_t idx; - - memset(section, 0, sizeof(*section)); - section->filename = filename; - section->offset = offset; - section->size = size; - section->ucount = 1; - - for (idx = 0; idx < sizeof(section->content); ++idx) - section->contentidx = idx; - -#if defined(FEATURE_THREADS) - { - int errcode; - - errcode = mtx_init(§ion->lock, mtx_plain); - if (errcode != thrd_success) { - free(section); - section = NULL; - } - - errcode = mtx_init(§ion->alock, mtx_plain); - if (errcode != thrd_success) { - mtx_destroy(§ion->lock); - free(section); - section = NULL; - } - } -#endif /* defined(FEATURE_THREADS) */ - } - - return section; -} - -static int pt_section_lock(struct pt_section *section) -{ - if (!section) - return -pte_internal; - -#if defined(FEATURE_THREADS) - { - int errcode; - - errcode = mtx_lock(§ion->lock); - if (errcode != thrd_success) - return -pte_bad_lock; - } -#endif /* defined(FEATURE_THREADS) */ - - return 0; -} - -static int pt_section_unlock(struct pt_section *section) -{ - if (!section) - return -pte_internal; - -#if defined(FEATURE_THREADS) - { - int errcode; - - errcode = mtx_unlock(§ion->lock); - if (errcode != thrd_success) - return -pte_bad_lock; - } -#endif /* defined(FEATURE_THREADS) */ - - return 0; -} - -static int pt_section_lock_attach(struct pt_section *section) -{ - if (!section) - return -pte_internal; - -#if defined(FEATURE_THREADS) - { - int errcode; - - errcode = mtx_lock(§ion->alock); - if (errcode != thrd_success) - return -pte_bad_lock; - } -#endif /* defined(FEATURE_THREADS) */ - - return 0; -} - -static int pt_section_unlock_attach(struct pt_section *section) -{ - if (!section) - return -pte_internal; - -#if defined(FEATURE_THREADS) - { - int errcode; - - errcode = mtx_unlock(§ion->alock); - if (errcode != thrd_success) - return -pte_bad_lock; - } -#endif /* defined(FEATURE_THREADS) */ - - return 0; -} - -int pt_section_get(struct pt_section *section) -{ - int errcode, ucount; - - if (!section) - return -pte_internal; - - errcode = pt_section_lock(section); - if (errcode < 0) - return errcode; - - ucount = ++section->ucount; - - errcode = pt_section_unlock(section); - if (errcode < 0) - return errcode; - - if (!ucount) - return -pte_internal; - - return 0; -} - -int pt_section_put(struct pt_section *section) -{ - int errcode, ucount; - - if (!section) - return -pte_internal; - - errcode = pt_section_lock(section); - if (errcode < 0) - return errcode; - - ucount = --section->ucount; - - errcode = pt_section_unlock(section); - if (errcode < 0) - return errcode; - - if (!ucount) { -#if defined(FEATURE_THREADS) - mtx_destroy(§ion->alock); - mtx_destroy(§ion->lock); -#endif /* defined(FEATURE_THREADS) */ - free(section); - } - - return 0; -} - -int pt_section_attach(struct pt_section *section, - struct pt_image_section_cache *iscache) -{ - int errcode, ucount, acount; - - if (!section || !iscache) - return -pte_internal; - - errcode = pt_section_lock_attach(section); - if (errcode < 0) - return errcode; - - ucount = section->ucount; - acount = section->acount; - if (!acount) { - if (section->iscache || !ucount) - goto out_unlock; - - section->iscache = iscache; - section->acount = 1; - - return pt_section_unlock_attach(section); - } - - acount += 1; - if (!acount) { - (void) pt_section_unlock_attach(section); - return -pte_overflow; - } - - if (ucount < acount) - goto out_unlock; - - if (section->iscache != iscache) - goto out_unlock; - - section->acount = acount; - - return pt_section_unlock_attach(section); - - out_unlock: - (void) pt_section_unlock_attach(section); - return -pte_internal; -} - -int pt_section_detach(struct pt_section *section, - struct pt_image_section_cache *iscache) +struct pt_block_cache *pt_bcache_alloc(uint64_t nentries) { - int errcode, ucount, acount; - - if (!section || !iscache) - return -pte_internal; - - errcode = pt_section_lock_attach(section); - if (errcode < 0) - return errcode; - - if (section->iscache != iscache) - goto out_unlock; - - acount = section->acount; - if (!acount) - goto out_unlock; - - acount -= 1; - ucount = section->ucount; - if (ucount < acount) - goto out_unlock; - - section->acount = acount; - if (!acount) - section->iscache = NULL; - - return pt_section_unlock_attach(section); - - out_unlock: - (void) pt_section_unlock_attach(section); - return -pte_internal; -} - -int pt_section_map(struct pt_section *section) -{ - struct pt_image_section_cache *iscache; - int errcode, status; - - if (!section) - return -pte_internal; - - errcode = pt_section_map_share(section); - if (errcode < 0) - return errcode; - - errcode = pt_section_lock_attach(section); - if (errcode < 0) - return errcode; - - status = 0; - iscache = section->iscache; - if (iscache) - status = pt_iscache_notify_map(iscache, section); - - errcode = pt_section_unlock_attach(section); - - return (status < 0) ? status : errcode; -} - -int pt_section_map_share(struct pt_section *section) -{ - int errcode, mcount; - - if (!section) - return -pte_internal; - - errcode = pt_section_lock(section); - if (errcode < 0) - return errcode; - - mcount = ++section->mcount; - - errcode = pt_section_unlock(section); - if (errcode < 0) - return errcode; - - if (mcount <= 0) - return -pte_internal; - - return 0; -} - -int pt_section_unmap(struct pt_section *section) -{ - int errcode, mcount; - - if (!section) - return -pte_internal; - - errcode = pt_section_lock(section); - if (errcode < 0) - return errcode; - - section->bcsize = 0ull; - mcount = --section->mcount; - - errcode = pt_section_unlock(section); - if (errcode < 0) - return errcode; - - if (mcount < 0) - return -pte_internal; - - return 0; -} - -int pt_section_request_bcache(struct pt_section *section) -{ - struct pt_image_section_cache *iscache; - uint64_t memsize; - int errcode; - - if (!section) - return -pte_internal; - - errcode = pt_section_lock_attach(section); - if (errcode < 0) - return errcode; - - errcode = pt_section_lock(section); - if (errcode < 0) - goto out_alock; + struct pt_block_cache *bcache; - if (section->bcsize) - goto out_lock; - - section->bcsize = section->size * 3; - memsize = section->size + section->bcsize; - - errcode = pt_section_unlock(section); - if (errcode < 0) - goto out_alock; - - iscache = section->iscache; - if (iscache) { - errcode = pt_iscache_notify_resize(iscache, section, memsize); - if (errcode < 0) - goto out_alock; - } - - return pt_section_unlock_attach(section); - - -out_lock: - (void) pt_section_unlock(section); - -out_alock: - (void) pt_section_unlock_attach(section); - return errcode; -} - -const char *pt_section_filename(const struct pt_section *section) -{ - if (!section) + if (!nentries || (UINT32_MAX < nentries)) return NULL; - return section->filename; -} - -uint64_t pt_section_offset(const struct pt_section *section) -{ - if (!section) - return 0ull; - - return section->offset; -} - -uint64_t pt_section_size(const struct pt_section *section) -{ - if (!section) - return 0ull; + /* The cache is not really used by tests. It suffices to allocate only + * the cache struct with the single default entry. + * + * We still set the number of entries to the requested size. + */ + bcache = malloc(sizeof(*bcache)); + if (bcache) + bcache->nentries = (uint32_t) nentries; - return section->size; + return bcache; } -int pt_section_memsize(struct pt_section *section, uint64_t *size) +void pt_bcache_free(struct pt_block_cache *bcache) { - if (!section || !size) - return -pte_internal; - - *size = section->mcount ? section->size + section->bcsize : 0ull; - - return 0; -} - -int pt_section_read(const struct pt_section *section, uint8_t *buffer, - uint16_t size, uint64_t offset) -{ - uint64_t begin, end, max; - - if (!section || !buffer) - return -pte_internal; - - begin = offset; - end = begin + size; - max = sizeof(section->content); - - if (max <= begin) - return -pte_nomap; - - if (max < end) - end = max; - - if (end <= begin) - return -pte_invalid; - - memcpy(buffer, §ion->contentbegin, (size_t) (end - begin)); - return (int) (end - begin); + free(bcache); } enum { @@ -537,25 +87,55 @@ /* A bunch of test sections. */ struct pt_section *sectionnum_sections; + /* A test file and its name. */ + char *fname; + FILE *file; + /* The test fixture initialization and finalization functions. */ struct ptunit_result (*init)(struct iscache_fixture *); struct ptunit_result (*fini)(struct iscache_fixture *); }; +static struct ptunit_result dfix_init_file(char **pname, FILE **pfile) +{ + FILE *file; + int errcode, bytes; + + errcode = ptunit_mkfile(pfile, pname, "wb"); + ptu_int_eq(errcode, 0); + + ptu_ptr(pfile); + file = *pfile; + for (bytes = 0; bytes < 0x90; bytes++) { + uint8_t buffer; + size_t written; + + buffer = (uint8_t) bytes; + + written = fwrite(&buffer, 1, sizeof(buffer), file); + ptu_uint_eq(written, sizeof(buffer)); + } + fflush(file); + + return ptu_passed(); +} + static struct ptunit_result dfix_init(struct iscache_fixture *cfix) { int idx; ptu_test(ptunit_thrd_init, &cfix->thrd); + ptu_test(dfix_init_file, &cfix->fname, &cfix->file); memset(cfix->section, 0, sizeof(cfix->section)); - for (idx = 0; idx < num_sections; ++idx) { struct pt_section *section; + int errcode; - section = pt_mk_section("some-filename", - idx % 3 == 0 ? 0x1000 : 0x2000, - idx % 2 == 0 ? 0x1000 : 0x2000); + errcode = pt_mk_section(§ion, cfix->fname, + idx % 3 == 0 ? 0x10 : 0x20, + idx % 2 == 0 ? 0x40 : 0x60); + ptu_int_eq(errcode, 0); ptu_ptr(section); cfix->sectionidx = section; @@ -595,6 +175,8 @@ static struct ptunit_result cfix_fini(struct iscache_fixture *cfix) { + char *filename; + FILE *file; int idx, errcode; ptu_test(ptunit_thrd_fini, &cfix->thrd); @@ -614,6 +196,41 @@ ptu_int_eq(errcode, 0); } + filename = cfix->fname; + file = cfix->file; + cfix->fname = NULL; + cfix->file = NULL; + + /* Try removing the file while we still have it open to avoid races + * with others re-using the temporary filename. + * + * On some systems that may not be possible and we can choose between: + * + * - guaranteed leaking files or + * - running the risk of removing someone elses file + * + * We choose the latter. Assuming those systems behave consistently, + * removing someone elses file should only succeed if it isn't open at + * the moment we try removing it. Given that this is a temporary file, + * we should be able to rule out accidental name clashes with + * non-termporary files. + */ + if (filename && file) { + errcode = remove(filename); + if (!errcode) { + free(filename); + filename = NULL; + } + } + + if (file) + fclose(file); + + if (filename) { + (void) remove(filename); + free(filename); + } + return ptu_passed(); } @@ -802,7 +419,8 @@ { int isid; - isid = pt_iscache_add_file(&cfix->iscache, "name", 0ull, 1ull, 0ull); + isid = pt_iscache_add_file(&cfix->iscache, cfix->fname, + 0ull, 1ull, 0ull); ptu_int_gt(isid, 0); return ptu_passed(); @@ -1111,10 +729,12 @@ { int isid2; - isid0 = pt_iscache_add_file(&cfix->iscache, "name", 0ull, 1ull, 0ull); + isid0 = pt_iscache_add_file(&cfix->iscache, cfix->fname, + 0ull, 1ull, 0ull); ptu_int_gt(isid0, 0); - isid1 = pt_iscache_add_file(&cfix->iscache, "name", 0ull, 1ull, 0ull); + isid1 = pt_iscache_add_file(&cfix->iscache, cfix->fname, + 0ull, 1ull, 0ull); ptu_int_gt(isid1, 0); /* The second add should be ignored. */ @@ -1128,10 +748,12 @@ { int isid2; - isid0 = pt_iscache_add_file(&cfix->iscache, "name", 0ull, 1ull, 0ull); + isid0 = pt_iscache_add_file(&cfix->iscache, cfix->fname, + 0ull, 1ull, 0ull); ptu_int_gt(isid0, 0); - isid1 = pt_iscache_add_file(&cfix->iscache, "name", 0ull, 1ull, 1ull); + isid1 = pt_iscache_add_file(&cfix->iscache, cfix->fname, + 0ull, 1ull, 1ull); ptu_int_gt(isid1, 0); /* We must get different identifiers. */ @@ -1145,10 +767,12 @@ { int isid2; - isid0 = pt_iscache_add_file(&cfix->iscache, "name", 0ull, 1ull, 0ull); + isid0 = pt_iscache_add_file(&cfix->iscache, cfix->fname, + 0ull, 1ull, 0ull); ptu_int_gt(isid0, 0); - isid1 = pt_iscache_add_file(&cfix->iscache, "name", 1ull, 1ull, 0ull); + isid1 = pt_iscache_add_file(&cfix->iscache, cfix->fname, + 1ull, 1ull, 0ull); ptu_int_gt(isid1, 0); /* We must get different identifiers. */ @@ -1167,8 +791,8 @@ status = pt_iscache_read(&cfix->iscache, buffer, 2ull, isid, 0xa008ull); ptu_int_eq(status, 2); - ptu_uint_eq(buffer0, 0x8); - ptu_uint_eq(buffer1, 0x9); + ptu_uint_eq(buffer0, 0x18); + ptu_uint_eq(buffer1, 0x19); ptu_uint_eq(buffer2, 0xcc); return ptu_passed(); @@ -1183,9 +807,9 @@ ptu_int_gt(isid, 0); status = pt_iscache_read(&cfix->iscache, buffer, sizeof(buffer), isid, - 0xa00full); + 0xa03full); ptu_int_eq(status, 1); - ptu_uint_eq(buffer0, 0xf); + ptu_uint_eq(buffer0, 0x4f); ptu_uint_eq(buffer1, 0xcc); return ptu_passed(); @@ -1224,9 +848,10 @@ static struct ptunit_result lru_map(struct iscache_fixture *cfix) { + uint64_t size; int status, isid; - cfix->iscache.limit = cfix->section0->size; + cfix->iscache.limit = 0x8000; ptu_uint_eq(cfix->iscache.used, 0ull); ptu_null(cfix->iscache.lru); @@ -1236,13 +861,16 @@ status = pt_section_map(cfix->section0); ptu_int_eq(status, 0); + status = pt_section_memsize(cfix->section0, &size); + ptu_int_eq(status, 0); + status = pt_section_unmap(cfix->section0); ptu_int_eq(status, 0); ptu_ptr(cfix->iscache.lru); ptu_ptr_eq(cfix->iscache.lru->section, cfix->section0); ptu_null(cfix->iscache.lru->next); - ptu_uint_eq(cfix->iscache.used, cfix->section0->size); + ptu_uint_eq(cfix->iscache.used, size); return ptu_passed(); } @@ -1252,7 +880,7 @@ uint8_t buffer = { 0xcc, 0xcc, 0xcc }; int status, isid; - cfix->iscache.limit = cfix->section0->size; + cfix->iscache.limit = 0x8000; ptu_uint_eq(cfix->iscache.used, 0ull); ptu_null(cfix->iscache.lru); @@ -1265,7 +893,7 @@ ptu_ptr(cfix->iscache.lru); ptu_ptr_eq(cfix->iscache.lru->section, cfix->section0); ptu_null(cfix->iscache.lru->next); - ptu_uint_eq(cfix->iscache.used, cfix->section0->size); + ptu_uint_ge(cfix->iscache.used, cfix->section0->size); return ptu_passed(); } @@ -1296,7 +924,7 @@ ptu_ptr(cfix->iscache.lru); ptu_ptr_eq(cfix->iscache.lru->section, cfix->section0); ptu_null(cfix->iscache.lru->next); - ptu_uint_eq(cfix->iscache.used, cfix->section0->size); + ptu_uint_ge(cfix->iscache.used, cfix->section0->size); return ptu_passed(); } @@ -1328,7 +956,7 @@ { int status, isid; - cfix->iscache.limit = cfix->section0->size + cfix->section1->size; + cfix->iscache.limit = 0x8000; ptu_uint_eq(cfix->iscache.used, 0ull); ptu_null(cfix->iscache.lru); @@ -1355,7 +983,7 @@ ptu_ptr(cfix->iscache.lru->next); ptu_ptr_eq(cfix->iscache.lru->next->section, cfix->section0); ptu_null(cfix->iscache.lru->next->next); - ptu_uint_eq(cfix->iscache.used, + ptu_uint_ge(cfix->iscache.used, cfix->section0->size + cfix->section1->size); return ptu_passed(); @@ -1365,7 +993,7 @@ { int status, isid; - cfix->iscache.limit = cfix->section0->size + cfix->section1->size; + cfix->iscache.limit = 0x8000; ptu_uint_eq(cfix->iscache.used, 0ull); ptu_null(cfix->iscache.lru); @@ -1398,7 +1026,7 @@ ptu_ptr(cfix->iscache.lru->next); ptu_ptr_eq(cfix->iscache.lru->next->section, cfix->section1); ptu_null(cfix->iscache.lru->next->next); - ptu_uint_eq(cfix->iscache.used, + ptu_uint_ge(cfix->iscache.used, cfix->section0->size + cfix->section1->size); return ptu_passed(); @@ -1434,7 +1062,9 @@ ptu_ptr(cfix->iscache.lru); ptu_ptr_eq(cfix->iscache.lru->section, cfix->section1); ptu_null(cfix->iscache.lru->next); - ptu_uint_eq(cfix->iscache.used, cfix->section1->size); + ptu_uint_ge(cfix->iscache.used, cfix->section1->size); + ptu_uint_lt(cfix->iscache.used, cfix->section0->size + + cfix->section1->size); return ptu_passed(); } @@ -1472,7 +1102,9 @@ ptu_ptr(cfix->iscache.lru); ptu_ptr_eq(cfix->iscache.lru->section, cfix->section0); ptu_null(cfix->iscache.lru->next); - ptu_uint_eq(cfix->iscache.used, 4 * cfix->section0->size); + ptu_uint_ge(cfix->iscache.used, 4 * cfix->section0->size); + ptu_uint_lt(cfix->iscache.used, 4 * cfix->section0->size + + cfix->section1->size); return ptu_passed(); } @@ -1481,7 +1113,9 @@ { int status, isid; - cfix->iscache.limit = cfix->section0->size + cfix->section1->size; + /* Add section offsets to allow both sections to be mmapped. */ + cfix->iscache.limit = cfix->section0->size + cfix->section1->size + + 0x30; ptu_uint_eq(cfix->iscache.used, 0ull); ptu_null(cfix->iscache.lru); @@ -1546,7 +1180,9 @@ ptu_ptr(cfix->iscache.lru); ptu_ptr_eq(cfix->iscache.lru->section, cfix->section1); ptu_null(cfix->iscache.lru->next); - ptu_uint_eq(cfix->iscache.used, cfix->section1->size); + ptu_uint_ge(cfix->iscache.used, cfix->section1->size); + ptu_uint_lt(cfix->iscache.used, cfix->section0->size + + cfix->section1->size); return ptu_passed(); } @@ -1555,7 +1191,7 @@ { int status, isid; - cfix->iscache.limit = cfix->section0->size; + cfix->iscache.limit = 0x8000; ptu_uint_eq(cfix->iscache.used, 0ull); ptu_null(cfix->iscache.lru); @@ -1590,7 +1226,7 @@ uint64_t laddr; int sec; - laddr = 0x1000ull * ((uint64_t)it % 23); + laddr = 0x10ull * ((uint64_t)it % 23); for (sec = 0; sec < num_sections; ++sec) { struct pt_section *section; @@ -1644,16 +1280,16 @@ uint64_t offset, size, laddr; int sec; - offset = it % 7 == 0 ? 0x1000 : 0x2000; - size = it % 5 == 0 ? 0x1000 : 0x2000; - laddr = it % 3 == 0 ? 0x1000 : 0x2000; + offset = it % 7 == 0 ? 0x10 : 0x20; + size = it % 5 == 0 ? 0x10 : 0x20; + laddr = it % 3 == 0 ? 0x10 : 0x20; for (sec = 0; sec < num_sections; ++sec) { struct pt_section *section; uint64_t addr; int isid, errcode; - isid = pt_iscache_add_file(&cfix->iscache, "name", + isid = pt_iscache_add_file(&cfix->iscache, cfix->fname, offset, size, laddr); if (isid < 0) return isid; @@ -1855,11 +1491,11 @@ uint64_t offset, size, laddr, addr; int isid, errcode; - offset = it % 7 < 4 ? 0x1000 : 0x2000; - size = it % 5 < 3 ? 0x1000 : 0x2000; - laddr = it % 3 < 2 ? 0x1000 : 0x2000; + offset = it % 7 < 4 ? 0x10 : 0x20; + size = it % 5 < 3 ? 0x10 : 0x20; + laddr = it % 3 < 2 ? 0x10 : 0x20; - isid = pt_iscache_add_file(&cfix->iscache, "name", + isid = pt_iscache_add_file(&cfix->iscache, cfix->fname, offset, size, laddr); if (isid < 0) return isid; @@ -1901,11 +1537,11 @@ uint64_t offset, size, laddr; int isid, errcode; - offset = it % 7 < 4 ? 0x1000 : 0x2000; - size = it % 5 < 3 ? 0x1000 : 0x2000; - laddr = it % 3 < 2 ? 0x1000 : 0x2000; + offset = it % 7 < 4 ? 0x10 : 0x20; + size = it % 5 < 3 ? 0x10 : 0x20; + laddr = it % 3 < 2 ? 0x10 : 0x20; - isid = pt_iscache_add_file(&cfix->iscache, "name", + isid = pt_iscache_add_file(&cfix->iscache, cfix->fname, offset, size, laddr); if (isid < 0) return isid;
View file
_service:tar_scm:v2.1.tar.gz/libipt/test/src/ptunit-insn_decoder.c
Added
@@ -0,0 +1,354 @@ +/* + * Copyright (c) 2019-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "ptunit.h" + +#include "pt_insn_decoder.h" + +#include "intel-pt.h" + + +/* A test fixture providing a decoder operating on a small buffer. */ +struct test_fixture { + /* The packet_decoder. */ + struct pt_insn_decoder decoder; + + /* The configuration. */ + struct pt_config config; + + /* The buffer it operates on. */ + uint8_t buffer24; + + /* The test fixture initialization and finalization functions. */ + struct ptunit_result (*init)(struct test_fixture *tfix); + struct ptunit_result (*fini)(struct test_fixture *tfix); +}; + +static struct ptunit_result tfix_init(struct test_fixture *tfix) +{ + struct pt_config *config; + uint8_t *buffer; + int errcode; + + config = &tfix->config; + buffer = tfix->buffer; + + memset(buffer, 0, sizeof(tfix->buffer)); + + pt_config_init(config); + config->begin = buffer; + config->end = buffer + sizeof(tfix->buffer); + + errcode = pt_insn_decoder_init(&tfix->decoder, config); + ptu_int_eq(errcode, 0); + + return ptu_passed(); +} + +static struct ptunit_result decoder_init_null(void) +{ + struct pt_insn_decoder decoder; + struct pt_config config; + int errcode; + + memset(&config, 0, sizeof(config)); + + errcode = pt_insn_decoder_init(NULL, &config); + ptu_int_eq(errcode, -pte_internal); + + errcode = pt_insn_decoder_init(&decoder, NULL); + ptu_int_eq(errcode, -pte_invalid); + + return ptu_passed(); +} + +static struct ptunit_result decoder_fini_null(void) +{ + pt_insn_decoder_fini(NULL); + + return ptu_passed(); +} + +static struct ptunit_result alloc_decoder_null(void) +{ + struct pt_insn_decoder *decoder; + + decoder = pt_insn_alloc_decoder(NULL); + ptu_null(decoder); + + return ptu_passed(); +} + +static struct ptunit_result free_decoder_null(void) +{ + pt_insn_free_decoder(NULL); + + return ptu_passed(); +} + +static struct ptunit_result sync_forward_null(void) +{ + int errcode; + + errcode = pt_insn_sync_forward(NULL); + ptu_int_eq(errcode, -pte_invalid); + + return ptu_passed(); +} + +static struct ptunit_result sync_backward_null(void) +{ + int errcode; + + errcode = pt_insn_sync_backward(NULL); + ptu_int_eq(errcode, -pte_invalid); + + return ptu_passed(); +} + +static struct ptunit_result sync_set_null(void) +{ + int errcode; + + errcode = pt_insn_sync_set(NULL, 0ull); + ptu_int_eq(errcode, -pte_invalid); + + return ptu_passed(); +} + +static struct ptunit_result sync_set_eos(struct test_fixture *tfix) +{ + int errcode; + + errcode = pt_insn_sync_set(&tfix->decoder, sizeof(tfix->buffer) + 1); + ptu_int_eq(errcode, -pte_eos); + + return ptu_passed(); +} + +static struct ptunit_result get_offset_null(void) +{ + struct pt_insn_decoder decoder; + uint64_t offset; + int errcode; + + errcode = pt_insn_get_offset(NULL, &offset); + ptu_int_eq(errcode, -pte_invalid); + + errcode = pt_insn_get_offset(&decoder, NULL); + ptu_int_eq(errcode, -pte_invalid); + + return ptu_passed(); +} + +static struct ptunit_result get_offset_init(struct test_fixture *tfix) +{ + uint64_t offset; + int errcode; + + errcode = pt_insn_get_offset(&tfix->decoder, &offset); + ptu_int_eq(errcode, -pte_nosync); + + return ptu_passed(); +} + +static struct ptunit_result get_sync_offset_null(void) +{ + struct pt_insn_decoder decoder; + uint64_t offset; + int errcode; + + errcode = pt_insn_get_sync_offset(NULL, &offset); + ptu_int_eq(errcode, -pte_invalid); + + errcode = pt_insn_get_sync_offset(&decoder, NULL); + ptu_int_eq(errcode, -pte_invalid); + + return ptu_passed(); +} + +static struct ptunit_result get_config_null(void) +{ + const struct pt_config *config; + + config = pt_insn_get_config(NULL); + ptu_null(config); + + return ptu_passed(); +} + +static struct ptunit_result get_image_null(void) +{ + const struct pt_image *image; + + image = pt_insn_get_image(NULL); + ptu_null(image); + + return ptu_passed(); +} + +static struct ptunit_result set_image_null(void) +{ + struct pt_image image; + int errcode; + + errcode = pt_insn_set_image(NULL, &image); + ptu_int_eq(errcode, -pte_invalid); + + errcode = pt_insn_set_image(NULL, NULL); + ptu_int_eq(errcode, -pte_invalid); + + return ptu_passed(); +} + +static struct ptunit_result get_config(struct test_fixture *tfix) +{ + const struct pt_config *config; + + config = pt_insn_get_config(&tfix->decoder); + ptu_ptr(config); + + return ptu_passed(); +} + +static struct ptunit_result time_null(void) +{ + struct pt_insn_decoder decoder; + uint64_t time; + uint32_t lost_mtc, lost_cyc; + int errcode; + + errcode = pt_insn_time(NULL, &time, &lost_mtc, &lost_cyc); + ptu_int_eq(errcode, -pte_invalid); + + errcode = pt_insn_time(&decoder, NULL, &lost_mtc, &lost_cyc); + ptu_int_eq(errcode, -pte_invalid); + + return ptu_passed(); +} + +static struct ptunit_result cbr_null(void) +{ + struct pt_insn_decoder decoder; + uint32_t cbr; + int errcode; + + errcode = pt_insn_core_bus_ratio(NULL, &cbr); + ptu_int_eq(errcode, -pte_invalid); + + errcode = pt_insn_core_bus_ratio(&decoder, NULL); + ptu_int_eq(errcode, -pte_invalid); + + return ptu_passed(); +} + +static struct ptunit_result asid_null(void) +{ + struct pt_insn_decoder decoder; + struct pt_asid asid; + int errcode; + + errcode = pt_insn_asid(NULL, &asid, sizeof(asid)); + ptu_int_eq(errcode, -pte_invalid); + + errcode = pt_insn_asid(&decoder, NULL, sizeof(asid)); + ptu_int_eq(errcode, -pte_invalid); + + return ptu_passed(); +} + +static struct ptunit_result next_null(void) +{ + struct pt_insn_decoder decoder; + struct pt_insn insn; + int errcode; + + errcode = pt_insn_next(NULL, &insn, sizeof(insn)); + ptu_int_eq(errcode, -pte_invalid); + + errcode = pt_insn_next(&decoder, NULL, sizeof(insn)); + ptu_int_eq(errcode, -pte_invalid); + + return ptu_passed(); +} + +static struct ptunit_result event_null(void) +{ + struct pt_insn_decoder decoder; + struct pt_event event; + int errcode; + + errcode = pt_insn_event(NULL, &event, sizeof(event)); + ptu_int_eq(errcode, -pte_invalid); + + errcode = pt_insn_event(&decoder, NULL, sizeof(event)); + ptu_int_eq(errcode, -pte_invalid); + + return ptu_passed(); +} + +int main(int argc, char **argv) +{ + struct test_fixture tfix; + struct ptunit_suite suite; + + tfix.init = tfix_init; + tfix.fini = NULL; + + suite = ptunit_mk_suite(argc, argv); + + ptu_run(suite, decoder_init_null); + ptu_run(suite, decoder_fini_null); + ptu_run(suite, alloc_decoder_null); + ptu_run(suite, free_decoder_null); + + ptu_run(suite, sync_forward_null); + ptu_run(suite, sync_backward_null); + ptu_run(suite, sync_set_null); + ptu_run_f(suite, sync_set_eos, tfix); + + ptu_run(suite, get_offset_null); + ptu_run_f(suite, get_offset_init, tfix); + ptu_run(suite, get_sync_offset_null); + + ptu_run(suite, get_image_null); + ptu_run(suite, set_image_null); + + ptu_run(suite, get_config_null); + ptu_run_f(suite, get_config, tfix); + + ptu_run(suite, time_null); + ptu_run(suite, cbr_null); + ptu_run(suite, asid_null); + + ptu_run(suite, next_null); + ptu_run(suite, event_null); + + return ptunit_report(&suite); +}
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/test/src/ptunit-last_ip.c -> _service:tar_scm:v2.1.tar.gz/libipt/test/src/ptunit-last_ip.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/test/src/ptunit-mapped_section.c -> _service:tar_scm:v2.1.tar.gz/libipt/test/src/ptunit-mapped_section.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2014-2022, Intel Corporation + * Copyright (c) 2014-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/test/src/ptunit-msec_cache.c -> _service:tar_scm:v2.1.tar.gz/libipt/test/src/ptunit-msec_cache.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2017-2022, Intel Corporation + * Copyright (c) 2017-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -208,6 +209,8 @@ struct pt_image image; int status; + memset(&mcache, 0, sizeof(mcache)); + status = pt_msec_cache_read(NULL, &msec, &image, 0ull); ptu_int_eq(status, -pte_internal);
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/test/src/ptunit-packet.c -> _service:tar_scm:v2.1.tar.gz/libipt/test/src/ptunit-packet.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2014-2022, Intel Corporation + * Copyright (c) 2014-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -272,7 +273,7 @@ } static struct ptunit_result mode_exec(struct packet_fixture *pfix, - enum pt_exec_mode mode) + enum pt_exec_mode mode, int iflag) { struct pt_packet_mode_exec packet; @@ -282,6 +283,7 @@ pfix->packet0.payload.mode.leaf = pt_mol_exec; pfix->packet0.payload.mode.bits.exec.csl = packet.csl; pfix->packet0.payload.mode.bits.exec.csd = packet.csd; + pfix->packet0.payload.mode.bits.exec.iflag = iflag ? 1u : 0u; ptu_test(pfix_test, pfix); @@ -464,6 +466,29 @@ return ptu_passed(); } +static struct ptunit_result cfe(struct packet_fixture *pfix) +{ + pfix->packet0.type = ppt_cfe; + pfix->packet0.payload.cfe.type = pt_cfe_vmexit_intr; + pfix->packet0.payload.cfe.vector = pt_cfe_intr_pf; + pfix->packet0.payload.cfe.ip = 1; + + ptu_test(pfix_test, pfix); + + return ptu_passed(); +} + +static struct ptunit_result evd(struct packet_fixture *pfix) +{ + pfix->packet0.type = ppt_evd; + pfix->packet0.payload.evd.type = pt_evd_vmxq; + pfix->packet0.payload.evd.payload = 0xf000baaa; + + ptu_test(pfix_test, pfix); + + return ptu_passed(); +} + static struct ptunit_result cutoff(struct packet_fixture *pfix, enum pt_packet_type type) { @@ -603,9 +628,9 @@ ptu_run_fp(suite, ip, pfix, ppt_fup, pt_ipc_sext_48, 0x42ull); ptu_run_fp(suite, ip, pfix, ppt_fup, pt_ipc_full, 0x42ull); - ptu_run_fp(suite, mode_exec, pfix, ptem_16bit); - ptu_run_fp(suite, mode_exec, pfix, ptem_32bit); - ptu_run_fp(suite, mode_exec, pfix, ptem_64bit); + ptu_run_fp(suite, mode_exec, pfix, ptem_16bit, 1); + ptu_run_fp(suite, mode_exec, pfix, ptem_32bit, 0); + ptu_run_fp(suite, mode_exec, pfix, ptem_64bit, 1); ptu_run_f(suite, mode_tsx, pfix); ptu_run_f(suite, pip, pfix); @@ -624,6 +649,8 @@ ptu_run_f(suite, pwrx, pfix); ptu_run_fp(suite, ptw, pfix, 0, 1); ptu_run_fp(suite, ptw, pfix, 1, 0); + ptu_run_f(suite, cfe, pfix); + ptu_run_f(suite, evd, pfix); ptu_run_fp(suite, cutoff, pfix, ppt_psb); ptu_run_fp(suite, cutoff_ip, pfix, ppt_tip); @@ -647,213 +674,8 @@ ptu_run_fp(suite, cutoff, pfix, ppt_pwre); ptu_run_fp(suite, cutoff, pfix, ppt_pwrx); ptu_run_fp(suite, cutoff, pfix, ppt_ptw); + ptu_run_fp(suite, cutoff, pfix, ppt_cfe); + ptu_run_fp(suite, cutoff, pfix, ppt_evd); return ptunit_report(&suite); } - - -/* Dummy decode functions to satisfy link dependencies. - * - * As a nice side-effect, we will know if we need to add more tests when - * adding new decoder functions. - */ -struct pt_query_decoder; - -int pt_qry_decode_unknown(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} -int pt_qry_decode_pad(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} -int pt_qry_decode_psb(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} -int pt_qry_decode_tip(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} -int pt_qry_decode_tnt_8(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} -int pt_qry_decode_tnt_64(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} -int pt_qry_decode_tip_pge(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} -int pt_qry_decode_tip_pgd(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} -int pt_qry_decode_fup(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} -int pt_qry_header_fup(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} -int pt_qry_decode_pip(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} -int pt_qry_header_pip(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} -int pt_qry_decode_ovf(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} -int pt_qry_decode_mode(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} -int pt_qry_header_mode(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} -int pt_qry_decode_psbend(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} -int pt_qry_decode_tsc(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} -int pt_qry_header_tsc(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} -int pt_qry_decode_cbr(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} -int pt_qry_header_cbr(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} -int pt_qry_decode_tma(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} -int pt_qry_decode_mtc(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} -int pt_qry_decode_cyc(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} -int pt_qry_decode_stop(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} -int pt_qry_decode_vmcs(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} -int pt_qry_header_vmcs(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} -int pt_qry_decode_mnt(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} -int pt_qry_header_mnt(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} -int pt_qry_decode_exstop(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} -int pt_qry_decode_mwait(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} -int pt_qry_decode_pwre(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} -int pt_qry_decode_pwrx(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -} -int pt_qry_decode_ptw(struct pt_query_decoder *d) -{ - (void) d; - - return -pte_internal; -}
View file
_service:tar_scm:v2.1.tar.gz/libipt/test/src/ptunit-packet_decoder.c
Added
@@ -0,0 +1,277 @@ +/* + * Copyright (c) 2019-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "ptunit.h" + +#include "pt_packet_decoder.h" + +#include "intel-pt.h" + + +/* A test fixture providing a decoder operating on a small buffer. */ +struct test_fixture { + /* The packet_decoder. */ + struct pt_packet_decoder decoder; + + /* The configuration. */ + struct pt_config config; + + /* The buffer it operates on. */ + uint8_t buffer24; + + /* The test fixture initialization and finalization functions. */ + struct ptunit_result (*init)(struct test_fixture *tfix); + struct ptunit_result (*fini)(struct test_fixture *tfix); +}; + +static struct ptunit_result tfix_init(struct test_fixture *tfix) +{ + struct pt_config *config; + uint8_t *buffer; + int errcode; + + config = &tfix->config; + buffer = tfix->buffer; + + memset(buffer, 0, sizeof(tfix->buffer)); + + pt_config_init(config); + config->begin = buffer; + config->end = buffer + sizeof(tfix->buffer); + + errcode = pt_pkt_decoder_init(&tfix->decoder, config); + ptu_int_eq(errcode, 0); + + return ptu_passed(); +} + +static struct ptunit_result decoder_init_null(void) +{ + struct pt_packet_decoder decoder; + struct pt_config config; + int errcode; + + memset(&config, 0, sizeof(config)); + + errcode = pt_pkt_decoder_init(NULL, &config); + ptu_int_eq(errcode, -pte_invalid); + + errcode = pt_pkt_decoder_init(&decoder, NULL); + ptu_int_eq(errcode, -pte_invalid); + + return ptu_passed(); +} + +static struct ptunit_result decoder_fini_null(void) +{ + pt_pkt_decoder_fini(NULL); + + return ptu_passed(); +} + +static struct ptunit_result alloc_decoder_null(void) +{ + struct pt_packet_decoder *decoder; + + decoder = pt_pkt_alloc_decoder(NULL); + ptu_null(decoder); + + return ptu_passed(); +} + +static struct ptunit_result free_decoder_null(void) +{ + pt_pkt_free_decoder(NULL); + + return ptu_passed(); +} + +static struct ptunit_result sync_forward_null(void) +{ + int errcode; + + errcode = pt_pkt_sync_forward(NULL); + ptu_int_eq(errcode, -pte_invalid); + + return ptu_passed(); +} + +static struct ptunit_result sync_backward_null(void) +{ + int errcode; + + errcode = pt_pkt_sync_backward(NULL); + ptu_int_eq(errcode, -pte_invalid); + + return ptu_passed(); +} + +static struct ptunit_result sync_set_null(void) +{ + int errcode; + + errcode = pt_pkt_sync_set(NULL, 0ull); + ptu_int_eq(errcode, -pte_invalid); + + return ptu_passed(); +} + +static struct ptunit_result sync_set_eos(struct test_fixture *tfix) +{ + int errcode; + + errcode = pt_pkt_sync_set(&tfix->decoder, sizeof(tfix->buffer) + 1); + ptu_int_eq(errcode, -pte_eos); + + return ptu_passed(); +} + +static struct ptunit_result get_offset_null(void) +{ + struct pt_packet_decoder decoder; + uint64_t offset; + int errcode; + + errcode = pt_pkt_get_offset(NULL, &offset); + ptu_int_eq(errcode, -pte_invalid); + + errcode = pt_pkt_get_offset(&decoder, NULL); + ptu_int_eq(errcode, -pte_invalid); + + return ptu_passed(); +} + +static struct ptunit_result get_offset_init(struct test_fixture *tfix) +{ + uint64_t offset; + int errcode; + + errcode = pt_pkt_get_offset(&tfix->decoder, &offset); + ptu_int_eq(errcode, -pte_nosync); + + return ptu_passed(); +} + +static struct ptunit_result sync_set_get_offset(struct test_fixture *tfix) +{ + uint64_t offset; + int errcode; + + errcode = pt_pkt_sync_set(&tfix->decoder, 1ull); + ptu_int_eq(errcode, 0); + + errcode = pt_pkt_get_offset(&tfix->decoder, &offset); + ptu_int_eq(errcode, 0); + ptu_uint_eq(offset, 1ull); + + return ptu_passed(); +} + +static struct ptunit_result get_sync_offset_null(void) +{ + struct pt_packet_decoder decoder; + uint64_t offset; + int errcode; + + errcode = pt_pkt_get_sync_offset(NULL, &offset); + ptu_int_eq(errcode, -pte_invalid); + + errcode = pt_pkt_get_sync_offset(&decoder, NULL); + ptu_int_eq(errcode, -pte_invalid); + + return ptu_passed(); +} + +static struct ptunit_result get_config_null(void) +{ + const struct pt_config *config; + + config = pt_pkt_get_config(NULL); + ptu_null(config); + + return ptu_passed(); +} + +static struct ptunit_result get_config(struct test_fixture *tfix) +{ + const struct pt_config *config; + + config = pt_pkt_get_config(&tfix->decoder); + ptu_ptr(config); + + return ptu_passed(); +} + +static struct ptunit_result next_null(void) +{ + struct pt_packet_decoder decoder; + struct pt_packet packet; + int errcode; + + errcode = pt_pkt_next(NULL, &packet, sizeof(packet)); + ptu_int_eq(errcode, -pte_invalid); + + errcode = pt_pkt_next(&decoder, NULL, sizeof(packet)); + ptu_int_eq(errcode, -pte_invalid); + + return ptu_passed(); +} + +int main(int argc, char **argv) +{ + struct test_fixture tfix; + struct ptunit_suite suite; + + tfix.init = tfix_init; + tfix.fini = NULL; + + suite = ptunit_mk_suite(argc, argv); + + ptu_run(suite, decoder_init_null); + ptu_run(suite, decoder_fini_null); + ptu_run(suite, alloc_decoder_null); + ptu_run(suite, free_decoder_null); + + ptu_run(suite, sync_forward_null); + ptu_run(suite, sync_backward_null); + ptu_run(suite, sync_set_null); + ptu_run_f(suite, sync_set_eos, tfix); + + ptu_run(suite, get_offset_null); + ptu_run_f(suite, get_offset_init, tfix); + ptu_run_f(suite, sync_set_get_offset, tfix); + ptu_run(suite, get_sync_offset_null); + + ptu_run(suite, get_config_null); + ptu_run_f(suite, get_config, tfix); + + ptu_run(suite, next_null); + + return ptunit_report(&suite); +}
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/test/src/ptunit-query.c -> _service:tar_scm:v2.1.tar.gz/libipt/test/src/ptunit-query.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -29,7 +30,6 @@ #include "ptunit.h" #include "pt_last_ip.h" -#include "pt_decoder_function.h" #include "pt_query_decoder.h" #include "pt_encoder.h" #include "pt_opcodes.h" @@ -76,10 +76,25 @@ */ static struct ptunit_result ptu_sync_decoder(struct pt_query_decoder *decoder) { + int errcode; + ptu_ptr(decoder); - decoder->enabled = 1; - (void) pt_df_fetch(&decoder->next, decoder->pos, &decoder->config); + errcode = pt_pkt_sync_set(&decoder->evdec.pacdec, 0ull); + ptu_int_eq(errcode, 0); + + errcode = pt_pkt_next(&decoder->evdec.pacdec, &decoder->evdec.packet, + sizeof(decoder->evdec.packet)); + if (errcode < 0) { + decoder->evdec.packet.type = ppt_invalid; + decoder->evdec.status = errcode; + } + + decoder->evdec.enabled = 1; + + decoder->status = pt_evt_next(&decoder->evdec, &decoder->event, + sizeof(decoder->event)); + return ptu_passed(); } @@ -87,6 +102,7 @@ static struct ptunit_result cutoff(struct pt_query_decoder *decoder, const struct pt_encoder *encoder) { + struct pt_config *config = &decoder->evdec.pacdec.config; uint8_t *pos; ptu_ptr(decoder); @@ -96,9 +112,9 @@ ptu_ptr(pos); pos -= 1; - ptu_ptr_le(decoder->config.begin, pos); + ptu_ptr_le(config->begin, pos); - decoder->config.end = pos; + config->end = pos; return ptu_passed(); } @@ -203,180 +219,6 @@ } static struct ptunit_result -sync_backward_empty_end(struct ptu_decoder_fixture *dfix) -{ - struct pt_query_decoder *decoder = &dfix->decoder; - struct pt_encoder *encoder = &dfix->encoder; - uint64_t sync3, offset, ip; - int errcode; - - /* Check that we can use repeated pt_qry_sync_backward() to iterate over - * synchronization points in backwards order. - * - * There's an empty PSB+ at the end. We skip it. - */ - - errcode = pt_enc_get_offset(encoder, &sync0); - ptu_int_ge(errcode, 0); - - pt_encode_psb(encoder); - pt_encode_mode_exec(encoder, ptem_64bit); - pt_encode_psbend(encoder); - - errcode = pt_enc_get_offset(encoder, &sync1); - ptu_int_ge(errcode, 0); - - pt_encode_psb(encoder); - pt_encode_mode_exec(encoder, ptem_64bit); - pt_encode_psbend(encoder); - - errcode = pt_enc_get_offset(encoder, &sync2); - ptu_int_ge(errcode, 0); - - pt_encode_psb(encoder); - pt_encode_psbend(encoder); - - /* Synchronize repeatedly and check that we reach each PSB in the - * correct order. - */ - - errcode = pt_qry_sync_backward(decoder, &ip); - ptu_int_ge(errcode, 0); - - errcode = pt_qry_get_sync_offset(decoder, &offset); - ptu_int_eq(errcode, 0); - ptu_uint_eq(offset, sync1); - - errcode = pt_qry_sync_backward(decoder, &ip); - ptu_int_ge(errcode, 0); - - errcode = pt_qry_get_sync_offset(decoder, &offset); - ptu_int_eq(errcode, 0); - ptu_uint_eq(offset, sync0); - - errcode = pt_qry_sync_backward(decoder, &ip); - ptu_int_eq(errcode, -pte_eos); - - return ptu_passed(); -} - -static struct ptunit_result -sync_backward_empty_mid(struct ptu_decoder_fixture *dfix) -{ - struct pt_query_decoder *decoder = &dfix->decoder; - struct pt_encoder *encoder = &dfix->encoder; - uint64_t sync3, offset, ip; - int errcode; - - /* Check that we can use repeated pt_qry_sync_backward() to iterate over - * synchronization points in backwards order. - * - * There's an empty PSB+ in the middle. We skip it. - */ - - errcode = pt_enc_get_offset(encoder, &sync0); - ptu_int_ge(errcode, 0); - - pt_encode_psb(encoder); - pt_encode_mode_exec(encoder, ptem_64bit); - pt_encode_psbend(encoder); - - errcode = pt_enc_get_offset(encoder, &sync1); - ptu_int_ge(errcode, 0); - - pt_encode_psb(encoder); - pt_encode_psbend(encoder); - - errcode = pt_enc_get_offset(encoder, &sync2); - ptu_int_ge(errcode, 0); - - pt_encode_psb(encoder); - pt_encode_mode_exec(encoder, ptem_64bit); - pt_encode_psbend(encoder); - - /* Synchronize repeatedly and check that we reach each PSB in the - * correct order. - */ - - errcode = pt_qry_sync_backward(decoder, &ip); - ptu_int_ge(errcode, 0); - - errcode = pt_qry_get_sync_offset(decoder, &offset); - ptu_int_eq(errcode, 0); - ptu_uint_eq(offset, sync2); - - errcode = pt_qry_sync_backward(decoder, &ip); - ptu_int_ge(errcode, 0); - - errcode = pt_qry_get_sync_offset(decoder, &offset); - ptu_int_eq(errcode, 0); - ptu_uint_eq(offset, sync0); - - errcode = pt_qry_sync_backward(decoder, &ip); - ptu_int_eq(errcode, -pte_eos); - - return ptu_passed(); -} - -static struct ptunit_result -sync_backward_empty_begin(struct ptu_decoder_fixture *dfix) -{ - struct pt_query_decoder *decoder = &dfix->decoder; - struct pt_encoder *encoder = &dfix->encoder; - uint64_t sync3, offset, ip; - int errcode; - - /* Check that we can use repeated pt_qry_sync_backward() to iterate over - * synchronization points in backwards order. - * - * There's an empty PSB+ at the beginning. We skip it. - */ - - errcode = pt_enc_get_offset(encoder, &sync0); - ptu_int_ge(errcode, 0); - - pt_encode_psb(encoder); - pt_encode_psbend(encoder); - - errcode = pt_enc_get_offset(encoder, &sync1); - ptu_int_ge(errcode, 0); - - pt_encode_psb(encoder); - pt_encode_mode_exec(encoder, ptem_64bit); - pt_encode_psbend(encoder); - - errcode = pt_enc_get_offset(encoder, &sync2); - ptu_int_ge(errcode, 0); - - pt_encode_psb(encoder); - pt_encode_mode_exec(encoder, ptem_64bit); - pt_encode_psbend(encoder); - - /* Synchronize repeatedly and check that we reach each PSB in the - * correct order. - */ - - errcode = pt_qry_sync_backward(decoder, &ip); - ptu_int_ge(errcode, 0); - - errcode = pt_qry_get_sync_offset(decoder, &offset); - ptu_int_eq(errcode, 0); - ptu_uint_eq(offset, sync2); - - errcode = pt_qry_sync_backward(decoder, &ip); - ptu_int_ge(errcode, 0); - - errcode = pt_qry_get_sync_offset(decoder, &offset); - ptu_int_eq(errcode, 0); - ptu_uint_eq(offset, sync1); - - errcode = pt_qry_sync_backward(decoder, &ip); - ptu_int_eq(errcode, -pte_eos); - - return ptu_passed(); -} - -static struct ptunit_result decode_sync_backward(struct ptu_decoder_fixture *dfix) { struct pt_query_decoder *decoder = &dfix->decoder; @@ -393,14 +235,12 @@ ptu_int_ge(errcode, 0); pt_encode_psb(encoder); - pt_encode_mode_exec(encoder, ptem_64bit); pt_encode_psbend(encoder); errcode = pt_enc_get_offset(encoder, &sync1); ptu_int_ge(errcode, 0); pt_encode_psb(encoder); - pt_encode_mode_exec(encoder, ptem_64bit); pt_encode_psbend(encoder); @@ -413,11 +253,15 @@ errcode = pt_qry_event(decoder, &event, sizeof(event)); ptu_int_ge(errcode, 0); - ptu_int_eq(event.type, ptev_exec_mode); + ptu_int_eq(event.type, ptev_disabled); + ptu_uint_eq(event.status_update, 1u); + ptu_uint_eq(event.ip_suppressed, 1u); errcode = pt_qry_event(decoder, &event, sizeof(event)); ptu_int_ge(errcode, 0); - ptu_int_eq(event.type, ptev_exec_mode); + ptu_int_eq(event.type, ptev_disabled); + ptu_uint_eq(event.status_update, 1u); + ptu_uint_eq(event.ip_suppressed, 1u); errcode = pt_qry_sync_backward(decoder, &ip); ptu_int_ge(errcode, 0); @@ -442,7 +286,6 @@ static struct ptunit_result indir_null(struct ptu_decoder_fixture *dfix) { struct pt_query_decoder *decoder = &dfix->decoder; - struct pt_config *config = &decoder->config; uint64_t ip = pt_dfix_bad_ip, addr = ip; int errcode; @@ -452,7 +295,6 @@ errcode = pt_qry_indirect_branch(decoder, NULL); ptu_int_eq(errcode, -pte_invalid); - ptu_ptr_eq(decoder->pos, config->begin); return ptu_passed(); } @@ -460,11 +302,10 @@ static struct ptunit_result indir_empty(struct ptu_decoder_fixture *dfix) { struct pt_query_decoder *decoder = &dfix->decoder; - struct pt_config *config = &decoder->config; uint64_t ip = pt_dfix_bad_ip, addr = ip; int errcode; - decoder->pos = config->end; + ptu_check(ptu_sync_decoder, decoder); errcode = pt_qry_indirect_branch(decoder, &addr); ptu_int_eq(errcode, -pte_eos); @@ -578,10 +419,8 @@ struct pt_query_decoder *decoder = &dfix->decoder; struct pt_encoder *encoder = &dfix->encoder; uint64_t ip = pt_dfix_bad_ip, addr = ip; - const uint8_t *pos; int errcode; - pos = encoder->pos; pt_encode_tip_pge(encoder, 0, pt_ipc_sext_48); pt_encode_tip(encoder, 0, pt_ipc_sext_48); @@ -589,7 +428,6 @@ errcode = pt_qry_indirect_branch(decoder, &addr); ptu_int_eq(errcode, -pte_bad_query); - ptu_ptr_eq(decoder->pos, pos); ptu_uint_eq(addr, ip); return ptu_passed(); @@ -601,10 +439,8 @@ struct pt_query_decoder *decoder = &dfix->decoder; struct pt_encoder *encoder = &dfix->encoder; uint64_t ip = pt_dfix_bad_ip, addr = ip; - const uint8_t *pos; int errcode; - pos = encoder->pos; pt_encode_tip_pgd(encoder, 0, pt_ipc_sext_48); pt_encode_tip(encoder, 0, pt_ipc_sext_48); @@ -612,7 +448,6 @@ errcode = pt_qry_indirect_branch(decoder, &addr); ptu_int_eq(errcode, -pte_bad_query); - ptu_ptr_eq(decoder->pos, pos); ptu_uint_eq(addr, ip); return ptu_passed(); @@ -624,11 +459,9 @@ struct pt_query_decoder *decoder = &dfix->decoder; struct pt_encoder *encoder = &dfix->encoder; uint64_t ip = pt_dfix_bad_ip, addr = ip; - const uint8_t *pos; int errcode; pt_encode_fup(encoder, 0, pt_ipc_sext_48); - pos = encoder->pos; pt_encode_tip(encoder, 0, pt_ipc_sext_48); pt_encode_tip(encoder, 0, pt_ipc_sext_48); @@ -636,7 +469,6 @@ errcode = pt_qry_indirect_branch(decoder, &addr); ptu_int_eq(errcode, -pte_bad_query); - ptu_ptr_eq(decoder->pos, pos); ptu_uint_eq(addr, ip); return ptu_passed(); @@ -648,11 +480,9 @@ struct pt_query_decoder *decoder = &dfix->decoder; struct pt_encoder *encoder = &dfix->encoder; uint64_t ip = pt_dfix_bad_ip, addr = ip; - const uint8_t *pos; int errcode; pt_encode_fup(encoder, 0, pt_ipc_sext_48); - pos = encoder->pos; pt_encode_tip_pgd(encoder, 0, pt_ipc_sext_48); pt_encode_tip(encoder, 0, pt_ipc_sext_48); @@ -660,7 +490,6 @@ errcode = pt_qry_indirect_branch(decoder, &addr); ptu_int_eq(errcode, -pte_bad_query); - ptu_ptr_eq(decoder->pos, pos); ptu_uint_eq(addr, ip); return ptu_passed(); @@ -669,7 +498,6 @@ static struct ptunit_result cond_null(struct ptu_decoder_fixture *dfix) { struct pt_query_decoder *decoder = &dfix->decoder; - struct pt_config *config = &decoder->config; int errcode, tnt = 0xbc, taken = tnt; errcode = pt_qry_cond_branch(NULL, &taken); @@ -678,7 +506,6 @@ errcode = pt_qry_cond_branch(decoder, NULL); ptu_int_eq(errcode, -pte_invalid); - ptu_ptr_eq(decoder->pos, config->begin); return ptu_passed(); } @@ -686,10 +513,9 @@ static struct ptunit_result cond_empty(struct ptu_decoder_fixture *dfix) { struct pt_query_decoder *decoder = &dfix->decoder; - struct pt_config *config = &decoder->config; int errcode, tnt = 0xbc, taken = tnt; - decoder->pos = config->end; + ptu_check(ptu_sync_decoder, decoder); errcode = pt_qry_cond_branch(decoder, &taken); ptu_int_eq(errcode, -pte_eos); @@ -735,9 +561,7 @@ struct pt_query_decoder *decoder = &dfix->decoder; struct pt_encoder *encoder = &dfix->encoder; int errcode, tnt = 0xbc, taken = tnt; - const uint8_t *pos; - pos = encoder->pos; pt_encode_tip(encoder, 0, pt_ipc_sext_48); pt_encode_tnt_8(encoder, 0, 1); @@ -745,7 +569,6 @@ errcode = pt_qry_cond_branch(decoder, &taken); ptu_int_eq(errcode, -pte_bad_query); - ptu_ptr_eq(decoder->pos, pos); ptu_int_eq(taken, tnt); return ptu_passed(); @@ -757,9 +580,7 @@ struct pt_query_decoder *decoder = &dfix->decoder; struct pt_encoder *encoder = &dfix->encoder; int errcode, tnt = 0xbc, taken = tnt; - const uint8_t *pos; - pos = encoder->pos; pt_encode_tip_pge(encoder, 0, pt_ipc_sext_48); pt_encode_tnt_8(encoder, 0, 1); @@ -767,7 +588,6 @@ errcode = pt_qry_cond_branch(decoder, &taken); ptu_int_eq(errcode, -pte_bad_query); - ptu_ptr_eq(decoder->pos, pos); ptu_int_eq(taken, tnt); return ptu_passed(); @@ -779,9 +599,7 @@ struct pt_query_decoder *decoder = &dfix->decoder; struct pt_encoder *encoder = &dfix->encoder; int errcode, tnt = 0xbc, taken = tnt; - const uint8_t *pos; - pos = encoder->pos; pt_encode_tip_pgd(encoder, 0, pt_ipc_sext_48); pt_encode_tnt_8(encoder, 0, 1); @@ -789,7 +607,6 @@ errcode = pt_qry_cond_branch(decoder, &taken); ptu_int_eq(errcode, -pte_bad_query); - ptu_ptr_eq(decoder->pos, pos); ptu_int_eq(taken, tnt); return ptu_passed(); @@ -801,10 +618,8 @@ struct pt_query_decoder *decoder = &dfix->decoder; struct pt_encoder *encoder = &dfix->encoder; int errcode, tnt = 0xbc, taken = tnt; - const uint8_t *pos; pt_encode_fup(encoder, 0, pt_ipc_sext_48); - pos = encoder->pos; pt_encode_tip(encoder, 0, pt_ipc_sext_48); pt_encode_tnt_8(encoder, 0, 1); @@ -812,7 +627,6 @@ errcode = pt_qry_cond_branch(decoder, &taken); ptu_int_eq(errcode, -pte_bad_query); - ptu_ptr_eq(decoder->pos, pos); ptu_int_eq(taken, tnt); return ptu_passed(); @@ -824,10 +638,8 @@ struct pt_query_decoder *decoder = &dfix->decoder; struct pt_encoder *encoder = &dfix->encoder; int errcode, tnt = 0xbc, taken = tnt; - const uint8_t *pos; pt_encode_fup(encoder, 0, pt_ipc_sext_48); - pos = encoder->pos; pt_encode_tip_pgd(encoder, 0, pt_ipc_sext_48); pt_encode_tnt_8(encoder, 0, 1); @@ -835,7 +647,6 @@ errcode = pt_qry_cond_branch(decoder, &taken); ptu_int_eq(errcode, -pte_bad_query); - ptu_ptr_eq(decoder->pos, pos); ptu_int_eq(taken, tnt); return ptu_passed(); @@ -844,7 +655,6 @@ static struct ptunit_result event_null(struct ptu_decoder_fixture *dfix) { struct pt_query_decoder *decoder = &dfix->decoder; - struct pt_config *config = &decoder->config; struct pt_event event; int errcode; @@ -853,7 +663,6 @@ errcode = pt_qry_event(decoder, NULL, sizeof(event)); ptu_int_eq(errcode, -pte_invalid); - ptu_ptr_eq(decoder->pos, config->begin); return ptu_passed(); } @@ -921,11 +730,10 @@ static struct ptunit_result event_empty(struct ptu_decoder_fixture *dfix) { struct pt_query_decoder *decoder = &dfix->decoder; - struct pt_config *config = &decoder->config; struct pt_event event; int errcode; - decoder->pos = config->end; + ptu_check(ptu_sync_decoder, decoder); errcode = pt_qry_event(decoder, &event, sizeof(event)); ptu_int_eq(errcode, -pte_eos); @@ -950,21 +758,23 @@ pt_encode_tip_pge(encoder, packet.ip, packet.ipc); ptu_check(ptu_sync_decoder, decoder); + decoder->evdec.enabled = 0; errcode = pt_qry_event(decoder, &event, sizeof(event)); + ptu_int_eq(errcode, pts_eos); + ptu_int_eq(event.type, ptev_enabled); if (ipc == pt_ipc_suppressed) - ptu_int_eq(errcode, -pte_bad_packet); + ptu_uint_ne(event.ip_suppressed, 0u); else { - ptu_int_eq(errcode, pts_eos); - ptu_int_eq(event.type, ptev_enabled); + ptu_uint_eq(event.ip_suppressed, 0u); ptu_uint_eq(event.variant.enabled.ip, dfix->last_ip.ip); + } - if (!tsc) - ptu_int_eq(event.has_tsc, 0); - else { - ptu_int_eq(event.has_tsc, 1); - ptu_uint_eq(event.tsc, tsc); - } + if (!tsc) + ptu_uint_eq(event.has_tsc, 0u); + else { + ptu_uint_ne(event.has_tsc, 0u); + ptu_uint_eq(event.tsc, tsc); } return ptu_passed(); @@ -1435,27 +1245,20 @@ ptu_check(ptu_sync_decoder, decoder); errcode = pt_qry_event(decoder, &event, sizeof(event)); - switch (ipc) { - case pt_ipc_suppressed: - ptu_int_eq(errcode, -pte_noip); - break; - - case pt_ipc_update_16: - case pt_ipc_update_32: - case pt_ipc_update_48: - case pt_ipc_sext_48: - case pt_ipc_full: - ptu_int_eq(errcode, pts_eos); - ptu_int_eq(event.type, ptev_overflow); + ptu_int_eq(errcode, pts_eos); + ptu_int_eq(event.type, ptev_overflow); + if (ipc == pt_ipc_suppressed) + ptu_uint_ne(event.ip_suppressed, 0u); + else { + ptu_uint_eq(event.ip_suppressed, 0u); ptu_uint_eq(event.variant.overflow.ip, dfix->last_ip.ip); + } - if (!tsc) - ptu_int_eq(event.has_tsc, 0); - else { - ptu_int_eq(event.has_tsc, 1); - ptu_uint_eq(event.tsc, tsc); - } - break; + if (!tsc) + ptu_uint_eq(event.has_tsc, 0u); + else { + ptu_uint_ne(event.has_tsc, 0u); + ptu_uint_eq(event.tsc, tsc); } return ptu_passed(); @@ -1495,27 +1298,20 @@ } errcode = pt_qry_event(decoder, &event, sizeof(event)); - switch (ipc) { - case pt_ipc_suppressed: - ptu_int_eq(errcode, -pte_bad_packet); - break; - - case pt_ipc_update_16: - case pt_ipc_update_32: - case pt_ipc_update_48: - case pt_ipc_sext_48: - case pt_ipc_full: - ptu_int_eq(errcode, pts_eos); - ptu_int_eq(event.type, ptev_enabled); + ptu_int_eq(errcode, pts_eos); + ptu_int_eq(event.type, ptev_enabled); + if (ipc == pt_ipc_suppressed) + ptu_uint_ne(event.ip_suppressed, 0u); + else { + ptu_uint_eq(event.ip_suppressed, 0u); ptu_uint_eq(event.variant.enabled.ip, dfix->last_ip.ip); + } - if (!tsc) - ptu_int_eq(event.has_tsc, 0); - else { - ptu_int_eq(event.has_tsc, 1); - ptu_uint_eq(event.tsc, tsc); - } - break; + if (!tsc) + ptu_uint_eq(event.has_tsc, 0u); + else { + ptu_uint_ne(event.has_tsc, 0u); + ptu_uint_eq(event.tsc, tsc); } return ptu_passed(); @@ -1587,8 +1383,16 @@ ptu_check(ptu_sync_decoder, decoder); + errcode = pt_qry_indirect_branch(decoder, &addr); + if (ipc == pt_ipc_suppressed) + ptu_int_eq(errcode, pts_ip_suppressed | pts_event_pending); + else { + ptu_int_eq(errcode, pts_event_pending); + ptu_uint_eq(addr, dfix->last_ip.ip); + } + errcode = pt_qry_event(decoder, &event, sizeof(event)); - ptu_int_eq(errcode, 0); + ptu_int_eq(errcode, pts_eos); if (ipc == pt_ipc_suppressed) ptu_uint_ne(event.ip_suppressed, 0); else { @@ -1605,14 +1409,6 @@ ptu_uint_eq(event.tsc, tsc); } - errcode = pt_qry_indirect_branch(decoder, &addr); - if (ipc == pt_ipc_suppressed) - ptu_int_eq(errcode, pts_ip_suppressed | pts_eos); - else { - ptu_int_eq(errcode, pts_eos); - ptu_uint_eq(addr, dfix->last_ip.ip); - } - return ptu_passed(); } @@ -1645,7 +1441,6 @@ enum pt_exec_mode mode = ptem_16bit; struct pt_packet_ip packet; struct pt_event event; - uint64_t addr = 0ull; int errcode; packet.ipc = ipc; @@ -1656,36 +1451,41 @@ pt_encode_tip_pge(encoder, packet.ip, packet.ipc); ptu_check(ptu_sync_decoder, decoder); - decoder->enabled = 0; + decoder->evdec.enabled = 0; errcode = pt_qry_event(decoder, &event, sizeof(event)); - if (ipc == pt_ipc_suppressed) { - ptu_int_eq(errcode, -pte_bad_packet); - ptu_uint_eq(addr, 0ull); - } else { - ptu_int_eq(errcode, pts_event_pending); - ptu_int_eq(event.type, ptev_enabled); - ptu_uint_eq(event.variant.enabled.ip, dfix->last_ip.ip); + ptu_int_eq(errcode, pts_event_pending); + ptu_int_eq(event.type, ptev_enabled); + if (ipc == pt_ipc_suppressed) + ptu_uint_ne(event.ip_suppressed, 0u); + else { + ptu_uint_eq(event.ip_suppressed, 0u); + ptu_uint_eq(event.variant.overflow.ip, dfix->last_ip.ip); + } - if (!tsc) - ptu_int_eq(event.has_tsc, 0); - else { - ptu_int_eq(event.has_tsc, 1); - ptu_uint_eq(event.tsc, tsc); - } + if (!tsc) + ptu_uint_eq(event.has_tsc, 0u); + else { + ptu_uint_ne(event.has_tsc, 0u); + ptu_uint_eq(event.tsc, tsc); + } - errcode = pt_qry_event(decoder, &event, sizeof(event)); - ptu_int_eq(errcode, pts_eos); - ptu_int_eq(event.type, ptev_exec_mode); - ptu_int_eq(event.variant.exec_mode.mode, mode); + errcode = pt_qry_event(decoder, &event, sizeof(event)); + ptu_int_eq(errcode, pts_eos); + ptu_int_eq(event.type, ptev_exec_mode); + ptu_int_eq(event.variant.exec_mode.mode, mode); + if (ipc == pt_ipc_suppressed) + ptu_uint_ne(event.ip_suppressed, 0u); + else { + ptu_uint_eq(event.ip_suppressed, 0u); ptu_uint_eq(event.variant.exec_mode.ip, dfix->last_ip.ip); + } - if (!tsc) - ptu_int_eq(event.has_tsc, 0); - else { - ptu_int_eq(event.has_tsc, 1); - ptu_uint_eq(event.tsc, tsc); - } + if (!tsc) + ptu_uint_eq(event.has_tsc, 0u); + else { + ptu_uint_ne(event.has_tsc, 0u); + ptu_uint_eq(event.tsc, tsc); } return ptu_passed(); @@ -1827,10 +1627,8 @@ struct pt_query_decoder *decoder = &dfix->decoder; struct pt_encoder *encoder = &dfix->encoder; struct pt_event event; - const uint8_t *pos; int errcode; - pos = encoder->pos; pt_encode_tip(encoder, 0, pt_ipc_sext_48); /* We omit the actual event - we don't get that far, anyway. */ @@ -1838,7 +1636,6 @@ errcode = pt_qry_event(decoder, &event, sizeof(event)); ptu_int_eq(errcode, -pte_bad_query); - ptu_ptr_eq(decoder->pos, pos); return ptu_passed(); } @@ -1923,6 +1720,18 @@ } errcode = pt_qry_event(decoder, &event, sizeof(event)); + ptu_int_eq(errcode, pts_event_pending); + ptu_uint_ne(event.status_update, 0); + if (ipc == pt_ipc_suppressed) { + ptu_int_eq(event.type, ptev_disabled); + ptu_uint_ne(event.ip_suppressed, 0); + } else { + ptu_int_eq(event.type, ptev_enabled); + ptu_uint_eq(event.ip_suppressed, 0); + ptu_uint_eq(event.variant.enabled.ip, dfix->last_ip.ip); + } + + errcode = pt_qry_event(decoder, &event, sizeof(event)); ptu_int_eq(errcode, pts_eos); ptu_uint_ne(event.status_update, 0); if (ipc == pt_ipc_suppressed) @@ -2007,6 +1816,13 @@ errcode = pt_qry_event(decoder, &event, sizeof(event)); ptu_int_eq(errcode, pts_event_pending); ptu_uint_ne(event.status_update, 0); + ptu_int_eq(event.type, ptev_enabled); + ptu_uint_eq(event.ip_suppressed, 0); + ptu_uint_eq(event.variant.enabled.ip, fup.ip); + + errcode = pt_qry_event(decoder, &event, sizeof(event)); + ptu_int_eq(errcode, pts_event_pending); + ptu_uint_ne(event.status_update, 0); ptu_int_eq(event.type, ptev_tsx); ptu_int_eq(event.variant.tsx.speculative, 0); ptu_int_eq(event.variant.tsx.aborted, 0); @@ -2015,24 +1831,18 @@ ptu_uint_eq(event.tsc, 0x1000); errcode = pt_qry_event(decoder, &event, sizeof(event)); - switch (ipc) { - case pt_ipc_suppressed: - ptu_int_eq(errcode, -pte_noip); - return ptu_passed(); - - case pt_ipc_update_16: - case pt_ipc_update_32: - case pt_ipc_update_48: - case pt_ipc_sext_48: - case pt_ipc_full: - ptu_int_eq(errcode, pts_eos); - ptu_int_eq(event.type, ptev_overflow); + ptu_int_eq(errcode, pts_eos); + ptu_int_eq(event.type, ptev_overflow); + if (ipc == pt_ipc_suppressed) + ptu_uint_ne(event.ip_suppressed, 0u); + else { + ptu_uint_eq(event.ip_suppressed, 0u); ptu_uint_eq(event.variant.overflow.ip, dfix->last_ip.ip); - ptu_int_eq(event.has_tsc, 1); - ptu_uint_eq(event.tsc, 0x1000); - break; } + ptu_int_eq(event.has_tsc, 1); + ptu_uint_eq(event.tsc, 0x1000); + return ptu_passed(); } @@ -2232,11 +2042,11 @@ errcode = pt_qry_decoder_init(&dfix->decoder, config); ptu_int_eq(errcode, 0); - dfix->decoder.ip.ip = pt_dfix_bad_ip; - dfix->decoder.ip.have_ip = 1; - dfix->decoder.ip.suppressed = 0; + dfix->decoder.evdec.ip.ip = pt_dfix_bad_ip; + dfix->decoder.evdec.ip.have_ip = 1; + dfix->decoder.evdec.ip.suppressed = 0; - dfix->last_ip = dfix->decoder.ip; + dfix->last_ip = dfix->decoder.evdec.ip; if (dfix->header) dfix->header(dfix); @@ -2252,25 +2062,10 @@ return ptu_passed(); } -/* Synchronize the decoder at the beginnig of an empty buffer. */ -static struct ptunit_result -ptu_dfix_header_sync(struct ptu_decoder_fixture *dfix) -{ - struct pt_query_decoder *decoder = &dfix->decoder; - - /* Synchronize the decoder at the beginning of the buffer. */ - decoder->pos = decoder->config.begin; - - return ptu_passed(); -} - -/* Synchronize the decoder at the beginnig of a buffer containing packets that - * should be skipped for unconditional indirect branch queries. - */ +/* Generate packets to be skipped for unconditional indirect branch queries. */ static struct ptunit_result ptu_dfix_header_indir(struct ptu_decoder_fixture *dfix) { - struct pt_query_decoder *decoder = &dfix->decoder; struct pt_encoder *encoder = &dfix->encoder; pt_encode_pad(encoder); @@ -2278,79 +2073,36 @@ pt_encode_pad(encoder); pt_encode_tsc(encoder, 0); - /* Synchronize the decoder at the beginning of the buffer. */ - decoder->pos = decoder->config.begin; - - return ptu_passed(); -} - -/* Synchronize the decoder at the beginnig of a buffer containing packets that - * should be skipped for unconditional indirect branch queries including a PSB. - */ -static struct ptunit_result -ptu_dfix_header_indir_psb(struct ptu_decoder_fixture *dfix) -{ - struct pt_query_decoder *decoder = &dfix->decoder; - struct pt_encoder *encoder = &dfix->encoder; - - /* The psb must be empty since the tests won't skip status events. - * On the other hand, we do need to provide an address since tests - * may want to update last-ip, which requires a last-ip, of course. - */ - pt_encode_pad(encoder); - pt_encode_tsc(encoder, 0); - pt_encode_psb(encoder); - pt_encode_mtc(encoder, 1); - pt_encode_pad(encoder); - pt_encode_tsc(encoder, 0); - pt_encode_fup(encoder, pt_dfix_sext_ip, pt_ipc_sext_48); - pt_encode_psbend(encoder); - pt_encode_mtc(encoder, 1); - pt_encode_pad(encoder); - - /* Synchronize the decoder at the beginning of the buffer. */ - decoder->pos = decoder->config.begin; - return ptu_passed(); } -/* Synchronize the decoder at the beginnig of a buffer containing packets that - * should be skipped for conditional branch queries. - */ +/* Generate packets to be skipped for conditional branch queries. */ static struct ptunit_result ptu_dfix_header_cond(struct ptu_decoder_fixture *dfix) { struct pt_query_decoder *decoder = &dfix->decoder; struct pt_encoder *encoder = &dfix->encoder; + struct pt_packet_ip fup; - /* The psb must be empty since the tests won't skip status events. - * On the other hand, we do need to provide an address since tests - * may want to update last-ip, which requires a last-ip, of course. + /* We do need to provide an address since tests may want to update + * last-ip, which requires a last-ip, of course. */ + fup.ipc = pt_ipc_sext_48; + fup.ip = pt_dfix_sext_ip; + pt_last_ip_update_ip(&decoder->evdec.ip, &fup, &dfix->config); + pt_encode_pad(encoder); pt_encode_mtc(encoder, 1); - pt_encode_psb(encoder); - pt_encode_tsc(encoder, 0); - pt_encode_pad(encoder); - pt_encode_fup(encoder, pt_dfix_sext_ip, pt_ipc_sext_48); - pt_encode_psbend(encoder); - pt_encode_pad(encoder); pt_encode_tsc(encoder, 0); pt_encode_pad(encoder); - /* Synchronize the decoder at the beginning of the buffer. */ - decoder->pos = decoder->config.begin; - return ptu_passed(); } -/* Synchronize the decoder at the beginnig of a buffer containing packets that - * should be skipped for event queries. - */ +/* Generate packets to be skipped for event queries. */ static struct ptunit_result ptu_dfix_header_event(struct ptu_decoder_fixture *dfix) { - struct pt_query_decoder *decoder = &dfix->decoder; struct pt_encoder *encoder = &dfix->encoder; pt_encode_pad(encoder); @@ -2358,71 +2110,54 @@ pt_encode_pad(encoder); pt_encode_tsc(encoder, 0x1000); - /* Synchronize the decoder at the beginning of the buffer. */ - decoder->pos = decoder->config.begin; - return ptu_passed(); } -/* Synchronize the decoder at the beginnig of a buffer containing packets that - * should be skipped for event queries including a PSB. - */ +/* Generate packets to be skipped for event queries including a PSB. */ static struct ptunit_result ptu_dfix_header_event_psb(struct ptu_decoder_fixture *dfix) { struct pt_query_decoder *decoder = &dfix->decoder; struct pt_encoder *encoder = &dfix->encoder; + struct pt_packet_ip fup; - /* The psb must be empty since the tests won't skip status events. - * On the other hand, we do need to provide an address since tests - * may want to update last-ip, which requires a last-ip, of course. + /* We do need to provide an address since tests may want to update + * last-ip, which requires a last-ip, of course. */ + fup.ipc = pt_ipc_sext_48; + fup.ip = pt_dfix_sext_ip; + pt_last_ip_update_ip(&decoder->evdec.ip, &fup, &dfix->config); + pt_encode_pad(encoder); - pt_encode_tsc(encoder, 0); - pt_encode_psb(encoder); pt_encode_mtc(encoder, 1); pt_encode_pad(encoder); pt_encode_tsc(encoder, 0x1000); - pt_encode_fup(encoder, pt_dfix_sext_ip, pt_ipc_sext_48); - pt_encode_psbend(encoder); - pt_encode_mtc(encoder, 1); pt_encode_pad(encoder); - /* Synchronize the decoder at the beginning of the buffer. */ - decoder->pos = decoder->config.begin; - return ptu_passed(); } -static struct ptu_decoder_fixture dfix_raw; static struct ptu_decoder_fixture dfix_empty; static struct ptu_decoder_fixture dfix_indir; -static struct ptu_decoder_fixture dfix_indir_psb; static struct ptu_decoder_fixture dfix_cond; static struct ptu_decoder_fixture dfix_event; static struct ptu_decoder_fixture dfix_event_psb; static void init_fixtures(void) { - dfix_raw.init = ptu_dfix_init; - dfix_raw.fini = ptu_dfix_fini; - - dfix_empty = dfix_raw; - dfix_empty.header = ptu_dfix_header_sync; + dfix_empty.init = ptu_dfix_init; + dfix_empty.fini = ptu_dfix_fini; - dfix_indir = dfix_raw; + dfix_indir = dfix_empty; dfix_indir.header = ptu_dfix_header_indir; - dfix_indir_psb = dfix_raw; - dfix_indir_psb.header = ptu_dfix_header_indir_psb; - - dfix_cond = dfix_raw; + dfix_cond = dfix_empty; dfix_cond.header = ptu_dfix_header_cond; - dfix_event = dfix_raw; + dfix_event = dfix_empty; dfix_event.header = ptu_dfix_header_event; - dfix_event_psb = dfix_raw; + dfix_event_psb = dfix_empty; dfix_event_psb.header = ptu_dfix_header_event_psb; } @@ -2434,15 +2169,12 @@ suite = ptunit_mk_suite(argc, argv); - ptu_run_f(suite, indir_not_synced, dfix_raw); - ptu_run_f(suite, cond_not_synced, dfix_raw); - ptu_run_f(suite, event_not_synced, dfix_raw); + ptu_run_f(suite, indir_not_synced, dfix_empty); + ptu_run_f(suite, cond_not_synced, dfix_empty); + ptu_run_f(suite, event_not_synced, dfix_empty); - ptu_run_f(suite, sync_backward, dfix_raw); - ptu_run_f(suite, sync_backward_empty_end, dfix_raw); - ptu_run_f(suite, sync_backward_empty_mid, dfix_raw); - ptu_run_f(suite, sync_backward_empty_begin, dfix_raw); - ptu_run_f(suite, decode_sync_backward, dfix_raw); + ptu_run_f(suite, sync_backward, dfix_empty); + ptu_run_f(suite, decode_sync_backward, dfix_empty); ptu_run_f(suite, indir_null, dfix_empty); ptu_run_f(suite, indir_empty, dfix_empty); @@ -2484,19 +2216,6 @@ ptu_run_f(suite, indir_skip_fup_tip_fail, dfix_indir); ptu_run_f(suite, indir_skip_fup_tip_pgd_fail, dfix_indir); - ptu_run_fp(suite, indir, dfix_indir_psb, pt_ipc_suppressed); - ptu_run_fp(suite, indir, dfix_indir_psb, pt_ipc_sext_48); - ptu_run_fp(suite, indir, dfix_indir_psb, pt_ipc_full); - ptu_run_fp(suite, indir_tnt, dfix_indir_psb, pt_ipc_suppressed); - ptu_run_fp(suite, indir_tnt, dfix_indir_psb, pt_ipc_sext_48); - ptu_run_fp(suite, indir_tnt, dfix_indir_psb, pt_ipc_full); - ptu_run_f(suite, indir_cutoff_fail, dfix_indir_psb); - ptu_run_f(suite, indir_skip_tnt_fail, dfix_indir_psb); - ptu_run_f(suite, indir_skip_tip_pge_fail, dfix_indir_psb); - ptu_run_f(suite, indir_skip_tip_pgd_fail, dfix_indir_psb); - ptu_run_f(suite, indir_skip_fup_tip_fail, dfix_indir_psb); - ptu_run_f(suite, indir_skip_fup_tip_pgd_fail, dfix_indir_psb); - ptu_run_f(suite, cond_null, dfix_empty); ptu_run_f(suite, cond_empty, dfix_empty); ptu_run_f(suite, cond, dfix_empty);
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/test/src/ptunit-retstack.c -> _service:tar_scm:v2.1.tar.gz/libipt/test/src/ptunit-retstack.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/test/src/ptunit-section-file.c -> _service:tar_scm:v2.1.tar.gz/libipt/test/src/ptunit-section-file.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2015-2022, Intel Corporation + * Copyright (c) 2015-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/test/src/ptunit-section.c -> _service:tar_scm:v2.1.tar.gz/libipt/test/src/ptunit-section.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -162,10 +163,12 @@ const char *name; uint8_t bytes = { 0xcc, 0xcc, 0xcc, 0xcc, 0xcc }; uint64_t offset, size; + int errcode; sfix_write(sfix, bytes); - sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull); + errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull); + ptu_int_eq(errcode, 0); ptu_ptr(sfix->section); name = pt_section_filename(sfix->section); @@ -182,8 +185,10 @@ static struct ptunit_result create_bad_offset(struct section_fixture *sfix) { - sfix->section = pt_mk_section(sfix->name, 0x10ull, 0x0ull); - ptu_null(sfix->section); + int errcode; + + errcode = pt_mk_section(&sfix->section, sfix->name, 0x10ull, 0x0ull); + ptu_int_eq(errcode, -pte_invalid); return ptu_passed(); } @@ -193,10 +198,12 @@ const char *name; uint8_t bytes = { 0xcc, 0xcc, 0xcc, 0xcc, 0xcc }; uint64_t offset, size; + int errcode; sfix_write(sfix, bytes); - sfix->section = pt_mk_section(sfix->name, 0x1ull, UINT64_MAX); + errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, UINT64_MAX); + ptu_int_eq(errcode, 0); ptu_ptr(sfix->section); name = pt_section_filename(sfix->section); @@ -213,7 +220,10 @@ static struct ptunit_result create_empty(struct section_fixture *sfix) { - sfix->section = pt_mk_section(sfix->name, 0x0ull, 0x10ull); + int errcode; + + errcode = pt_mk_section(&sfix->section, sfix->name, 0x0ull, 0x10ull); + ptu_int_eq(errcode, -pte_invalid); ptu_null(sfix->section); return ptu_passed(); @@ -359,7 +369,8 @@ sfix_write(sfix, bytes); - sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull); + errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull); + ptu_int_eq(errcode, 0); ptu_ptr(sfix->section); sfix->section->ucount = UINT16_MAX; @@ -380,7 +391,8 @@ sfix_write(sfix, bytes); - sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull); + errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull); + ptu_int_eq(errcode, 0); ptu_ptr(sfix->section); sfix->section->acount = UINT16_MAX; @@ -401,7 +413,8 @@ sfix_write(sfix, bytes); - sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull); + errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull); + ptu_int_eq(errcode, 0); ptu_ptr(sfix->section); sfix->section->acount = 2; @@ -421,7 +434,8 @@ sfix_write(sfix, bytes); - sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull); + errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull); + ptu_int_eq(errcode, 0); ptu_ptr(sfix->section); sfix_write(sfix, bytes); @@ -439,7 +453,8 @@ sfix_write(sfix, bytes); - sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull); + errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull); + ptu_int_eq(errcode, 0); ptu_ptr(sfix->section); errcode = pt_section_map(sfix->section); @@ -461,7 +476,8 @@ sfix_write(sfix, bytes); - sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull); + errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull); + ptu_int_eq(errcode, 0); ptu_ptr(sfix->section); errcode = pt_section_unmap(sfix->section); @@ -477,7 +493,8 @@ sfix_write(sfix, bytes); - sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull); + errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull); + ptu_int_eq(errcode, 0); ptu_ptr(sfix->section); sfix->section->mcount = UINT16_MAX; @@ -497,7 +514,8 @@ sfix_write(sfix, bytes); - sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull); + errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull); + ptu_int_eq(errcode, 0); ptu_ptr(sfix->section); errcode = pt_section_get(sfix->section); @@ -523,7 +541,8 @@ sfix_write(sfix, bytes); - sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull); + errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull); + ptu_int_eq(errcode, 0); ptu_ptr(sfix->section); sfix->section->ucount += 2; @@ -553,7 +572,8 @@ sfix_write(sfix, bytes); - sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull); + errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull); + ptu_int_eq(errcode, 0); ptu_ptr(sfix->section); sfix->section->ucount += 2; @@ -580,7 +600,8 @@ sfix_write(sfix, bytes); - sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull); + errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull); + ptu_int_eq(errcode, 0); ptu_ptr(sfix->section); errcode = pt_section_attach(sfix->section, &iscache); @@ -602,7 +623,8 @@ sfix_write(sfix, bytes); - sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull); + errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull); + ptu_int_eq(errcode, 0); ptu_ptr(sfix->section); errcode = pt_section_map(sfix->section); @@ -630,7 +652,8 @@ sfix_write(sfix, bytes); - sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull); + errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull); + ptu_int_eq(errcode, 0); ptu_ptr(sfix->section); errcode = pt_section_attach(sfix->section, &iscache); @@ -666,7 +689,8 @@ sfix_write(sfix, bytes); - sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull); + errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull); + ptu_int_eq(errcode, 0); ptu_ptr(sfix->section); errcode = pt_section_attach(sfix->section, &iscache); @@ -691,7 +715,8 @@ sfix_write(sfix, bytes); - sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull); + errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull); + ptu_int_eq(errcode, 0); ptu_ptr(sfix->section); errcode = pt_section_attach(sfix->section, &iscache); @@ -718,7 +743,8 @@ sfix_write(sfix, bytes); - sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull); + status = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull); + ptu_int_eq(status, 0); ptu_ptr(sfix->section); status = pt_section_map(sfix->section); @@ -744,7 +770,8 @@ sfix_write(sfix, bytes); - sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull); + status = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull); + ptu_int_eq(status, 0); ptu_ptr(sfix->section); status = pt_section_map(sfix->section); @@ -772,7 +799,8 @@ sfix_write(sfix, bytes); - sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull); + status = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull); + ptu_int_eq(status, 0); ptu_ptr(sfix->section); status = pt_section_map(sfix->section); @@ -797,7 +825,8 @@ sfix_write(sfix, bytes); - sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull); + status = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull); + ptu_int_eq(status, 0); ptu_ptr(sfix->section); status = pt_section_map(sfix->section); @@ -821,7 +850,8 @@ sfix_write(sfix, bytes); - sfix->section = pt_mk_section(sfix->name, 0x2ull, 0x10ull); + status = pt_mk_section(&sfix->section, sfix->name, 0x2ull, 0x10ull); + ptu_int_eq(status, 0); ptu_ptr(sfix->section); status = pt_section_map(sfix->section); @@ -845,7 +875,8 @@ sfix_write(sfix, bytes); - sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull); + status = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull); + ptu_int_eq(status, 0); ptu_ptr(sfix->section); status = pt_section_map(sfix->section); @@ -868,7 +899,8 @@ sfix_write(sfix, bytes); - sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull); + status = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull); + ptu_int_eq(status, 0); ptu_ptr(sfix->section); status = pt_section_map(sfix->section); @@ -892,7 +924,8 @@ sfix_write(sfix, bytes); - sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull); + status = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull); + ptu_int_eq(status, 0); ptu_ptr(sfix->section); status = pt_section_map(sfix->section); @@ -916,7 +949,8 @@ sfix_write(sfix, bytes); - sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull); + status = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull); + ptu_int_eq(status, 0); ptu_ptr(sfix->section); status = pt_section_read(sfix->section, buffer, 1, 0x0ull); @@ -934,7 +968,8 @@ sfix_write(sfix, bytes); - sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull); + status = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull); + ptu_int_eq(status, 0); ptu_ptr(sfix->section); status = pt_section_map(sfix->section); @@ -1073,7 +1108,8 @@ sfix_write(sfix, bytes); - sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull); + errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull); + ptu_int_eq(errcode, 0); ptu_ptr(sfix->section); #if defined(FEATURE_THREADS) @@ -1099,7 +1135,8 @@ sfix_write(sfix, bytes); - sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull); + errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull); + ptu_int_eq(errcode, 0); ptu_ptr(sfix->section); errcode = pt_section_map(sfix->section); @@ -1122,7 +1159,8 @@ sfix_write(sfix, bytes); - sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull); + errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull); + ptu_int_eq(errcode, 0); ptu_ptr(sfix->section); errcode = pt_section_map(sfix->section); @@ -1151,7 +1189,8 @@ sfix_write(sfix, bytes); - sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull); + errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull); + ptu_int_eq(errcode, 0); ptu_ptr(sfix->section); errcode = pt_section_map(sfix->section); @@ -1176,7 +1215,8 @@ sfix_write(sfix, bytes); - sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull); + errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull); + ptu_int_eq(errcode, 0); ptu_ptr(sfix->section); errcode = pt_section_alloc_bcache(sfix->section); @@ -1193,7 +1233,8 @@ sfix_write(sfix, bytes); - sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull); + errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull); + ptu_int_eq(errcode, 0); ptu_ptr(sfix->section); errcode = pt_section_memsize(sfix->section, &memsize); @@ -1211,7 +1252,8 @@ sfix_write(sfix, bytes); - sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull); + errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull); + ptu_int_eq(errcode, 0); ptu_ptr(sfix->section); errcode = pt_section_map(sfix->section); @@ -1235,7 +1277,8 @@ sfix_write(sfix, bytes); - sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull); + errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull); + ptu_int_eq(errcode, 0); ptu_ptr(sfix->section); errcode = pt_section_map(sfix->section); @@ -1262,7 +1305,8 @@ sfix_write(sfix, bytes); - sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull); + errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull); + ptu_int_eq(errcode, 0); ptu_ptr(sfix->section); errcode = pt_section_map(sfix->section); @@ -1300,31 +1344,55 @@ static struct ptunit_result sfix_fini(struct section_fixture *sfix) { - int thrd; + char *filename; + FILE *file; + int thrd, errcode; ptu_test(ptunit_thrd_fini, &sfix->thrd); - for (thrd = 0; thrd < sfix->thrd.nthreads; ++thrd) - ptu_int_eq(sfix->thrd.resultthrd, 0); - if (sfix->section) { pt_section_put(sfix->section); sfix->section = NULL; } - if (sfix->file) { - fclose(sfix->file); - sfix->file = NULL; + filename = sfix->name; + file = sfix->file; + sfix->name = NULL; + sfix->file = NULL; - if (sfix->name) - remove(sfix->name); + /* Try removing the file while we still have it open to avoid races + * with others re-using the temporary filename. + * + * On some systems that may not be possible and we can choose between: + * + * - guaranteed leaking files or + * - running the risk of removing someone elses file + * + * We choose the latter. Assuming those systems behave consistently, + * removing someone elses file should only succeed if it isn't open at + * the moment we try removing it. Given that this is a temporary file, + * we should be able to rule out accidental name clashes with + * non-termporary files. + */ + if (filename && file) { + errcode = remove(filename); + if (!errcode) { + free(filename); + filename = NULL; + } } - if (sfix->name) { - free(sfix->name); - sfix->name = NULL; + if (file) + fclose(file); + + if (filename) { + (void) remove(filename); + free(filename); } + for (thrd = 0; thrd < sfix->thrd.nthreads; ++thrd) + ptu_int_eq(sfix->thrd.resultthrd, 0); + return ptu_passed(); }
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/test/src/ptunit-sync.c -> _service:tar_scm:v2.1.tar.gz/libipt/test/src/ptunit-sync.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2014-2022, Intel Corporation + * Copyright (c) 2014-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -36,15 +37,18 @@ /* A test fixture for sync tests. */ struct sync_fixture { - /* The trace buffer. */ - uint8_t buffer1024; - /* A trace configuration. */ struct pt_config config; /* The test fixture initialization and finalization functions. */ struct ptunit_result (*init)(struct sync_fixture *); struct ptunit_result (*fini)(struct sync_fixture *); + + /* The trace buffer. + * + * We need it at the end for overread sanitizer checks. + */ + uint8_t buffer1024; }; static struct ptunit_result sfix_init(struct sync_fixture *sfix) @@ -239,15 +243,16 @@ return ptu_passed(); } -static struct ptunit_result sync_fwd_cutoff(struct sync_fixture *sfix) +static struct ptunit_result sync_fwd_cutoff(struct sync_fixture *sfix, + size_t head, size_t tail) { const uint8_t *sync; int errcode; sfix_encode_psb(sfix->config.begin); sfix_encode_psb(sfix->config.end - ptps_psb); - sfix->config.begin += 1; - sfix->config.end -= 1; + sfix->config.begin += head; + sfix->config.end -= tail; errcode = pt_sync_forward(&sync, sfix->config.begin, &sfix->config); ptu_int_eq(errcode, -pte_eos); @@ -255,15 +260,16 @@ return ptu_passed(); } -static struct ptunit_result sync_bwd_cutoff(struct sync_fixture *sfix) +static struct ptunit_result sync_bwd_cutoff(struct sync_fixture *sfix, + size_t head, size_t tail) { const uint8_t *sync; int errcode; sfix_encode_psb(sfix->config.begin); sfix_encode_psb(sfix->config.end - ptps_psb); - sfix->config.begin += 1; - sfix->config.end -= 1; + sfix->config.begin += head; + sfix->config.end -= tail; errcode = pt_sync_backward(&sync, sfix->config.end, &sfix->config); ptu_int_eq(errcode, -pte_eos); @@ -299,8 +305,10 @@ ptu_run_f(suite, sync_fwd_past, sfix); ptu_run_f(suite, sync_bwd_past, sfix); - ptu_run_f(suite, sync_fwd_cutoff, sfix); - ptu_run_f(suite, sync_bwd_cutoff, sfix); + ptu_run_fp(suite, sync_fwd_cutoff, sfix, 1, 1); + ptu_run_fp(suite, sync_fwd_cutoff, sfix, sizeof(sfix.buffer) - 8, 0); + ptu_run_fp(suite, sync_bwd_cutoff, sfix, 1, 1); + ptu_run_fp(suite, sync_bwd_cutoff, sfix, sizeof(sfix.buffer) - 8, 0); return ptunit_report(&suite); }
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/test/src/ptunit-time.c -> _service:tar_scm:v2.1.tar.gz/libipt/test/src/ptunit-time.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2014-2022, Intel Corporation + * Copyright (c) 2014-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/libipt/test/src/ptunit-tnt_cache.c -> _service:tar_scm:v2.1.tar.gz/libipt/test/src/ptunit-tnt_cache.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -158,58 +159,63 @@ return ptu_passed(); } -static struct ptunit_result update_tnt(void) +static struct ptunit_result add_empty(void) { struct pt_tnt_cache tnt_cache; - struct pt_packet_tnt packet; int errcode; pt_tnt_cache_init(&tnt_cache); - packet.bit_size = 4ull; - packet.payload = 8ull; - - errcode = pt_tnt_cache_update_tnt(&tnt_cache, &packet, NULL); + errcode = pt_tnt_cache_add(&tnt_cache, 0x29ull, 7); ptu_int_eq(errcode, 0); - ptu_uint_eq(tnt_cache.tnt, 8ull); - ptu_uint_eq(tnt_cache.index, 1ull << 3); + ptu_uint_eq(tnt_cache.tnt, 0x29ull); + ptu_uint_eq(tnt_cache.index, 0x40); return ptu_passed(); } -static struct ptunit_result update_tnt_not_empty(void) +static struct ptunit_result add_partial(void) { struct pt_tnt_cache tnt_cache; - struct pt_packet_tnt packet; int errcode; - tnt_cache.tnt = 42ull; - tnt_cache.index = 12ull; - - memset(&packet, 0, sizeof(packet)); + pt_tnt_cache_init(&tnt_cache); - errcode = pt_tnt_cache_update_tnt(&tnt_cache, &packet, NULL); - ptu_int_eq(errcode, -pte_bad_context); - ptu_uint_eq(tnt_cache.tnt, 42ull); - ptu_uint_eq(tnt_cache.index, 12ull); + errcode = pt_tnt_cache_add(&tnt_cache, 0x29ull, 3); + ptu_int_eq(errcode, 0); + ptu_uint_eq(tnt_cache.tnt, 0x1ull); + ptu_uint_eq(tnt_cache.index, 0x4); return ptu_passed(); } -static struct ptunit_result update_tnt_null_tnt(void) +static struct ptunit_result add_not_empty(void) { - struct pt_packet_tnt packet; + struct pt_tnt_cache tnt_cache; int errcode; - memset(&packet, 0, sizeof(packet)); + tnt_cache.tnt = 0x23ull; + tnt_cache.index = 0x80ull; - errcode = pt_tnt_cache_update_tnt(NULL, &packet, NULL); + errcode = pt_tnt_cache_add(&tnt_cache, 0x6ull, 4); + ptu_int_eq(errcode, 0); + ptu_uint_eq(tnt_cache.tnt, 0x236ull); + ptu_uint_eq(tnt_cache.index, 0x800ull); + + return ptu_passed(); +} + +static struct ptunit_result add_null_tnt(void) +{ + int errcode; + + errcode = pt_tnt_cache_add(NULL, 0ull, 1); ptu_int_eq(errcode, -pte_invalid); return ptu_passed(); } -static struct ptunit_result update_tnt_null_packet(void) +static struct ptunit_result add_zero_size(void) { struct pt_tnt_cache tnt_cache; int errcode; @@ -217,8 +223,8 @@ tnt_cache.tnt = 42ull; tnt_cache.index = 12ull; - errcode = pt_tnt_cache_update_tnt(&tnt_cache, NULL, NULL); - ptu_int_eq(errcode, -pte_invalid); + errcode = pt_tnt_cache_add(&tnt_cache, 0xffull, 0); + ptu_int_eq(errcode, 0); ptu_uint_eq(tnt_cache.tnt, 42ull); ptu_uint_eq(tnt_cache.index, 12ull); @@ -241,10 +247,11 @@ ptu_run(suite, query_not_taken); ptu_run(suite, query_empty); ptu_run(suite, query_null); - ptu_run(suite, update_tnt); - ptu_run(suite, update_tnt_not_empty); - ptu_run(suite, update_tnt_null_tnt); - ptu_run(suite, update_tnt_null_packet); + ptu_run(suite, add_empty); + ptu_run(suite, add_partial); + ptu_run(suite, add_not_empty); + ptu_run(suite, add_null_tnt); + ptu_run(suite, add_zero_size); return ptunit_report(&suite); }
View file
_service:tar_scm:v2.0.5.tar.gz/pevent/CMakeLists.txt -> _service:tar_scm:v2.1.tar.gz/pevent/CMakeLists.txt
Changed
@@ -1,4 +1,5 @@ -# Copyright (c) 2014-2022, Intel Corporation +# Copyright (c) 2014-2023, Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/pevent/include/pevent.h -> _service:tar_scm:v2.1.tar.gz/pevent/include/pevent.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2014-2022, Intel Corporation + * Copyright (c) 2014-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -31,7 +32,7 @@ #include <linux/perf_event.h> -#include "intel-pt.h" +#include "libipt-sb.h" #include <stdint.h> #include <stddef.h> @@ -46,6 +47,8 @@ /* The respective field in struct perf_event_attr. * * We require sample_id_all in struct perf_event_attr to be set. + * + * This field is only valid if \@sample_config is NULL. */ uint64_t sample_type; @@ -53,8 +56,17 @@ uint16_t time_shift; uint32_t time_mult; uint64_t time_zero; + +#if (LIBIPT_SB_VERSION >= 0x201) + /* The sample configuration. */ + struct pev_sample_config *sample_config; +#endif }; +#define pev_config_has(config, field) \ + (config->size >= (offsetof(struct pev_config, field) + \ + sizeof(config->field))) + static inline void pev_config_init(struct pev_config *config) { memset(config, 0, sizeof(*config));
View file
_service:tar_scm:v2.0.5.tar.gz/pevent/src/pevent.c -> _service:tar_scm:v2.1.tar.gz/pevent/src/pevent.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2014-2022, Intel Corporation + * Copyright (c) 2014-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -29,10 +30,6 @@ #include "pevent.h" -#define pev_config_has(config, field) \ - (config->size >= (offsetof(struct pev_config, field) + \ - sizeof(config->field))) - int pev_time_to_tsc(uint64_t *tsc, uint64_t time, const struct pev_config *config) { @@ -43,6 +40,15 @@ if (!tsc || !config) return -pte_internal; + /* "time 0" is for synthesized events, and is not a real time. Using + * the normal conversion for a synthesized time causes problems, so + * just translate it as TSC time 0 ("beginning of time"). + */ + if (!time) { + *tsc = 0; + return 0; + } + if (!pev_config_has(config, time_zero)) return -pte_bad_config; @@ -118,19 +124,72 @@ return -pte_bad_packet; } +static int pev_sample_type(uint64_t *psample_type, const uint64_t *pidentifier, + const struct pev_config *config) +{ + if (!psample_type || !config) + return -pte_internal; + + if (!pev_config_has(config, sample_type)) + return -pte_bad_config; + +#if (LIBIPT_SB_VERSION >= 0x201) + if (pev_config_has(config, sample_config)) { + const struct pev_sample_config *sconfig; + uint64_t identifier; + int sti, nstypes; + + sconfig = config->sample_config; + if (!sconfig || !pidentifier) { + *psample_type = config->sample_type; + return 0; + } + + identifier = *pidentifier; + nstypes = sconfig->nstypes; + for (sti = 0; sti < nstypes; ++sti) { + const struct pev_sample_type *stype; + uint64_t sample_type; + + stype = &sconfig->stypessti; + if (stype->identifier != identifier) + continue; + + sample_type = stype->sample_type; + if (!(sample_type & PERF_SAMPLE_IDENTIFIER)) + return -pte_bad_config; + + *psample_type = sample_type; + return 0; + } + } +#endif + + *psample_type = config->sample_type; + return 0; +} + static int pev_read_samples(struct pev_event *event, const uint8_t *begin, - const uint8_t *end, const struct pev_config *config) + const uint8_t *end, + const struct pev_config *config) { + const uint64_t *pidentifier; const uint8_t *pos; uint64_t sample_type; + int errcode; - if (!event || !begin || !config) + if (!event || !begin || !end || !config) return -pte_internal; - if (!pev_config_has(config, sample_type)) - return -pte_bad_config; + pidentifier = NULL; + pos = (end - sizeof(*pidentifier)); + if (begin <= pos) + pidentifier = (const uint64_t *) pos; + + errcode = pev_sample_type(&sample_type, pidentifier, config); + if (errcode < 0) + return errcode; - sample_type = config->sample_type; pos = begin; if (sample_type & PERF_SAMPLE_TID) { @@ -140,8 +199,6 @@ } if (sample_type & PERF_SAMPLE_TIME) { - int errcode; - event->sample.time = (const uint64_t *) pos; pos += 8; @@ -197,6 +254,9 @@ header = (const struct perf_event_header *) pos; pos += sizeof(*header); + if (header->size < sizeof(*header)) + return -pte_nosync; + if (!header->type || (end < (begin + header->size))) return -pte_eos; @@ -329,38 +389,54 @@ return size; } -static size_t sample_size(const struct pev_event *event) +static int pev_sample_config(size_t *psample_size, uint64_t *psample_type, + const struct pev_event *event) { - size_t size; + uint64_t sample_type; + size_t sample_size; - if (!event) - return 0; + if (!psample_size || !psample_type || !event) + return -pte_internal; - size = 0; + sample_type = 0; + sample_size = 0; if (event->sample.tid) { - size += sizeof(*event->sample.pid); - size += sizeof(*event->sample.tid); + sample_type |= PERF_SAMPLE_TID; + sample_size += sizeof(*event->sample.pid); + sample_size += sizeof(*event->sample.tid); } - if (event->sample.time) - size += sizeof(*event->sample.time); + if (event->sample.time) { + sample_type |= PERF_SAMPLE_TIME; + sample_size += sizeof(*event->sample.time); + } - if (event->sample.id) - size += sizeof(*event->sample.id); + if (event->sample.id) { + sample_type |= PERF_SAMPLE_ID; + sample_size += sizeof(*event->sample.id); + } - if (event->sample.stream_id) - size += sizeof(*event->sample.stream_id); + if (event->sample.stream_id) { + sample_type |= PERF_SAMPLE_STREAM_ID; + sample_size += sizeof(*event->sample.stream_id); + } if (event->sample.cpu) { - size += sizeof(*event->sample.cpu); - size += sizeof(uint32_t); + sample_type |= PERF_SAMPLE_CPU; + sample_size += sizeof(*event->sample.cpu); + sample_size += sizeof(uint32_t); } - if (event->sample.identifier) - size += sizeof(*event->sample.identifier); + if (event->sample.identifier) { + sample_type |= PERF_SAMPLE_IDENTIFIER; + sample_size += sizeof(*event->sample.identifier); + } - return size; + *psample_type = sample_type; + *psample_size = sample_size; + + return 0; } static void write(uint8_t **stream, const void *object, size_t size) @@ -376,17 +452,20 @@ } static int write_samples(uint8_t **stream, const struct pev_event *event, - const struct pev_config *config) + const struct pev_config *config, uint64_t sample_type) { - uint64_t sample_type; + uint64_t cstype; + int errcode; if (!event || !config) return -pte_internal; - if (!pev_config_has(config, sample_type)) - return -pte_bad_config; + errcode = pev_sample_type(&cstype, event->sample.identifier, config); + if (errcode < 0) + return errcode; - sample_type = config->sample_type; + if (cstype != sample_type) + return -pte_bad_config; if (sample_type & PERF_SAMPLE_TID) { sample_type &= ~(uint64_t) PERF_SAMPLE_TID; @@ -456,15 +535,20 @@ const struct pev_config *config) { struct perf_event_header header; + uint64_t sample_type; uint8_t *pos; - size_t size; + size_t sample_size, size; int errcode; if (!event || !begin || end < begin) return -pte_internal; + errcode = pev_sample_config(&sample_size, &sample_type, event); + if (errcode < 0) + return errcode; + pos = begin; - size = sizeof(header) + sample_size(event); + size = sizeof(header) + sample_size; if (UINT16_MAX < size) return -pte_internal; @@ -478,7 +562,11 @@ case PERF_RECORD_MMAP: { size_t slen, gap; - slen = strlen(event->record.mmap->filename) + 1; + slen = strnlen(event->record.mmap->filename, UINT16_MAX); + if (UINT16_MAX <= slen) + return -pte_eos; + + slen += 1; gap = ((slen + 7u) & ~7u) - slen; size += sizeof(*event->record.mmap) + slen + gap; @@ -512,7 +600,11 @@ case PERF_RECORD_COMM: { size_t slen, gap; - slen = strlen(event->record.comm->comm) + 1; + slen = strnlen(event->record.comm->comm, UINT16_MAX); + if (UINT16_MAX <= slen) + return -pte_eos; + + slen += 1; gap = ((slen + 7u) & ~7u) - slen; size += sizeof(*event->record.comm) + slen + gap; @@ -574,7 +666,11 @@ case PERF_RECORD_MMAP2: { size_t slen, gap; - slen = strlen(event->record.mmap2->filename) + 1; + slen = strnlen(event->record.mmap2->filename, UINT16_MAX); + if (UINT16_MAX <= slen) + return -pte_eos; + + slen += 1; gap = ((slen + 7u) & ~7u) - slen; size += sizeof(*event->record.mmap2) + slen + gap; @@ -656,7 +752,7 @@ break; } - errcode = write_samples(&pos, event, config); + errcode = write_samples(&pos, event, config, sample_type); if (errcode < 0) return errcode;
View file
_service:tar_scm:v2.0.5.tar.gz/pevent/test/src/ptunit-pevent.c -> _service:tar_scm:v2.1.tar.gz/pevent/test/src/ptunit-pevent.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2014-2022, Intel Corporation + * Copyright (c) 2014-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,6 +31,13 @@ #include "pevent.h" +#include <stdlib.h> +#include <stdio.h> + +#if defined(_MSC_VER) && (_MSC_VER < 1900) +# define snprintf _snprintf_c +#endif + /* A test fixture. */ struct pev_fixture { @@ -46,12 +54,16 @@ /* The perf event configuration. */ struct pev_config config; + /* The sample_type to be tested. */ + uint64_t sample_type; + /* Test samples. */ struct { uint32_t pid, tid; uint64_t time; uint64_t tsc; uint32_t cpu; + uint64_t identifier; } sample; /* The test fixture initialization and finalization functions. */ @@ -69,6 +81,16 @@ pev_config_init(&pfix->config); + pfix->sample_type = 0; + + return ptu_passed(); +} + +static struct ptunit_result pfix_fini(struct pev_fixture *pfix) +{ +#if (LIBIPT_SB_VERSION >= 0x201) + free(pfix->config.sample_config); +#endif return ptu_passed(); } @@ -81,6 +103,7 @@ pfix->config.time_shift = 4; pfix->config.time_mult = 3; + pfix->sample_type = pfix->config.sample_type; pfix->sample.time = 0xa0b00cdeull; pfix->event0.sample.time = &pfix->sample.time; @@ -94,6 +117,7 @@ pfix->config.sample_type |= (uint64_t) PERF_SAMPLE_TID; pfix->config.sample_type |= (uint64_t) PERF_SAMPLE_CPU; + pfix->sample_type = pfix->config.sample_type; pfix->sample.pid = 0xa0; pfix->sample.tid = 0xa1; pfix->sample.cpu = 0xb; @@ -105,6 +129,40 @@ return ptu_passed(); } +#if (LIBIPT_SB_VERSION >= 0x201) +static struct ptunit_result pfix_init_sample_config(struct pev_fixture *pfix) +{ + struct pev_sample_config *sample_config; + + ptu_test(pfix_init, pfix); + + sample_config = malloc(sizeof(*pfix->config.sample_config) + + (3 * sizeof(struct pev_sample_type))); + ptu_ptr(sample_config); + + pfix->config.sample_config = sample_config; + sample_config->nstypes = 3; + sample_config->stypes0.identifier = 1; + sample_config->stypes0.sample_type = (uint64_t) + PERF_SAMPLE_TID | PERF_SAMPLE_IDENTIFIER; + sample_config->stypes1.identifier = 2; + sample_config->stypes1.sample_type = (uint64_t) + PERF_SAMPLE_CPU | PERF_SAMPLE_IDENTIFIER; + sample_config->stypes2.identifier = 3; + sample_config->stypes2.sample_type = (uint64_t) + PERF_SAMPLE_TIME | PERF_SAMPLE_IDENTIFIER; + + pfix->sample_type = sample_config->stypes1.sample_type; + pfix->sample.cpu = 0xb; + pfix->sample.identifier = sample_config->stypes1.identifier; + + pfix->event0.sample.cpu = &pfix->sample.cpu; + pfix->event0.sample.identifier = &pfix->sample.identifier; + + return ptu_passed(); +} +#endif + static struct ptunit_result pfix_read_write(struct pev_fixture *pfix) { uint8_t *begin, *end; @@ -182,19 +240,19 @@ static struct ptunit_result pfix_check_sample(struct pev_fixture *pfix) { - if (pfix->config.sample_type & PERF_SAMPLE_TID) + if (pfix->sample_type & PERF_SAMPLE_TID) ptu_test(pfix_check_sample_tid, pfix); else { ptu_null(pfix->event1.sample.pid); ptu_null(pfix->event1.sample.tid); } - if (pfix->config.sample_type & PERF_SAMPLE_TIME) + if (pfix->sample_type & PERF_SAMPLE_TIME) ptu_test(pfix_check_sample_time, pfix); else ptu_null(pfix->event1.sample.time); - if (pfix->config.sample_type & PERF_SAMPLE_CPU) + if (pfix->sample_type & PERF_SAMPLE_CPU) ptu_test(pfix_check_sample_cpu, pfix); else ptu_null(pfix->event1.sample.cpu); @@ -281,13 +339,13 @@ memset(&config, 0, sizeof(config)); config.time_mult = 1; - errcode = pev_time_to_tsc(&tsc, 0x0ull, &config); + errcode = pev_time_to_tsc(&tsc, 0x1ull, &config); ptu_int_eq(errcode, -pte_bad_config); config.size = sizeof(config); config.time_mult = 0; - errcode = pev_time_to_tsc(&tsc, 0x0ull, &config); + errcode = pev_time_to_tsc(&tsc, 0x1ull, &config); ptu_int_eq(errcode, -pte_bad_config); return ptu_passed(); @@ -363,6 +421,30 @@ return ptu_passed(); } +static struct ptunit_result nosync(uint16_t type) +{ + union { + struct perf_event_header header; + uint8_t buffer128; + } input; + struct pev_config config; + struct pev_event event; + int errcode; + + pev_config_init(&config); + + memset(input.buffer, 0xcc, sizeof(input.buffer)); + input.header.type = type; + input.header.misc = 0; + input.header.size = sizeof(input.header.type); + + errcode = pev_read(&event, input.buffer, + input.buffer + sizeof(input.buffer), &config); + ptu_int_eq(errcode, -pte_nosync); + + return ptu_passed(); +} + static struct ptunit_result bad_string(uint16_t type) { union { @@ -388,19 +470,22 @@ return ptu_passed(); } -static struct ptunit_result mmap(struct pev_fixture *pfix) +static struct ptunit_result record_mmap(struct pev_fixture *pfix) { union { struct pev_record_mmap record; char buffer1024; } mmap; + memset(&mmap, 0, sizeof(mmap)); + mmap.record.pid = 0xa; mmap.record.tid = 0xb; mmap.record.addr = 0xa00100ull; mmap.record.len = 0x110ull; mmap.record.pgoff = 0xb0000ull; - strcpy(mmap.record.filename, "foo.so"); + snprintf(mmap.record.filename, + sizeof(mmap.buffer) - sizeof(mmap.record), "%s", "foo.so"); pfix->event0.record.mmap = &mmap.record; pfix->event0.type = PERF_RECORD_MMAP; @@ -420,7 +505,7 @@ return ptu_passed(); } -static struct ptunit_result lost(struct pev_fixture *pfix) +static struct ptunit_result record_lost(struct pev_fixture *pfix) { struct pev_record_lost lost; @@ -441,16 +526,19 @@ return ptu_passed(); } -static struct ptunit_result comm(struct pev_fixture *pfix) +static struct ptunit_result record_comm(struct pev_fixture *pfix) { union { struct pev_record_comm record; char buffer1024; } comm; + memset(&comm, 0, sizeof(comm)); + comm.record.pid = 0xa; comm.record.tid = 0xb; - strcpy(comm.record.comm, "foo -b ar"); + snprintf(comm.record.comm, sizeof(comm.buffer) - sizeof(comm.record), + "%s", "foo -b ar"); pfix->event0.record.comm = &comm.record; pfix->event0.type = PERF_RECORD_COMM; @@ -494,7 +582,7 @@ return ptu_passed(); } -static struct ptunit_result throttle(struct pev_fixture *pfix) +static struct ptunit_result record_throttle(struct pev_fixture *pfix) { struct pev_record_throttle throttle; @@ -518,7 +606,7 @@ return ptu_passed(); } -static struct ptunit_result unthrottle(struct pev_fixture *pfix) +static struct ptunit_result record_unthrottle(struct pev_fixture *pfix) { struct pev_record_throttle throttle; @@ -542,7 +630,7 @@ return ptu_passed(); } -static struct ptunit_result fork(struct pev_fixture *pfix) +static struct ptunit_result record_fork(struct pev_fixture *pfix) { struct pev_record_fork fork; @@ -569,13 +657,15 @@ return ptu_passed(); } -static struct ptunit_result mmap2(struct pev_fixture *pfix) +static struct ptunit_result record_mmap2(struct pev_fixture *pfix) { union { struct pev_record_mmap2 record; char buffer1024; } mmap2; + memset(&mmap2, 0, sizeof(mmap2)); + mmap2.record.pid = 0xa; mmap2.record.tid = 0xb; mmap2.record.addr = 0xa00100ull; @@ -587,7 +677,8 @@ mmap2.record.ino_generation = 0x4ull; mmap2.record.prot = 0x755; mmap2.record.flags = 0; - strcpy(mmap2.record.filename, "foo.so"); + snprintf(mmap2.record.filename, + sizeof(mmap2.buffer) - sizeof(mmap2.record), "%s", "foo.so"); pfix->event0.record.mmap2 = &mmap2.record; pfix->event0.type = PERF_RECORD_MMAP2; @@ -615,7 +706,7 @@ return ptu_passed(); } -static struct ptunit_result aux(struct pev_fixture *pfix) +static struct ptunit_result record_aux(struct pev_fixture *pfix) { struct pev_record_aux aux; @@ -638,7 +729,7 @@ return ptu_passed(); } -static struct ptunit_result itrace_start(struct pev_fixture *pfix) +static struct ptunit_result record_itrace_start(struct pev_fixture *pfix) { struct pev_record_itrace_start itrace_start; @@ -659,7 +750,7 @@ return ptu_passed(); } -static struct ptunit_result lost_samples(struct pev_fixture *pfix) +static struct ptunit_result record_lost_samples(struct pev_fixture *pfix) { struct pev_record_lost_samples lost_samples; @@ -679,8 +770,8 @@ return ptu_passed(); } -static struct ptunit_result switch_task(struct pev_fixture *pfix, - int switch_out) +static struct ptunit_result record_switch_task(struct pev_fixture *pfix, + int switch_out) { pfix->event0.type = PERF_RECORD_SWITCH; pfix->event0.misc = switch_out ? PERF_RECORD_MISC_SWITCH_OUT : 0; @@ -694,8 +785,8 @@ return ptu_passed(); } -static struct ptunit_result switch_cpu_wide(struct pev_fixture *pfix, - int switch_out) +static struct ptunit_result record_switch_cpu_wide(struct pev_fixture *pfix, + int switch_out) { struct pev_record_switch_cpu_wide switch_cpu_wide; @@ -723,6 +814,9 @@ int main(int argc, char **argv) { struct pev_fixture pfix, pfix_time, pfix_who; +#if (LIBIPT_SB_VERSION >= 0x201) + struct pev_fixture pfix_sconf; +#endif struct ptunit_suite suite; pfix.init = pfix_init; @@ -734,6 +828,10 @@ pfix_who.init = pfix_init_sample_who; pfix_who.fini = NULL; +#if (LIBIPT_SB_VERSION >= 0x201) + pfix_sconf.init = pfix_init_sample_config; + pfix_sconf.fini = pfix_fini; +#endif suite = ptunit_mk_suite(argc, argv); ptu_run(suite, time_to_tsc_null); @@ -751,53 +849,75 @@ ptu_run_p(suite, bad_string, PERF_RECORD_COMM); ptu_run_p(suite, bad_string, PERF_RECORD_MMAP2); - ptu_run_f(suite, mmap, pfix); - ptu_run_f(suite, lost, pfix); - ptu_run_f(suite, comm, pfix); + ptu_run_p(suite, nosync, PERF_RECORD_MMAP); + ptu_run_p(suite, nosync, PERF_RECORD_COMM); + ptu_run_p(suite, nosync, 0); + + ptu_run_f(suite, record_mmap, pfix); + ptu_run_f(suite, record_lost, pfix); + ptu_run_f(suite, record_comm, pfix); ptu_run_f(suite, record_exit, pfix); - ptu_run_f(suite, throttle, pfix); - ptu_run_f(suite, unthrottle, pfix); - ptu_run_f(suite, fork, pfix); - ptu_run_f(suite, mmap2, pfix); - ptu_run_f(suite, aux, pfix); - ptu_run_f(suite, itrace_start, pfix); - ptu_run_f(suite, lost_samples, pfix); - ptu_run_fp(suite, switch_task, pfix, 0); - ptu_run_fp(suite, switch_task, pfix, 1); - ptu_run_fp(suite, switch_cpu_wide, pfix, 0); - ptu_run_fp(suite, switch_cpu_wide, pfix, 1); - - ptu_run_f(suite, mmap, pfix_time); - ptu_run_f(suite, lost, pfix_time); - ptu_run_f(suite, comm, pfix_time); + ptu_run_f(suite, record_throttle, pfix); + ptu_run_f(suite, record_unthrottle, pfix); + ptu_run_f(suite, record_fork, pfix); + ptu_run_f(suite, record_mmap2, pfix); + ptu_run_f(suite, record_aux, pfix); + ptu_run_f(suite, record_itrace_start, pfix); + ptu_run_f(suite, record_lost_samples, pfix); + ptu_run_fp(suite, record_switch_task, pfix, 0); + ptu_run_fp(suite, record_switch_task, pfix, 1); + ptu_run_fp(suite, record_switch_cpu_wide, pfix, 0); + ptu_run_fp(suite, record_switch_cpu_wide, pfix, 1); + + ptu_run_f(suite, record_mmap, pfix_time); + ptu_run_f(suite, record_lost, pfix_time); + ptu_run_f(suite, record_comm, pfix_time); ptu_run_f(suite, record_exit, pfix_time); - ptu_run_f(suite, throttle, pfix_time); - ptu_run_f(suite, unthrottle, pfix_time); - ptu_run_f(suite, fork, pfix_time); - ptu_run_f(suite, mmap2, pfix_time); - ptu_run_f(suite, aux, pfix_time); - ptu_run_f(suite, itrace_start, pfix_time); - ptu_run_f(suite, lost_samples, pfix_time); - ptu_run_fp(suite, switch_task, pfix_time, 0); - ptu_run_fp(suite, switch_task, pfix_time, 1); - ptu_run_fp(suite, switch_cpu_wide, pfix_time, 0); - ptu_run_fp(suite, switch_cpu_wide, pfix_time, 1); - - ptu_run_f(suite, mmap, pfix_who); - ptu_run_f(suite, lost, pfix_who); - ptu_run_f(suite, comm, pfix_who); + ptu_run_f(suite, record_throttle, pfix_time); + ptu_run_f(suite, record_unthrottle, pfix_time); + ptu_run_f(suite, record_fork, pfix_time); + ptu_run_f(suite, record_mmap2, pfix_time); + ptu_run_f(suite, record_aux, pfix_time); + ptu_run_f(suite, record_itrace_start, pfix_time); + ptu_run_f(suite, record_lost_samples, pfix_time); + ptu_run_fp(suite, record_switch_task, pfix_time, 0); + ptu_run_fp(suite, record_switch_task, pfix_time, 1); + ptu_run_fp(suite, record_switch_cpu_wide, pfix_time, 0); + ptu_run_fp(suite, record_switch_cpu_wide, pfix_time, 1); + + ptu_run_f(suite, record_mmap, pfix_who); + ptu_run_f(suite, record_lost, pfix_who); + ptu_run_f(suite, record_comm, pfix_who); ptu_run_f(suite, record_exit, pfix_who); - ptu_run_f(suite, throttle, pfix_who); - ptu_run_f(suite, unthrottle, pfix_who); - ptu_run_f(suite, fork, pfix_who); - ptu_run_f(suite, mmap2, pfix_who); - ptu_run_f(suite, aux, pfix_who); - ptu_run_f(suite, itrace_start, pfix_who); - ptu_run_f(suite, lost_samples, pfix_who); - ptu_run_fp(suite, switch_task, pfix_who, 0); - ptu_run_fp(suite, switch_task, pfix_who, 1); - ptu_run_fp(suite, switch_cpu_wide, pfix_who, 0); - ptu_run_fp(suite, switch_cpu_wide, pfix_who, 1); + ptu_run_f(suite, record_throttle, pfix_who); + ptu_run_f(suite, record_unthrottle, pfix_who); + ptu_run_f(suite, record_fork, pfix_who); + ptu_run_f(suite, record_mmap2, pfix_who); + ptu_run_f(suite, record_aux, pfix_who); + ptu_run_f(suite, record_itrace_start, pfix_who); + ptu_run_f(suite, record_lost_samples, pfix_who); + ptu_run_fp(suite, record_switch_task, pfix_who, 0); + ptu_run_fp(suite, record_switch_task, pfix_who, 1); + ptu_run_fp(suite, record_switch_cpu_wide, pfix_who, 0); + ptu_run_fp(suite, record_switch_cpu_wide, pfix_who, 1); + +#if (LIBIPT_SB_VERSION >= 0x201) + ptu_run_f(suite, record_mmap, pfix_sconf); + ptu_run_f(suite, record_lost, pfix_sconf); + ptu_run_f(suite, record_comm, pfix_sconf); + ptu_run_f(suite, record_exit, pfix_sconf); + ptu_run_f(suite, record_throttle, pfix_sconf); + ptu_run_f(suite, record_unthrottle, pfix_sconf); + ptu_run_f(suite, record_fork, pfix_sconf); + ptu_run_f(suite, record_mmap2, pfix_sconf); + ptu_run_f(suite, record_aux, pfix_sconf); + ptu_run_f(suite, record_itrace_start, pfix_sconf); + ptu_run_f(suite, record_lost_samples, pfix_sconf); + ptu_run_fp(suite, record_switch_task, pfix_sconf, 0); + ptu_run_fp(suite, record_switch_task, pfix_sconf, 1); + ptu_run_fp(suite, record_switch_cpu_wide, pfix_sconf, 0); + ptu_run_fp(suite, record_switch_cpu_wide, pfix_sconf, 1); +#endif return ptunit_report(&suite); }
View file
_service:tar_scm:v2.0.5.tar.gz/ptdump/CMakeLists.txt -> _service:tar_scm:v2.1.tar.gz/ptdump/CMakeLists.txt
Changed
@@ -1,4 +1,5 @@ -# Copyright (c) 2013-2022, Intel Corporation +# Copyright (c) 2013-2023, Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: @@ -36,14 +37,6 @@ ../libipt/src/pt_time.c ) -if (CMAKE_HOST_UNIX) - set(PTDUMP_FILES ${PTDUMP_FILES} ../libipt/src/posix/pt_cpuid.c) -endif (CMAKE_HOST_UNIX) - -if (CMAKE_HOST_WIN32) - set(PTDUMP_FILES ${PTDUMP_FILES} ../libipt/src/windows/pt_cpuid.c) -endif (CMAKE_HOST_WIN32) - add_executable(ptdump ${PTDUMP_FILES} )
View file
_service:tar_scm:v2.0.5.tar.gz/ptdump/src/ptdump.c -> _service:tar_scm:v2.1.tar.gz/ptdump/src/ptdump.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -80,6 +81,11 @@ /* Show timing information as delta to the previous value. */ uint32_t show_time_as_delta:1; +#if (LIBIPT_VERSION >= 0x201) + /* Preserve timing calibration on overflow. */ + uint32_t keep_tcal_on_ovf:1; +#endif + /* Quiet mode: Don't print anything but errors. */ uint32_t quiet:1; @@ -214,6 +220,9 @@ printf(" --no-tcal skip timing calibration.\n"); printf(" this will result in errors when CYC packets are encountered.\n"); printf(" --no-wall-clock suppress the no-time error and print relative time.\n"); +#if (LIBIPT_VERSION >= 0x201) + printf(" --keep-tcal-on-ovf preserve timing calibration on overflow.\n"); +#endif #if defined(FEATURE_SIDEBAND) printf(" --sb:compact | --sb show sideband records in compact format.\n"); printf(" --sb:verbose show sideband records in verbose format.\n"); @@ -226,6 +235,8 @@ printf(" load a perf_event sideband stream from <file>.\n"); printf(" an optional offset or range can be given.\n"); printf(" --pevent:sample-type <val> set perf_event_attr.sample_type to <val> (default: 0).\n"); + printf(" --pevent:sample-config <id>:<val>\n"); + printf(" set perf_event_attr.sample_type to <val> for event <id>.\n"); printf(" --pevent:time-zero <val> set perf_event_mmap_page.time_zero to <val> (default: 0).\n"); printf(" --pevent:time-shift <val> set perf_event_mmap_page.time_shift to <val> (default: 0).\n"); printf(" --pevent:time-mult <val> set perf_event_mmap_page.time_mult to <val> (default: 1).\n"); @@ -238,9 +249,8 @@ printf(" --pevent:vdso-ia32 <file> ignored.\n"); #endif /* defined(FEATURE_PEVENT) */ #endif /* defined(FEATURE_SIDEBAND) */ - printf(" --cpu none|auto|f/m/s set cpu to the given value and decode according to:\n"); + printf(" --cpu none|f/m/s set cpu to the given value and decode according to:\n"); printf(" none spec (default)\n"); - printf(" auto current cpu\n"); printf(" f/m/s family/model/stepping\n"); printf(" --mtc-freq <n> set the MTC frequency (IA32_RTIT_CTL17:14) to <n>.\n"); printf(" --nom-freq <n> set the nominal frequency (MSR_PLATFORM_INFO15:8) to <n>.\n"); @@ -581,6 +591,7 @@ { const uint8_t *begin, *end; char *bbegin, *bend; + int len; if (!buffer || !packet) return diag("error printing packet", offset, -pte_internal); @@ -594,16 +605,12 @@ bbegin = buffer->raw; bend = bbegin + sizeof(buffer->raw); - for (; begin < end; ++begin) { - char *pos; - - pos = bbegin; - bbegin += 2; + for (; begin < end; ++begin, bbegin += len) { + size_t size = (size_t) ((uintptr_t) bend - (uintptr_t) bbegin); - if (bend <= bbegin) + len = snprintf(bbegin, size, "%02x", *begin); + if (len != 2) return diag("truncating raw packet", offset, 0); - - sprintf(pos, "%02x", *begin); } return 0; @@ -1096,6 +1103,22 @@ case ppt_ovf: print_field(buffer->opcode, "ovf"); + + if (options->track_time) { +#if (LIBIPT_VERSION >= 0x201) + if (options->keep_tcal_on_ovf) { + int errcode; + + errcode = pt_tcal_update_ovf(&tracking->tcal, + config); + if (errcode < 0) + diag("error calibrating time", + offset, errcode); + } else +#endif + pt_tcal_init(&tracking->tcal); + } + return 0; case ppt_stop: @@ -1181,9 +1204,16 @@ sep = csd0 && csl0 ? ", " : ""; print_field(buffer->opcode, "mode.exec"); +#if (LIBIPT_VERSION < 0x201) print_field(buffer->payload.standard, "%s%s%s", csd, sep, csl); - +#else + print_field(buffer->payload.standard, "%s%s%s%s%s", + csd, sep, csl, + mode->bits.exec.iflag && + (csd0 || csl0) ? ", " : "", + mode->bits.exec.iflag ? "if" : ""); +#endif if (options->show_exec_mode) { const char *em; @@ -1334,6 +1364,60 @@ packet->payload.ptw.ip ? ", ip" : ""); return 0; + +#if (LIBIPT_VERSION >= 0x201) + case ppt_cfe: + print_field(buffer->opcode, "cfe"); + + switch (packet->payload.cfe.type) { + case pt_cfe_intr: + case pt_cfe_vmexit_intr: + case pt_cfe_uintr: + print_field(buffer->payload.standard, "%u: %u%s", + packet->payload.cfe.type, + packet->payload.cfe.vector, + packet->payload.cfe.ip ? ", ip" : ""); + return 0; + + case pt_cfe_sipi: + print_field(buffer->payload.standard, "%u: %x%s", + packet->payload.cfe.type, + packet->payload.cfe.vector, + packet->payload.cfe.ip ? ", ip" : ""); + return 0; + + case pt_cfe_iret: + case pt_cfe_smi: + case pt_cfe_rsm: + case pt_cfe_init: + case pt_cfe_vmentry: + case pt_cfe_vmexit: + case pt_cfe_shutdown: + case pt_cfe_uiret: + break; + } + + print_field(buffer->payload.standard, "%u%s", + packet->payload.cfe.type, + packet->payload.cfe.ip ? ", ip" : ""); + return 0; + + case ppt_evd: + print_field(buffer->opcode, "evd"); + print_field(buffer->payload.standard, "%u: %" PRIx64, + packet->payload.evd.type, + packet->payload.evd.payload); + + switch (packet->payload.evd.type) { + case pt_evd_cr2: + case pt_evd_vmxq: + case pt_evd_vmxr: + break; + } + + return 0; + +#endif /* (LIBIPT_VERSION >= 0x201) */ } return diag("unknown packet", offset, -pte_bad_opc); @@ -1553,6 +1637,58 @@ return 0; } +static int pt_parse_sample_config(struct pt_sb_pevent_config *pevent, + const char *arg) +{ + struct pev_sample_config *sample_config; + uint64_t identifier, sample_type; + uint8_t nstypes; + char *rest; + + if (!pevent || !arg) + return -pte_internal; + + errno = 0; + identifier = strtoull(arg, &rest, 0); + if (errno || (rest == arg)) + return -pte_invalid; + + arg = rest; + if (arg0 != ':') + return -pte_invalid; + + arg += 1; + sample_type = strtoull(arg, &rest, 0); + if (errno || *rest) + return -pte_invalid; + + sample_config = pevent->sample_config; + if (!sample_config) { + sample_config = malloc(sizeof(*sample_config)); + if (!sample_config) + return -pte_nomem; + + memset(sample_config, 0, sizeof(*sample_config)); + pevent->sample_config = sample_config; + } + + nstypes = sample_config->nstypes; + sample_config = realloc(sample_config, + sizeof(*sample_config) + + ((nstypes + 1) * + sizeof(struct pev_sample_type))); + if (!sample_config) + return -pte_nomem; + + sample_config->stypesnstypes.identifier = identifier; + sample_config->stypesnstypes.sample_type = sample_type; + sample_config->nstypes = nstypes + 1; + + pevent->sample_config = sample_config; + + return 0; +} + #endif /* defined(FEATURE_PEVENT) */ #endif /* defined(FEATURE_SIDEBAND) */ @@ -1722,6 +1858,10 @@ options->no_tcal = 1; else if (strcmp(argvidx, "--no-wall-clock") == 0) options->no_wall_clock = 1; +#if (LIBIPT_VERSION >= 0x201) + else if (strcmp(argvidx, "--keep-tcal-on-ovf") == 0) + options->keep_tcal_on_ovf = 1; +#endif #if defined(FEATURE_SIDEBAND) else if ((strcmp(argvidx, "--sb:compact") == 0) || (strcmp(argvidx, "--sb") == 0)) { @@ -1766,6 +1906,15 @@ "--pevent:sample-type", argv++idx, argv0)) return -1; + } else if (strcmp(argvidx, "--pevent:sample-config") == 0) { + errcode = pt_parse_sample_config(&pevent, argv++idx); + if (errcode < 0) { + fprintf(stderr, + "%s: bad sample config %s: %s.\n", + argv0, argvidx-1, + pt_errstr(pt_errcode(errcode))); + return -1; + } } else if (strcmp(argvidx, "--pevent:time-zero") == 0) { if (!get_arg_uint64(&pevent.time_zero, "--pevent:time-zero", @@ -1821,18 +1970,6 @@ return -1; } - if (strcmp(arg, "auto") == 0) { - errcode = pt_cpu_read(&config->cpu); - if (errcode < 0) { - fprintf(stderr, - "%s: error reading cpu: %s.\n", - argv0, - pt_errstr(pt_errcode(errcode))); - return -1; - } - continue; - } - if (strcmp(arg, "none") == 0) { memset(&config->cpu, 0, sizeof(config->cpu)); continue;
View file
_service:tar_scm:v2.1.tar.gz/ptseg
Added
+(directory)
View file
_service:tar_scm:v2.1.tar.gz/ptseg/CMakeLists.txt
Added
@@ -0,0 +1,32 @@ +# Copyright (c) 2018-2023, Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of Intel Corporation nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +add_executable(ptseg + src/ptseg.c +) + +target_link_libraries(ptseg libipt)
View file
_service:tar_scm:v2.1.tar.gz/ptseg/src
Added
+(directory)
View file
_service:tar_scm:v2.1.tar.gz/ptseg/src/ptseg.c
Added
@@ -0,0 +1,366 @@ +/* + * Copyright (c) 2018-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "pt_version.h" + +#include "intel-pt.h" + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <errno.h> + + +static int help(const char *ptseg) +{ + printf("usage: %s <options> <ptfile>:<offset>\n\n", ptseg); + printf("options:\n"); + printf(" --help|-h this text.\n"); + printf(" --version display version information and exit.\n"); + + return 0; +} + +static int usage(const char *ptseg) +{ + help(ptseg); + + return 1; +} + +static int version(const char *ptseg) +{ + pt_print_tool_version(ptseg); + + return 0; +} + +static int internal_error(const char *ptseg) +{ + fprintf(stderr, "%s: internal error.\n", ptseg); + + return 1; +} + +static int bad_option(const char *ptseg, const char *arg) +{ + fprintf(stderr, "%s: unknown option: %s.\n", ptseg, arg); + + return 1; +} + +static int no_ptfile(const char *ptseg) +{ + fprintf(stderr, "%s: missing ptfile.\n", ptseg); + + return 1; +} + +static int trailing_junk(const char *ptseg, const char *arg) +{ + fprintf(stderr, "%s: trailing junk: %s.\n", ptseg, arg); + + return 1; +} + +static int no_filename(const char *ptseg, const char *arg) +{ + fprintf(stderr, "%s: missing file name: %s.\n", ptseg, arg); + + return 1; +} + +static int no_offset(const char *ptseg, const char *arg) +{ + fprintf(stderr, "%s: missing file offset: %s.\n", ptseg, arg); + + return 1; +} + +static int bad_offset(const char *ptseg, const char *arg) +{ + fprintf(stderr, "%s: bad file offset: %s.\n", ptseg, arg); + + return 1; +} + +static int decode_error(const char *ptseg, int errcode) +{ + fprintf(stderr, "%s: decode error: %s.\n", ptseg, + pt_errstr(pt_errcode(errcode))); + + return -errcode; +} + +static int load_file(uint8_t **buffer, size_t *psize, const char *filename, + uint64_t offset, uint64_t size, const char *ptseg) +{ + uint8_t *content; + size_t read; + FILE *file; + long fsize, begin, end; + int errcode; + + if (!buffer || !psize || !filename) + return internal_error(ptseg); + + errno = 0; + file = fopen(filename, "rb"); + if (!file) { + fprintf(stderr, "%s: failed to open %s: %d.\n", + ptseg, filename, errno); + return -1; + } + + errcode = fseek(file, 0, SEEK_END); + if (errcode) { + fprintf(stderr, "%s: failed to determine size of %s: %d.\n", + ptseg, filename, errno); + goto err_file; + } + + fsize = ftell(file); + if (fsize < 0) { + fprintf(stderr, "%s: failed to determine size of %s: %d.\n", + ptseg, filename, errno); + goto err_file; + } + + begin = (long) offset; + if (((uint64_t) begin != offset) || (fsize <= begin)) { + fprintf(stderr, + "%s: bad offset 0x%" PRIx64 " into %s.\n", + ptseg, offset, filename); + goto err_file; + } + + end = fsize; + if (size) { + uint64_t range_end; + + range_end = offset + size; + if ((uint64_t) end < range_end) { + fprintf(stderr, + "%s: bad range 0x%" PRIx64 " in %s.\n", + ptseg, range_end, filename); + goto err_file; + } + + end = (long) range_end; + } + + fsize = end - begin; + + content = malloc((size_t) fsize); + if (!content) { + fprintf(stderr, "%s: failed to allocated memory %s.\n", + ptseg, filename); + goto err_file; + } + + errcode = fseek(file, begin, SEEK_SET); + if (errcode) { + fprintf(stderr, "%s: failed to load %s: %d.\n", + ptseg, filename, errno); + goto err_content; + } + + read = fread(content, (size_t) fsize, 1u, file); + if (read != 1) { + fprintf(stderr, "%s: failed to load %s: %d.\n", + ptseg, filename, errno); + goto err_content; + } + + fclose(file); + + *buffer = content; + *psize = (size_t) fsize; + + return 0; + +err_content: + free(content); + +err_file: + fclose(file); + return -1; +} + +static int ptseg_pkt_find_seg(uint64_t *begin, uint64_t *end, + struct pt_packet_decoder *decoder, + uint64_t offset) +{ + int errcode; + + errcode = pt_pkt_sync_set(decoder, offset); + if (errcode < 0) + return errcode; + + errcode = pt_pkt_sync_backward(decoder); + if (errcode < 0) { + if (errcode != -pte_eos) + return errcode; + } else { + errcode = pt_pkt_get_offset(decoder, begin); + if (errcode < 0) + return errcode; + } + + errcode = pt_pkt_sync_forward(decoder); + if (errcode < 0) { + if (errcode != -pte_eos) + return errcode; + } else { + errcode = pt_pkt_get_offset(decoder, end); + if (errcode < 0) + return errcode; + } + + return 0; +} + +static int ptseg_find_seg(uint64_t *begin, uint64_t *end, + const struct pt_config *config, uint64_t offset) +{ + struct pt_packet_decoder *decoder; + int errcode; + + decoder = pt_pkt_alloc_decoder(config); + if (!decoder) + return -pte_nomem; + + errcode = ptseg_pkt_find_seg(begin, end, decoder, offset); + + pt_pkt_free_decoder(decoder); + + return errcode; +} + +static int ptseg_print_seg(const char *ptfile, uint64_t offset, + const char *ptseg) +{ + struct pt_config config; + uint64_t begin, end; + uint8_t *buffer; + size_t size; + int errcode; + + errcode = load_file(&buffer, &size, ptfile, 0ull, 0ull, ptseg); + if (errcode) + return errcode; + + pt_config_init(&config); + config.begin = buffer; + config.end = buffer + size; + + begin = 0ull; + end = size; + + errcode = ptseg_find_seg(&begin, &end, &config, offset); + + free(buffer); + + if (errcode < 0) + return decode_error(ptseg, errcode); + + printf("0x%" PRIx64 "-0x%" PRIx64 " (offset: 0x%" PRIx64 ", size: 0x%" + PRIx64 ")\n", begin, end, offset - begin, end - begin); + + return 0; +} + +static int ptseg_split_ptarg(const char **ptfile, uint64_t *ptoffset, + char *ptarg, const char *ptseg) +{ + char *psep, *rest; + + if (!ptfile || !ptoffset || !ptarg) + return internal_error(ptseg); + + /* Search from the end as the filename may also contain ':'. */ + psep = strrchr(ptarg, ':'); + if (!psep) + return no_offset(ptseg, ptarg); + + if (psep == ptarg) + return no_filename(ptseg, ptarg); + + *ptfile = ptarg; + *psep++ = 0; + + errno = 0; + *ptoffset = (uint64_t) strtoull(psep, &rest, 0); + if (errno || *rest) + return bad_offset(ptseg, psep); + + return 0; +} + +extern int main(int argc, char *argv) +{ + const char *ptseg, *ptfile; + char *arg, *ptarg; + uint64_t ptoffset; + int errcode; + + (void) argc; + if (!argv) + return usage(""); + + ptseg = *argv++; + if (!ptseg) + return usage(""); + + arg = *argv++; + if (!arg) + return no_ptfile(ptseg); + + if (strcmp(arg, "--help") == 0 || strcmp(arg, "-h") == 0) + return help(ptseg); + + if (strcmp(arg, "--version") == 0) + return version(ptseg); + + if (arg0 == '-') + return bad_option(ptseg, arg); + + ptarg = arg; + arg = *argv++; + if (arg) + return trailing_junk(ptseg, arg); + + ptfile = NULL; + ptoffset = 0ull; + errcode = ptseg_split_ptarg(&ptfile, &ptoffset, ptarg, ptseg); + if (errcode) + return -errcode; + + return ptseg_print_seg(ptfile, ptoffset, ptseg); +}
View file
_service:tar_scm:v2.0.5.tar.gz/pttc/CMakeLists.txt -> _service:tar_scm:v2.1.tar.gz/pttc/CMakeLists.txt
Changed
@@ -1,4 +1,5 @@ -# Copyright (c) 2013-2022, Intel Corporation +# Copyright (c) 2013-2023, Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: @@ -43,7 +44,6 @@ set(PTTC_FILES ${PTTC_FILES} src/posix/util.c - ../libipt/src/posix/pt_cpuid.c ) endif (CMAKE_HOST_UNIX) @@ -51,7 +51,6 @@ set(PTTC_FILES ${PTTC_FILES} src/windows/util.c - ../libipt/src/windows/pt_cpuid.c ) endif (CMAKE_HOST_WIN32)
View file
_service:tar_scm:v2.0.5.tar.gz/pttc/include/errcode.h -> _service:tar_scm:v2.1.tar.gz/pttc/include/errcode.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -79,6 +80,8 @@ err_no_mem, + err_name_too_long, + /* Used for all invalid function arguments. */ err_internal,
View file
_service:tar_scm:v2.0.5.tar.gz/pttc/include/file.h -> _service:tar_scm:v2.1.tar.gz/pttc/include/file.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -44,13 +45,16 @@ char **line; }; -/* Allocates new text. +/* Turns @s into a new text; @n is the length of @s excluding termination. + * + * On success, the returned text owns @s and @s will be freed by text_free(); + * otherwise @s will be freed by text_alloc() and NULL will be returned. * * Note, if s is NULL or the empty string the text has zero lines. * * Returns a non-NULL text object on success; NULL otherwise. */ -extern struct text *text_alloc(const char *s); +extern struct text *text_alloc(char *s, size_t n); /* Deallocates @t. * If @t is the NULL pointer, nothing happens.
View file
_service:tar_scm:v2.0.5.tar.gz/pttc/include/parse.h -> _service:tar_scm:v2.1.tar.gz/pttc/include/parse.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -96,6 +97,11 @@ #endif /* defined(FEATURE_SIDEBAND) */ +enum { + /* The maximal size of a label in characters. */ + l_max = 256 +}; + /* Represents the parser. */ struct parser { /* File pointer to the trace output file. */
View file
_service:tar_scm:v2.0.5.tar.gz/pttc/include/pttc.h -> _service:tar_scm:v2.1.tar.gz/pttc/include/pttc.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/pttc/include/util.h -> _service:tar_scm:v2.1.tar.gz/pttc/include/util.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,15 +31,17 @@ #define UTIL_H #include <stdint.h> +#include <stddef.h> -/* Duplicates @s and returns a pointer to it. +/* Duplicates @s into *@d provided the length of @s does not exceed @n bytes. * - * The returned pointer must be freed by the caller. + * The provided pointer must be freed by the caller. * - * Returns the pointer to the duplicate on success; otherwise NULL is - * returned. + * Returns zero on success; a negative enum errcode otherwise. + * Returns -err_name_too_long if the length of @s exceeds @n bytes. + * Returns -err_no_mem when running out of memory. */ -extern char *duplicate_str(const char *s); +extern int duplicate_name(char **d, const char *s, size_t n); /* Converts the string @str into an usigned x-bit value @val using base @base. *
View file
_service:tar_scm:v2.0.5.tar.gz/pttc/include/yasm.h -> _service:tar_scm:v2.1.tar.gz/pttc/include/yasm.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -47,10 +48,11 @@ /* Modifies @s, so it can be used as a label, if @s actually looks like * a label. * - * Returns true if @s looks like a label; false otherwise. - * Returns -err_internal if @l or @name is the NULL pointer. + * @end points one byte beyond the end of the string buffer containing @s. + * + * Returns non-zero if @s looks like a label; zero otherwise. */ -extern int make_label(char *s); +extern int make_label(char *s, const char *end); /* Represents the state of the pt directive parser. The parser uses the * canonical yasm lst file syntax to follow all asm source files that
View file
_service:tar_scm:v2.0.5.tar.gz/pttc/src/errcode.c -> _service:tar_scm:v2.1.tar.gz/pttc/src/errcode.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -77,6 +78,8 @@ "out of memory", + "name too long", + "internal error", "processing stopped",
View file
_service:tar_scm:v2.0.5.tar.gz/pttc/src/file.c -> _service:tar_scm:v2.1.tar.gz/pttc/src/file.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -35,32 +36,35 @@ #include <string.h> #include <errno.h> -struct text *text_alloc(const char *s) +struct text *text_alloc(char *s, size_t n) { - size_t n, i; + size_t i; char **line; struct text *t; t = calloc(1, sizeof(struct text)); - if (!t) + if (!t) { + free(s); return NULL; + } /* If s is NULL or empty, there is nothing to do. */ - if (!s || *s == '\0') + if (!s || *s == '\0') { + free(s); return t; + } /* beginning of s is the first line. */ t->n = 1; t->line = calloc(1, sizeof(*t->line)); - if (!t->line) + if (!t->line) { + free(s); goto error; + } - t->line0 = duplicate_str(s); - if (!t->line0) - goto error; + t->line0 = s; /* iterate through all chars and make \r?\n to \0. */ - n = strlen(t->line0); for (i = 0; i < n; i++) { if (t->line0i == '\r') { if (i+1 >= n) { @@ -69,16 +73,22 @@ break; } /* terminate the line string if it's a line end. */ - if (t->line0i+1 == '\n') + if (t->line0i+1 == '\n') { t->line0i = '\0'; + continue; + } + } - } else if (t->line0i == '\n') { + if (t->line0i == '\n') { /* set newline character always to \0. */ t->line0i = '\0'; if (i+1 >= n) { /* the file ends with \n. */ break; } + } + + if (t->line0i == '\0') { /* increase line pointer buffer. */ line = realloc(t->line, (t->n+1) * sizeof(*t->line)); if (!line) @@ -190,11 +200,9 @@ goto error; } - fl->next->filename = duplicate_str(filename); - if (!fl->next->filename) { - errcode = -err_no_mem; + errcode = duplicate_name(&fl->next->filename, filename, FILENAME_MAX); + if (errcode < 0) goto error; - } errno = 0; f = fopen(filename, "rb"); @@ -245,13 +253,12 @@ goto error; } - *t = text_alloc(s); + *t = text_alloc(s, fsize); if (!*t) { errcode = -err_no_mem; goto error; } - free(s); fl->next->text = *t; return 0; @@ -262,7 +269,6 @@ /* filename is closed after reading before handling error. */ fl_free(fl->next); fl->next = NULL; - free(s); text_free(*t); *t = NULL; return errcode;
View file
_service:tar_scm:v2.0.5.tar.gz/pttc/src/main.c -> _service:tar_scm:v2.1.tar.gz/pttc/src/main.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -42,9 +43,8 @@ "options:\n" " --help|-h this text.\n" " --version display version information and exit.\n" - " --cpu none|auto|f/m/s set cpu to the given value and encode according to:\n" + " --cpu none|f/m/s set cpu to the given value and encode according to:\n" " none spec (default)\n" - " auto current cpu\n" " f/m/s family/model/stepping\n" " <pttfile> the annotated yasm input file.\n", prog); @@ -75,18 +75,6 @@ if (strcmp(arg, "--cpu") == 0) { arg = argvi++; - if (strcmp(arg, "auto") == 0) { - errcode = pt_cpu_read(&options.cpu); - if (errcode < 0) { - fprintf(stderr, - "%s: error reading cpu: %s.\n", - prog, - pt_errstr(pt_errcode(errcode))); - return 1; - } - continue; - } - if (strcmp(arg, "none") == 0) { memset(&options.cpu, 0, sizeof(options.cpu)); continue;
View file
_service:tar_scm:v2.0.5.tar.gz/pttc/src/parse.c -> _service:tar_scm:v2.1.tar.gz/pttc/src/parse.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -36,17 +37,18 @@ #include <stdlib.h> #include <string.h> #include <errno.h> +#include <limits.h> #if defined(_MSC_VER) && (_MSC_VER < 1900) # define snprintf _snprintf_c #endif -static const char *pt_suffix = ".pt"; -static const char *exp_suffix = ".exp"; +static const char pt_suffix = ".pt"; +static const char exp_suffix = ".exp"; #if defined(FEATURE_SIDEBAND) -static const char *sb_suffix = ".sb"; +static const char sb_suffix = ".sb"; #endif enum { @@ -58,14 +60,16 @@ static void sb_rename_file(struct sb_file *sb) { char filenameFILENAME_MAX; + int len; /* We encode the configuration in the sideband filename. */ switch (sb->format) { case sbf_raw: - strncpy(filename, sb->name, sizeof(filename) - 1); - - /* Make sure @filename is terminated. */ - filenamesizeof(filename) - 1 = 0; + len = snprintf(filename, sizeof(filename), "%s", sb->name); + if ((len < 0) || (sizeof(filename) <= (size_t) len)) { + fprintf(stderr, "error renaming %s.\n", sb->name); + return; + } break; #if defined(FEATURE_PEVENT) @@ -89,7 +93,7 @@ ext_len = (size_t) printed; - suffix_len = strnlen(sb_suffix, sizeof(filename)); + suffix_len = sizeof(sb_suffix) - 1; base_len = strnlen(sb->name, sizeof(filename)); if (base_len < suffix_len) { fprintf(stderr, "error renaming %s.\n", sb->name); @@ -105,12 +109,15 @@ return; } - strncpy(filename, sb->name, base_len); + if (INT_MAX < base_len) { + fprintf(stderr, "error renaming %s.\n", sb->name); + return; + } - printed = snprintf(filename + base_len, - sizeof(filename) - base_len, "%s%s", - extension, sb_suffix); - if (printed < 0) { + printed = snprintf(filename, sizeof(filename), "%.*s%s%s", + (int) base_len, sb->name, extension, + sb_suffix); + if ((printed < 0) || (sizeof(filename) <= (size_t) printed)) { fprintf(stderr, "error renaming %s.\n", sb->name); return; } @@ -126,7 +133,7 @@ } /* Print the name of the sideband file for test.bash. */ - printf("%s\n", filename); + printf("%s ", filename); } #endif /* defined(FEATURE_SIDEBAND) */ @@ -175,8 +182,9 @@ */ static struct parser *p_alloc(const char *pttfile, const struct pt_config *conf) { - size_t n; + size_t n, size; struct parser *p; + int len; if (!conf) return NULL; @@ -192,14 +200,19 @@ if (!p->y) goto error; - n = strlen(p->y->fileroot) + 1; + n = strnlen(p->y->fileroot, FILENAME_MAX - sizeof(pt_suffix)); + if ((FILENAME_MAX - sizeof(pt_suffix)) <= n) + goto error; + + size = n + sizeof(pt_suffix); - p->ptfilename = malloc(n+strlen(pt_suffix)); + p->ptfilename = malloc(size); if (!p->ptfilename) goto error; - strcpy(p->ptfilename, p->y->fileroot); - strcat(p->ptfilename, pt_suffix); + len = snprintf(p->ptfilename, size, "%s%s", p->y->fileroot, pt_suffix); + if ((len < 0) || ((size_t) len != (size - 1))) + goto error; p->pd = pd_alloc(pd_len); if (!p->pd) @@ -224,68 +237,50 @@ } /* Generates an .exp filename following the scheme: - * <fileroot>-<extra>.exp + * <fileroot>-<extra>-cpu_<f>_<m>_<s>.exp */ static char *expfilename(struct parser *p, const char *extra) { - char *filename; - /* reserve enough space to hold the string - * "-cpu_fffff_mmm_sss" + 1 for the trailing null character. - */ - char cpu_suffix19; - size_t n; - - if (!extra) - extra = ""; - *cpu_suffix = '\0'; - - /* determine length of resulting filename, which looks like: - * <fileroot>-<extra>-cpu_<f>_<m>_<s>.exp - */ - n = strlen(p->y->fileroot); + char filenameFILENAME_MAX, cpuext64, *pfname; + int len; - if (*extra != '\0') - /* the extra string is prepended with a -. */ - n += 1 + strlen(extra); + memset(filename, 0, sizeof(filename)); + memset(cpuext, 0, sizeof(cpuext)); if (p->conf->cpu.vendor != pcv_unknown) { struct pt_cpu cpu; - int len; cpu = p->conf->cpu; if (cpu.stepping) - len = sprintf(cpu_suffix, - "-cpu_%" PRIu16 "_%" PRIu8 "_%" PRIu8 "", - cpu.family, cpu.model, cpu.stepping); + len = snprintf(cpuext, sizeof(cpuext), + "-cpu_%" PRIu16 "_%" PRIu8 "_%" PRIu8, + cpu.family, cpu.model, cpu.stepping); else - len = sprintf(cpu_suffix, - "-cpu_%" PRIu16 "_%" PRIu8 "", cpu.family, - cpu.model); + len = snprintf(cpuext, sizeof(cpuext), + "-cpu_%" PRIu16 "_%" PRIu8, cpu.family, + cpu.model); - if (len < 0) + if ((len < 0) || (sizeof(cpuext) <= (size_t) len)) return NULL; - - n += (size_t) len; } - n += strlen(exp_suffix); + if (extra && *extra) + len = snprintf(filename, sizeof(filename), "%s-%s%s%s", + p->y->fileroot, extra, cpuext, exp_suffix); + else + len = snprintf(filename, sizeof(filename), "%s-%s%s", + p->y->fileroot, cpuext, exp_suffix); - /* trailing null character. */ - n += 1; + if ((len < 0) || (sizeof(filename) <= (size_t) len)) + return NULL; - filename = malloc(n); - if (!filename) + pfname = malloc((size_t) len + 1); + if (!pfname) return NULL; - strcpy(filename, p->y->fileroot); - if (*extra != '\0') { - strcat(filename, "-"); - strcat(filename, extra); - } - strcat(filename, cpu_suffix); - strcat(filename, exp_suffix); + pfnamelen = 0; - return filename; + return memcpy(pfname, filename, (size_t) len); } /* Returns true if @c is part of a label; false otherwise. */ @@ -312,11 +307,11 @@ static int p_gen_expfile(struct parser *p) { int errcode; - enum { slen = 1024 }; - char sslen; + char s1024; struct pt_directive *pd; char *filename; FILE *f; + size_t slen; if (bug_on(!p)) return -err_internal; @@ -342,19 +337,26 @@ for (;;) { int i; - char *line, *comment; + char *line, *comment, *end; - errcode = yasm_next_line(p->y, s, slen); + errcode = yasm_next_line(p->y, s, sizeof(s)); if (errcode < 0) break; + slen = strnlen(s, sizeof(s)); + if (sizeof(s) <= slen) { + errcode = -err_internal; + break; + } + end = &sslen; + errcode = yasm_pd_parse(p->y, pd); if (errcode < 0 && errcode != -err_no_directive) break; if (errcode == 0 && strcmp(pd->name, ".exp") == 0) { fclose(f); - printf("%s\n", filename); + printf("%s ", filename); free(filename); filename = expfilename(p, pd->payload); if (!filename) @@ -374,12 +376,13 @@ line += 1; comment = strchr(line, '#'); - if (comment) + if (comment) { + end = comment; *comment = '\0'; - + } /* remove trailing spaces. */ - for (i = (int) strlen(line)-1; i >= 0 && isspace(linei); i--) - linei = '\0'; + for (end -= 1; line <= end && isspace(*end); --end) + *end = '\0'; for (;;) { char *tmp, label256; @@ -442,7 +445,7 @@ for (i = 0; islabelchar(linei); i++) ; - if (i > 255) { + if (l_max <= i) { errcode = -err_label_name; goto error; } @@ -546,11 +549,10 @@ fclose(f); if (errcode < 0 && errcode != -err_out_of_range) { - fprintf(stderr, "fatal: %s could not be created:\n", filename); + fprintf(stderr, "fatal: error generating %s:\n", filename); yasm_print_err(p->y, "", errcode); - remove(filename); } else - printf("%s\n", filename); + printf("%s ", filename); free(filename); /* If there are no lines left, we are done. */ @@ -597,6 +599,143 @@ return -err_pt_lib; } +/* Parse any amount of whitespace from @pinput, including none. + * + * We want to stay within one source line so we only parse spaces and + * horizontal tabs. + * + * Returns zero on success and updates @input. + * Returns a negative integer on error. + */ +static int parse_whitespace(const char **pinput) +{ + const char *input; + + if (!pinput) + return -err_internal; + + input = *pinput; + if (!input) + return -err_internal; + + while ((*input == ' ') || (*input == '\t')) + input += 1; + + *pinput = input; + return 0; +} + +/* Parse @size bytes of a literal @token in @input. + * + * Returns zero on success and updates @input. + * Returns a positive integer on failure. + * Returns a negative integer on error. + */ +static int parse_token_aux(const char **pinput, const char *token, size_t size) +{ + const char *input; + int status; + + if (!pinput) + return -err_internal; + + input = *pinput; + if (!input) + return -err_internal; + + if (!token || !size) + return -err_internal; + + status = parse_whitespace(&input); + if (status < 0) + return status; + + if (strncmp(input, token, size) != 0) + return 1; + + input += size; + *pinput = input; + return 0; +} + +/* Parse a string literal @token in @input. */ +#define parse_token(input, token) \ + parse_token_aux(input, token, sizeof(token) - 1) + +/* Parse an @size-bit base-@base unsigned integer in @input. + * + * If an integer number can be parsed from @input, diagnoses exceeding the + * expected range with an error code return. + * + * Returns zero on success and updates @input. + * Returns a positive integer if @input does not start with an integer. + * Returns a negative integer on error. + */ +static int parse_uint(const char **pinput, unsigned long long *puint, + uint8_t size, int base) +{ + unsigned long long uint; + const char *input; + char *end; + + if (!pinput) + return -err_internal; + + input = *pinput; + if (!input) + return -err_internal; + + if (!puint || !size) + return -err_internal; + + if (size > 64) + return -err_internal; + + errno = 0; + uint = strtoull(input, &end, base); + if (input == end) + return 1; + + if (errno == EINVAL) + return -err_internal; + + if (errno == ERANGE) + return -err_parse_int_too_big; + + if ((size < 64) && ((uint >> size) != 0)) + return -err_parse_int_too_big; + + *puint = uint; + *pinput = end; + return 0; +} + +static int parse_uint_8(const char **pinput, uint8_t *uint) +{ + unsigned long long tmp; + int status; + + status = parse_uint(pinput, &tmp, 8, 0); + if (status != 0) + return status; + + *uint = (uint8_t) tmp; + return 0; +} + +static int parse_uint_64(const char **pinput, uint64_t *uint) +{ + unsigned long long tmp; + int status; + + status = parse_uint(pinput, &tmp, 64, 0); + if (status != 0) + return status; + + *uint = (uint64_t) tmp; + return 0; +} + static int parse_mwait(uint32_t *hints, uint32_t *ext, char *payload) { int errcode; @@ -671,6 +810,273 @@ return 0; } +/* Parse a mode.exec execution mode in @input into @packet. + * + * Returns zero on success and updates @input. + * Returns a positive integer on failure. + * Returns a negative integer on error. + */ +static int parse_exec_mode(const char **input, + struct pt_packet_mode_exec *packet) +{ + int status; + + if (!packet) + return -err_internal; + + status = parse_token(input, "64bit"); + if (status <= 0) { + if (status < 0) + return status; + + packet->csl = 1; + packet->csd = 0; + + return status; + } + + status = parse_token(input, "32bit"); + if (status <= 0) { + if (status < 0) + return status; + + packet->csl = 0; + packet->csd = 1; + + return status; + } + + status = parse_token(input, "16bit"); + if (status <= 0) { + if (status < 0) + return status; + + packet->csl = 0; + packet->csd = 0; + + return status; + } + + return 1; +} + +/* Parse mode.exec arguments in @input into @packet. + * + * Returns zero on success and updates @input. + * Returns a positive integer on failure. + * Returns a negative integer on error. + */ +static int parse_mode_exec(const char **input, const struct parser *p, + struct pt_packet_mode_exec *packet) +{ + int status; + + if (!p || !packet) + return -err_internal; + + status = parse_exec_mode(input, packet); + if (status != 0) { + if (status < 0) + return status; + + status = yasm_print_err(p->y, "mode.exec: bad argument, " + "expected \"16bit\", \"64bit\" or " + "\"32bit\"", -err_parse); + if (status < 0) + return status; + + return 1; + } + + status = parse_token(input, ","); + if (status != 0) { + if (status < 0) + return status; + + packet->iflag = 0; + return 0; + } + + status = parse_token(input, "if"); + if (status != 0) { + if (status < 0) + return status; + + status = yasm_print_err(p->y, "mode.exec: bad argument, " + "expected \"if\"", -err_parse); + if (status < 0) + return status; + + return 1; + } + + packet->iflag = 1; + return 0; +} + +/* Parse cfe arguments in @input into @packet. + * + * Returns zero on success and updates @input. + * Returns a positive integer on failure. + * Returns a negative integer on error. + */ +static int parse_cfe(const char **input, const struct parser *p, + struct pt_packet_cfe *packet) +{ + uint8_t type; + int status; + + if (!p || !packet) + return -err_internal; + + status = parse_uint_8(input, &type); + if (status != 0) { + if (status < 0) + return status; + + status = yasm_print_err(p->y, "cfe: bad argument, expected " + "8-bit unsigned integer 'type'", + -err_parse); + if (status < 0) + return status; + + return 1; + } + + packet->type = (enum pt_cfe_type) type; + + status = parse_token(input, ":"); + if (status != 0) { + if (status < 0) + return status; + + switch (packet->type) { + case pt_cfe_intr: + case pt_cfe_sipi: + case pt_cfe_vmexit_intr: + case pt_cfe_uintr: + status = yasm_print_err(p->y, "cfe: type needs " + "'vector' argument", + -err_parse); + if (status < 0) + return status; + + return 1; + + case pt_cfe_iret: + case pt_cfe_smi: + case pt_cfe_rsm: + case pt_cfe_init: + case pt_cfe_vmentry: + case pt_cfe_vmexit: + case pt_cfe_shutdown: + case pt_cfe_uiret: + packet->vector = 0; + break; + } + } else { + status = parse_uint_8(input, &packet->vector); + if (status != 0) { + if (status < 0) + return status; + + status = yasm_print_err(p->y, "cfe: bad argument, " + "expected 8-bit unsigned " + "integer 'vector'", -err_parse); + if (status < 0) + return status; + + return 1; + } + } + + status = parse_token(input, ","); + if (status != 0) { + if (status < 0) + return status; + + packet->ip = 0; + return 0; + } + + status = parse_token(input, "ip"); + if (status != 0) { + if (status < 0) + return status; + + status = yasm_print_err(p->y, "cfe: bad argument, expected" + "'ip' keyword", -err_parse); + if (status < 0) + return status; + + return 1; + } + + packet->ip = 1; + return 0; +} + +/* Parse evd arguments in @input into @packet. + * + * Returns zero on success and updates @input. + * Returns a positive integer on failure. + * Returns a negative integer on error. + */ +static int parse_evd(const char **input, const struct parser *p, + struct pt_packet_evd *packet) +{ + uint8_t type; + int status; + + if (!p || !packet) + return -err_internal; + + status = parse_uint_8(input, &type); + if (status != 0) { + if (status < 0) + return status; + + status = yasm_print_err(p->y, "evd: bad argument, expected " + "8-bit unsigned integer 'type'", + -err_parse); + if (status < 0) + return status; + + return 1; + } + + packet->type = (enum pt_evd_type) type; + + status = parse_token(input, ":"); + if (status != 0) { + if (status < 0) + return status; + + status = yasm_print_err(p->y, "evd: bad argument, expected " + "':' separator", -err_parse); + if (status < 0) + return status; + + return 1; + } + + status = parse_uint_64(input, &packet->payload); + if (status != 0) { + if (status < 0) + return status; + + status = yasm_print_err(p->y, "evd: bad argument, expected " + "64-bit unsigned integer 'payload'", + -err_parse); + if (status < 0) + return status; + + return 1; + } + + return 0; +} + static int pt_raw(struct parser *p, struct pt_encoder *e, const void *buffer, size_t size) { @@ -851,21 +1257,22 @@ } packet.type = ppt_fup; } else if (strcmp(directive, "mode.exec") == 0) { - if (strcmp(payload, "16bit") == 0) { - packet.payload.mode.bits.exec.csl = 0; - packet.payload.mode.bits.exec.csd = 0; - } else if (strcmp(payload, "64bit") == 0) { - packet.payload.mode.bits.exec.csl = 1; - packet.payload.mode.bits.exec.csd = 0; - } else if (strcmp(payload, "32bit") == 0) { - packet.payload.mode.bits.exec.csl = 0; - packet.payload.mode.bits.exec.csd = 1; - } else { - errcode = yasm_print_err(p->y, - "mode.exec: argument must be one of \"16bit\", \"64bit\" or \"32bit\"", - -err_parse); + const char *cpl; + + cpl = (const char *) payload; + errcode = parse_mode_exec(&cpl, p, + &packet.payload.mode.bits.exec); + if (errcode != 0) { + if (errcode < 0) + yasm_print_err(p->y, + "mode.exec: parsing failed", + errcode); + else + errcode = -err_parse; + return errcode; } + packet.payload.mode.leaf = pt_mol_exec; packet.type = ppt_mode; } else if (strcmp(directive, "mode.tsx") == 0) { @@ -1088,6 +1495,38 @@ packet.payload.ptw.ip = 1; } + } else if (strcmp(directive, "cfe") == 0) { + const char *cpl; + + cpl = (const char *) payload; + errcode = parse_cfe(&cpl, p, &packet.payload.cfe); + if (errcode != 0) { + if (errcode < 0) + yasm_print_err(p->y, "cfe: parsing failed", + errcode); + else + errcode = -err_parse; + + return errcode; + } + + packet.type = ppt_cfe; + } else if (strcmp(directive, "evd") == 0) { + const char *cpl; + + cpl = (const char *) payload; + errcode = parse_evd(&cpl, p, &packet.payload.evd); + if (errcode != 0) { + if (errcode < 0) + yasm_print_err(p->y, "evd: parsing failed", + errcode); + else + errcode = -err_parse; + + return errcode; + } + + packet.type = ppt_evd; } else if (strcmp(directive, "raw-8") == 0) { uint8_t value; @@ -1158,6 +1597,7 @@ const char *root; char nameFILENAME_MAX; FILE *file; + int errcode; if (bug_on(!p) || bug_on(!p->y) || bug_on(!prio)) return -err_internal; @@ -1196,12 +1636,13 @@ memset(&sbfiles->sbfile, 0, sizeof(sbfiles->sbfile)); - sbfiles->sbfile.name = duplicate_str(name); - if (!sbfiles->sbfile.name) { - yasm_print_err(p->y, "open", -err_no_mem); + errcode = duplicate_name(&sbfiles->sbfile.name, name, + FILENAME_MAX); + if (errcode < 0) { + yasm_print_err(p->y, "open", errcode); fclose(file); free(sbfiles); - return -err_no_mem; + return errcode; } sbfiles->sbfile.file = file; @@ -1745,7 +2186,8 @@ uint8_t bufferFILENAME_MAX; } record; struct pev_event event; - int errcode; + size_t limit; + int errcode, len; if (bug_on(!p) || bug_on(!p->y)) return -err_internal; @@ -1765,7 +2207,12 @@ return errcode; } - strcpy(record.comm.comm, comm); + limit = sizeof(record.buffer) - sizeof(record.comm); + len = snprintf(record.comm.comm, limit, "%s", comm); + if (len < 0) + return -err_parse; + if (limit <= (size_t) len) + return -err_name_too_long; event.type = PERF_RECORD_COMM; event.misc = misc; @@ -2469,8 +2916,9 @@ */ static int p_process(struct parser *p, struct pt_encoder *e) { - char *directive, *tmp; + char *directive, *tmp, *end; struct pt_directive *pd; + size_t nlen; if (bug_on(!p)) return -err_internal; @@ -2481,6 +2929,13 @@ directive = pd->name; + nlen = strnlen(directive, pd_len); + if (pd_len <= nlen) + return -err_internal; + + /* Plus 1 for termination. */ + end = directive + nlen + 1; + /* We must have a directive. */ if (!directive || (strcmp(directive, "") == 0)) return yasm_print_err(p->y, "invalid syntax", @@ -2507,7 +2962,7 @@ char *pt_label_name; uint64_t x; int errcode, bytes_written; - size_t len; + size_t limit, len; pt_label_name = directive; directive = tmp+1; @@ -2572,8 +3027,16 @@ return errcode; /* Update the directive name in the parser. */ - len = strlen(directive) + 1; + if (end <= directive) + return -err_internal; + + limit = (size_t) ((uintptr_t) end - (uintptr_t) directive); + len = strnlen(directive, limit); + if (limit <= len) + return -err_internal; + memmove(pd->name, directive, len); + pd->namelen = '\0'; } switch (pd->kind) {
View file
_service:tar_scm:v2.0.5.tar.gz/pttc/src/posix/util.c -> _service:tar_scm:v2.1.tar.gz/pttc/src/posix/util.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/pttc/src/pttc.c -> _service:tar_scm:v2.1.tar.gz/pttc/src/pttc.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/pttc/src/util.c -> _service:tar_scm:v2.1.tar.gz/pttc/src/util.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -28,6 +29,7 @@ #include "errcode.h" #include "util.h" +#include "parse.h" #include <ctype.h> #include <errno.h> @@ -35,17 +37,26 @@ #include <stdlib.h> #include <string.h> -char *duplicate_str(const char *s) +int duplicate_name(char **d, const char *s, size_t n) { char *dup; + size_t len; - if (!s) - return NULL; + if (!d || !s) + return -err_internal; + + len = strnlen(s, n); + if (n <= len) + return -err_name_too_long; - dup = malloc(strlen(s)+1); + dup = malloc(len + 1); if (!dup) - return NULL; - return strcpy(dup, s); + return -err_no_mem; + + *d = memcpy(dup, s, len); + duplen = 0; + + return 0; } int str_to_uint64(const char *str, uint64_t *val, int base) @@ -155,6 +166,7 @@ int l_append(struct label *l, const char *name, uint64_t addr) { int errcode; + size_t nlen; if (bug_on(!l)) return -err_internal; @@ -162,6 +174,10 @@ if (bug_on(!name)) return -err_internal; + nlen = strnlen(name, (size_t) l_max); + if ((size_t) l_max <= nlen) + return -err_label_name; + /* skip to the last label. */ while (l->next) { l = l->next; @@ -177,11 +193,9 @@ return -err_no_mem; /* save the name. */ - l->next->name = duplicate_str(name); - if (!l->next->name) { - errcode = -err_no_mem; + errcode = duplicate_name(&l->next->name, name, nlen+1); + if (errcode < 0) goto error; - } /* save the address. */ l->next->addr = addr;
View file
_service:tar_scm:v2.0.5.tar.gz/pttc/src/windows/util.c -> _service:tar_scm:v2.1.tar.gz/pttc/src/windows/util.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -41,7 +42,7 @@ int errcode; int i; - size_t size; + size_t size, len; char *args; STARTUPINFO si; @@ -69,11 +70,18 @@ * all arguments, plus two quotation marks (to make it quoted strings * and allow for spaces in file/path names), plus a space after each * arguments as delimiter (after the last arguments it's a terminating - * zero-byte instead of the space). * + * zero-byte instead of the space). */ size = 0; - for (i = 0; argvi; ++i) - size += strlen(argvi) + 3; + for (i = 0; argvi; ++i) { + len = strnlen(argvi, FILENAME_MAX); + if (FILENAME_MAX <= len) { + errcode = -err_internal; + goto out; + } + + size += len + 3; + } /* allocate command line string */ args = calloc(size, 1); @@ -85,9 +93,15 @@ */ size = 0; for (i = 0; argvi; ++i) { + len = strnlen(argvi, FILENAME_MAX); + if (FILENAME_MAX <= len) { + errcode = -err_internal; + goto out; + } + argssize++ = '"'; - strcpy(args + size, argvi); - size += strlen(argvi); + memcpy(args + size, argvi, len); + size += len; argssize++ = '"'; argssize++ = ' '; }
View file
_service:tar_scm:v2.0.5.tar.gz/pttc/src/yasm.c -> _service:tar_scm:v2.1.tar.gz/pttc/src/yasm.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -153,13 +154,15 @@ return lookup_section_label(l, name, "vstart", vstart); } +static const char key_section = "section"; +static const char key_org = "org"; + int parse_yasm_labels(struct label *l, const struct text *t) { int errcode, no_org_directive; size_t i; uint64_t base_addr; - enum { linelen = 1024 }; - char linelinelen; + char line1024, *end; struct label *length; if (bug_on(!t)) @@ -168,6 +171,7 @@ base_addr = 0; no_org_directive = 1; length = NULL; + end = line + sizeof(line); /* determine base address from org directive and insert special * section labels. @@ -175,24 +179,24 @@ for (i = 0; i < t->n; i++) { char *tmp; - errcode = text_line(t, line, linelen, i); + errcode = text_line(t, line, sizeof(line), i); if (errcode < 0) return errcode; - tmp = strstr(line, "section"); + tmp = strstr(line, key_section); if (tmp) { - tmp += strlen("section"); + tmp += sizeof(key_section) - 1; errcode = parse_section(tmp, l, &length); if (errcode < 0) return errcode; continue; } - tmp = strstr(line, "org"); + tmp = strstr(line, key_org); if (tmp) { char *org; - org = tmp + strlen("org"); + org = tmp + sizeof(key_org) - 1; tmp = strstr(org, ""); if (!tmp) return -err_no_org_directive; @@ -258,17 +262,17 @@ return -err_no_org_directive; for (i = 0; i < t->n; i++) { - char *tmp, *name; + char *tmp; uint64_t addr; - errcode = text_line(t, line, linelen, i); + errcode = text_line(t, line, sizeof(line), i); if (errcode < 0) goto error; /* Change the base on section switches. */ - tmp = strstr(line, "section"); + tmp = strstr(line, key_section); if (tmp) { - tmp += strlen("section"); + tmp += sizeof(key_section) - 1; errcode = lookup_section_vstart(l, tmp, &base_addr); if (errcode < 0) return errcode; @@ -297,7 +301,7 @@ if (!tmp) continue; - if (!make_label(tmp)) { + if (!make_label(tmp, end)) { uint64_t laddr; /* get address in case we find a label later. */ @@ -311,7 +315,7 @@ /* this might be a label now. */ tmp = strtok(NULL, " "); - if (!make_label(tmp)) + if (!make_label(tmp, end)) continue; laddr = addr + base_addr; @@ -325,11 +329,6 @@ goto error; continue; } - name = duplicate_str(tmp); - if (!name) { - errcode = -err_no_mem; - goto error; - } /* there was a label so now an address needs to * be found. @@ -338,7 +337,7 @@ for (i += 1; i < t->n; i++) { int errcode_text; - errcode_text = text_line(t, line, linelen, i); + errcode_text = text_line(t, line, sizeof(line), i); if (errcode_text < 0) { errcode = errcode_text; break; @@ -353,13 +352,13 @@ break; } - errcode = l_append(l, name, laddr); + errcode = l_append(l, tmp, laddr); break; } } if (errcode == -err_label_addr) - fprintf(stderr, "label '%s' has no address\n", name); - free(name); + fprintf(stderr, "label '%s' has no address\n", tmp); + if (errcode < 0) goto error; } @@ -374,14 +373,21 @@ return errcode; } -int make_label(char *s) +int make_label(char *s, const char *end) { - size_t n; + size_t n, size; if (bug_on(!s)) - return -err_internal; + return 0; + + if (bug_on(end <= s)) + return 0; + + size = (size_t) ((uintptr_t) end - (uintptr_t) s); + n = strnlen(s, size); + if (size <= n) + return 0; - n = strlen(s); if (n == 0 || sn-1 != ':') return 0; @@ -430,6 +436,8 @@ */ static int st_set_file(struct state *st, const char *filename, int inc, int n) { + int errcode; + if (bug_on(!st)) return -err_internal; @@ -437,9 +445,10 @@ return -err_internal; free(st->filename); - st->filename = duplicate_str(filename); - if (!st->filename) - return -err_no_mem; + errcode = duplicate_name(&st->filename, filename, FILENAME_MAX); + if (errcode < 0) + return errcode; + st->inc = inc; st->n = n; return 0; @@ -451,10 +460,14 @@ */ static int st_update(struct state *st, const char *s) { + int errcode; + free(st->line); - st->line = duplicate_str(s); - if (!st->line) - return -err_no_mem; + st->line = NULL; + + errcode = duplicate_name(&st->line, s, FILENAME_MAX); + if (errcode < 0) + return errcode; st->n += st->inc; return 0; @@ -520,10 +533,10 @@ } /* Magic annotation markers. */ -static const char *pt_marker = "@pt "; +static const char pt_marker = "@pt "; #if defined(FEATURE_SIDEBAND) -static const char *sb_marker = "@sb "; +static const char sb_marker = "@sb "; #endif int pd_parse(struct pt_directive *pd, struct state *st) @@ -540,9 +553,9 @@ return -err_internal; - line = duplicate_str(st->line); - if (!line) - return -err_no_mem; + errcode = duplicate_name(&line, st->line, FILENAME_MAX); + if (errcode < 0) + return errcode; /* make line lower case. */ for (c = line; *c; ++c) @@ -565,14 +578,14 @@ /* search for @pt marker. */ directive = strstr(comment+1, pt_marker); if (directive) { - directive += strlen(pt_marker); + directive += sizeof(pt_marker) - 1; kind = pdk_pt; } else { #if defined(FEATURE_SIDEBAND) /* search for @sb marker. */ directive = strstr(comment+1, sb_marker); if (directive) { - directive += strlen(sb_marker); + directive += sizeof(sb_marker) - 1; kind = pdk_sb; } else #endif @@ -604,7 +617,7 @@ goto cleanup; } - /* make "multiple" strings by artifically terminating them with + /* make "multiple" strings by artificially terminating them with * '\0' then get directive and payload substrings, which will * have leading and trailing whitespace "removed". */ @@ -620,18 +633,16 @@ return errcode; } -static const char *bin_suffix = ".bin"; -static const char *lst_suffix = ".lst"; +static const char bin_suffix = ".bin"; +static const char lst_suffix = ".lst"; static const char path_separator = '/'; -enum { - max_filename_len = 1024 -}; struct yasm *yasm_alloc(const char *pttfile) { char *tmp; - size_t n; + size_t flen, binsize, lstsize; struct yasm *y; + int errcode, len; if (bug_on(!pttfile)) return NULL; @@ -648,12 +659,12 @@ if (!y->st_asm) goto error; - y->fileroot = duplicate_str(pttfile); - if (!y->fileroot) + errcode = duplicate_name(&y->fileroot, pttfile, FILENAME_MAX); + if (errcode < 0) goto error; - y->pttfile = duplicate_str(pttfile); - if (!y->pttfile) + errcode = duplicate_name(&y->pttfile, pttfile, FILENAME_MAX); + if (errcode < 0) goto error; tmp = strrchr(y->fileroot, '.'); @@ -663,23 +674,37 @@ tmp = strrchr(y->fileroot, path_separator); if (tmp) { tmp += 1; - memmove(y->fileroot, tmp, strlen(tmp)+1); + + flen = strnlen(tmp, FILENAME_MAX); + if (FILENAME_MAX <= flen) + goto error; + + memmove(y->fileroot, tmp, flen); + y->filerootflen = '\0'; } - y->binfile = malloc(strlen(y->fileroot)+strlen(bin_suffix)+1); + flen = strnlen(y->fileroot, FILENAME_MAX); + if (FILENAME_MAX <= flen) + goto error; + + binsize = flen + sizeof(bin_suffix); + lstsize = flen + sizeof(lst_suffix); + + y->binfile = malloc(binsize); if (!y->binfile) goto error; - y->lstfile = malloc(strlen(y->fileroot)+strlen(lst_suffix)+1); - if (!y->lstfile) + len = snprintf(y->binfile, binsize, "%s%s", y->fileroot, bin_suffix); + if ((len < 0) || ((size_t) len != (binsize - 1))) goto error; - n = strlen(y->fileroot); + y->lstfile = malloc(lstsize); + if (!y->lstfile) + goto error; - strcpy(y->binfile, y->fileroot); - strcpy(y->binfile+n, bin_suffix); - strcpy(y->lstfile, y->fileroot); - strcpy(y->lstfile+n, lst_suffix); + len = snprintf(y->lstfile, lstsize, "%s%s", y->fileroot, lst_suffix); + if ((len < 0) || ((size_t) len != (lstsize - 1))) + goto error; y->l = l_alloc(); if (!y->l) @@ -762,9 +787,8 @@ static int yasm_advance_next_line(struct yasm *y) { - enum { slen = 1024 }; - char sslen; - char filenamemax_filename_len; + char s1024; + char filenameFILENAME_MAX+1; int errcode; int asm_line, asm_inc; @@ -773,7 +797,7 @@ for (;;) { - errcode = fl_getline(y->fl, s, (size_t) slen, y->lstfile, + errcode = fl_getline(y->fl, s, sizeof(s), y->lstfile, (size_t) y->lst_curr_line); /* always advance in lst file. */ y->lst_curr_line += 1; @@ -785,12 +809,19 @@ * state information to this file, line and increment * and continue. */ - if (sscanf(s, "%*d %%line %d+%d %1023^\r\n", &asm_line, - &asm_inc, filename) == 3) { +#define tostr(val) # val +#define asstr(val) tostr(val) + if (sscanf(s, "%*d %%line %d+%d %" asstr(FILENAME_MAX) + "^\r\n", &asm_line, &asm_inc, filename) == 3) { + /* We must not exceed FILENAME_MAX, so truncate the + * filename, if necessary. + */ + filenameFILENAME_MAX-1 = 0; st_set_file(y->st_asm, filename, asm_line, asm_inc); continue; } - +#undef asstr +#undef tostr /* if line number or increment in the previous line * directive is <= 0, the current lst line has no * corresponding line in the source file. @@ -802,10 +833,13 @@ * correlated to the source file, so we retrieve the * line from it and update the state. */ - errcode = fl_getline(y->fl, s, (size_t) slen, + errcode = fl_getline(y->fl, s, (size_t) sizeof(s), y->st_asm->filename, (size_t) y->st_asm->n - 1u); - st_update(y->st_asm, s); + if (errcode < 0) + break; + + errcode = st_update(y->st_asm, s); break; }
View file
_service:tar_scm:v2.0.5.tar.gz/pttc/test/src/test_all_directives.ptt -> _service:tar_scm:v2.1.tar.gz/pttc/test/src/test_all_directives.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2013-2022, Intel Corporation +; Copyright (c) 2013-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/pttc/test/src/test_exp_labels.ptt -> _service:tar_scm:v2.1.tar.gz/pttc/test/src/test_exp_labels.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2013-2022, Intel Corporation +; Copyright (c) 2013-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/pttc/test/src/test_label_addr.ptt -> _service:tar_scm:v2.1.tar.gz/pttc/test/src/test_label_addr.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2013-2022, Intel Corporation +; Copyright (c) 2013-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/ptunit/CMakeLists.txt -> _service:tar_scm:v2.1.tar.gz/ptunit/CMakeLists.txt
Changed
@@ -1,4 +1,5 @@ -# Copyright (c) 2013-2022, Intel Corporation +# Copyright (c) 2013-2023, Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: @@ -40,4 +41,9 @@ ${PTUNIT_FILES} ) +set_target_properties(ptunit PROPERTIES + C_STANDARD 11 + C_STANDARD_REQUIRED ON +) + add_ptunit_c_test(selftest)
View file
_service:tar_scm:v2.0.5.tar.gz/ptunit/include/ptunit.h -> _service:tar_scm:v2.1.tar.gz/ptunit/include/ptunit.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/ptunit/include/ptunit_mkfile.h -> _service:tar_scm:v2.1.tar.gz/ptunit/include/ptunit_mkfile.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/ptunit/include/ptunit_threads.h -> _service:tar_scm:v2.1.tar.gz/ptunit/include/ptunit_threads.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2015-2022, Intel Corporation + * Copyright (c) 2015-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -32,7 +33,11 @@ #include "ptunit.h" #if defined(FEATURE_THREADS) -# include <threads.h> +# if !defined(__STDC_NO_THREADS__) +# include <threads.h> +# else +# include "pt_threads.h" +# endif #endif /* defined(FEATURE_THREADS) */ @@ -90,7 +95,7 @@ int thrd, errcodeptu_thrd_max; for (thrd = 0; thrd < tfix->nthreads; ++thrd) - errcodethrd = thrd_join(&tfix->threadsthrd, + errcodethrd = thrd_join(tfix->threadsthrd, &tfix->resultthrd); mtx_destroy(&tfix->lock);
View file
_service:tar_scm:v2.0.5.tar.gz/ptunit/src/posix/ptunit_mkfile.c -> _service:tar_scm:v2.1.tar.gz/ptunit/src/posix/ptunit_mkfile.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/ptunit/src/ptunit.c -> _service:tar_scm:v2.1.tar.gz/ptunit/src/ptunit.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -32,6 +33,7 @@ #include <stdio.h> #include <inttypes.h> #include <string.h> +#include <limits.h> struct ptunit_srcloc ptunit_mk_srcloc(const char *file, uint32_t line) @@ -211,11 +213,16 @@ static const char *basename(const char *file) { const char *base; + size_t len; if (!file) return NULL; - for (base = file + strlen(file); base != file; base -= 1) { + len = strnlen(file, FILENAME_MAX); + if (FILENAME_MAX <= len) + return NULL; + + for (base = file + len; base != file; base -= 1) { char ch; ch = base-1; @@ -228,7 +235,8 @@ static void ptunit_print_srcloc(const struct ptunit_test *test) { - const char *file; + const char *file, *base; + int prec; switch (test->result.type) { case ptur_passed: @@ -240,11 +248,17 @@ case ptur_failed_unsigned_int: case ptur_failed_pointer: case ptur_failed_str: - file = basename(test->result.failed.where.file); + file = test->result.failed.where.file; if (!file) file = "<unknown>"; - fprintf(stderr, "%s:%" PRIu32 ": ", file, + base = basename(file); + if (!base) + base = file; + + prec = (INT_MAX < FILENAME_MAX ? INT_MAX : FILENAME_MAX); + + fprintf(stderr, "%.*s:%" PRIu32 ": ", prec, base, test->result.failed.where.line); break; }
View file
_service:tar_scm:v2.0.5.tar.gz/ptunit/src/windows/ptunit_mkfile.c -> _service:tar_scm:v2.1.tar.gz/ptunit/src/windows/ptunit_mkfile.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/ptunit/test/src/ptunit-selftest.c -> _service:tar_scm:v2.1.tar.gz/ptunit/test/src/ptunit-selftest.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/ptxed/CMakeLists.txt -> _service:tar_scm:v2.1.tar.gz/ptxed/CMakeLists.txt
Changed
@@ -1,4 +1,5 @@ -# Copyright (c) 2013-2022, Intel Corporation +# Copyright (c) 2013-2023, Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: @@ -45,14 +46,6 @@ ../libipt/src/pt_cpu.c ) -if (CMAKE_HOST_UNIX) - set(PTXED_FILES ${PTXED_FILES} ../libipt/src/posix/pt_cpuid.c) -endif (CMAKE_HOST_UNIX) - -if (CMAKE_HOST_WIN32) - set(PTXED_FILES ${PTXED_FILES} ../libipt/src/windows/pt_cpuid.c) -endif (CMAKE_HOST_WIN32) - if (FEATURE_ELF) set(PTXED_FILES ${PTXED_FILES} src/load_elf.c) endif (FEATURE_ELF)
View file
_service:tar_scm:v2.0.5.tar.gz/ptxed/include/load_elf.h -> _service:tar_scm:v2.1.tar.gz/ptxed/include/load_elf.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/ptxed/src/load_elf.c -> _service:tar_scm:v2.1.tar.gz/ptxed/src/load_elf.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/ptxed/src/ptxed.c -> _service:tar_scm:v2.1.tar.gz/ptxed/src/ptxed.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2022, Intel Corporation + * Copyright (c) 2013-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -68,6 +69,25 @@ struct pt_block_decoder *block; } variant; + /* Decoder-specific configuration. + * + * We use a set of structs to store the configuration for multiple + * decoders. + * + * - block decoder. + */ + struct { + /* A collection of decoder-specific flags. */ + struct pt_conf_flags flags; + } block; + + /* - instruction flow decoder. */ + struct { + /* A collection of decoder-specific flags. */ + struct pt_conf_flags flags; + } insn; + + /* The image section cache. */ struct pt_image_section_cache *iscache; @@ -127,9 +147,6 @@ /* Print the ip of events. */ uint32_t print_event_ip:1; - /* Request tick events. */ - uint32_t enable_tick_events:1; - #if defined(FEATURE_SIDEBAND) /* Print sideband warnings. */ uint32_t print_sb_warnings:1; @@ -235,6 +252,7 @@ printf(" --event:time print the tsc for events if available.\n"); printf(" --event:ip print the ip of events if available.\n"); printf(" --event:tick request tick events.\n"); + printf(" --event:iflags request iflags events.\n"); printf(" --filter:addr<n>_cfg <cfg> set IA32_RTIT_CTL.ADDRn_CFG to <cfg>.\n"); printf(" --filter:addr<n>_a <base> set IA32_RTIT_ADDRn_A to <base>.\n"); printf(" --filter:addr<n>_b <limit> set IA32_RTIT_ADDRn_B to <limit>.\n"); @@ -255,6 +273,8 @@ printf(" load a perf_event sideband stream from <file>.\n"); printf(" an optional offset or range can be given.\n"); printf(" --pevent:sample-type <val> set perf_event_attr.sample_type to <val> (default: 0).\n"); + printf(" --pevent:sample-config <id>:<val>\n"); + printf(" set perf_event_attr.sample_type to <val> for event <id>.\n"); printf(" --pevent:time-zero <val> set perf_event_mmap_page.time_zero to <val> (default: 0).\n"); printf(" --pevent:time-shift <val> set perf_event_mmap_page.time_shift to <val> (default: 0).\n"); printf(" --pevent:time-mult <val> set perf_event_mmap_page.time_mult to <val> (default: 1).\n"); @@ -278,19 +298,24 @@ #endif /* defined(FEATURE_ELF) */ printf(" --raw <file>:<from>-<to>:<base> load a raw binary from <file> at address <base>.\n"); printf(" an optional offset or range can be given.\n"); - printf(" --cpu none|auto|f/m/s set cpu to the given value and decode according to:\n"); + printf(" --cpu none|f/m/s set cpu to the given value and decode according to:\n"); printf(" none spec (default)\n"); - printf(" auto current cpu\n"); printf(" f/m/s family/model/stepping\n"); printf(" --mtc-freq <n> set the MTC frequency (IA32_RTIT_CTL17:14) to <n>.\n"); printf(" --nom-freq <n> set the nominal frequency (MSR_PLATFORM_INFO15:8) to <n>.\n"); printf(" --cpuid-0x15.eax set the value of cpuid0x15.eax.\n"); printf(" --cpuid-0x15.ebx set the value of cpuid0x15.ebx.\n"); printf(" --insn-decoder use the instruction flow decoder.\n"); +#if (LIBIPT_VERSION >= 0x201) + printf(" --insn:keep-tcal-on-ovf preserve timing calibration on overflow.\n"); +#endif printf(" --block-decoder use the block decoder (default).\n"); printf(" --block:show-blocks show blocks in the output.\n"); printf(" --block:end-on-call set the end-on-call block decoder flag.\n"); printf(" --block:end-on-jump set the end-on-jump block decoder flag.\n"); +#if (LIBIPT_VERSION >= 0x201) + printf(" --block:keep-tcal-on-ovf preserve timing calibration on overflow.\n"); +#endif printf("\n"); #if defined(FEATURE_ELF) printf("You must specify at least one binary or ELF file (--raw|--elf).\n"); @@ -599,9 +624,13 @@ static const char *visualize_iclass(enum pt_insn_class iclass) { switch (iclass) { +#if (LIBIPT_VERSION >= 0x201) + case ptic_unknown: + return "unknown"; +#else case ptic_error: - return "unknown/error"; - + return "error"; +#endif case ptic_other: return "other"; @@ -628,6 +657,11 @@ case ptic_ptwrite: return "ptwrite"; + +#if (LIBIPT_VERSION >= 0x201) + case ptic_indirect: + return "indirect"; +#endif } return "undefined"; @@ -648,9 +682,13 @@ iclass = xed_inst_iclass(inst); switch (insn->iclass) { +#if (LIBIPT_VERSION >= 0x201) + case ptic_unknown: + break; +#else case ptic_error: break; - +#endif case ptic_ptwrite: case ptic_other: switch (category) { @@ -739,10 +777,12 @@ case XED_ICLASS_IRETD: case XED_ICLASS_IRETQ: case XED_ICLASS_SYSRET: + case XED_ICLASS_SYSRET64: case XED_ICLASS_SYSRET_AMD: case XED_ICLASS_SYSEXIT: case XED_ICLASS_VMLAUNCH: case XED_ICLASS_VMRESUME: + case XED_ICLASS_UIRET: return; } break; @@ -752,6 +792,38 @@ return; break; + +#if (LIBIPT_VERSION >= 0x201) + case ptic_indirect: + switch (iclass) { + default: + break; + + case XED_ICLASS_CALL_FAR: + case XED_ICLASS_INT: + case XED_ICLASS_INT1: + case XED_ICLASS_INT3: + case XED_ICLASS_INTO: + case XED_ICLASS_SYSCALL: + case XED_ICLASS_SYSCALL_AMD: + case XED_ICLASS_SYSENTER: + case XED_ICLASS_VMCALL: + case XED_ICLASS_RET_FAR: + case XED_ICLASS_IRET: + case XED_ICLASS_IRETD: + case XED_ICLASS_IRETQ: + case XED_ICLASS_SYSRET: + case XED_ICLASS_SYSRET64: + case XED_ICLASS_SYSRET_AMD: + case XED_ICLASS_SYSEXIT: + case XED_ICLASS_VMLAUNCH: + case XED_ICLASS_VMRESUME: + case XED_ICLASS_JMP_FAR: + case XED_ICLASS_JMP: + return; + } + break; +#endif /* (LIBIPT_VERSION >= 0x201) */ } /* If we get here, @insn->iclass doesn't match XED's classification. */ @@ -1133,6 +1205,130 @@ case ptev_mnt: printf("mnt: %" PRIx64, event->variant.mnt.payload); break; + +#if (LIBIPT_VERSION >= 0x201) + case ptev_tip: + printf("tip: %" PRIx64, event->variant.tip.ip); + break; + + case ptev_tnt: { + uint64_t index; + + printf("tnt: "); + for (index = event->variant.tnt.size; index; index >>= 1) + printf("%s", + (event->variant.tnt.bits & index) ? "!" : "."); + } + break; + + case ptev_iflags: + printf("interrupts %s", + event->variant.iflags.iflag ? "enabled" : "disabled"); + + if (options->print_event_ip && !event->ip_suppressed) + printf(", ip: %016" PRIx64, + event->variant.iflags.ip); + break; + + case ptev_interrupt: + printf("interrupt %u", event->variant.interrupt.vector); + + if (event->variant.interrupt.has_cr2) + printf(", cr2: %016" PRIx64, + event->variant.interrupt.cr2); + + if (options->print_event_ip && !event->ip_suppressed) + printf(", ip: %016" PRIx64, + event->variant.interrupt.ip); + break; + + case ptev_iret: + printf("iret"); + + if (options->print_event_ip && !event->ip_suppressed) + printf(", ip: %016" PRIx64, + event->variant.iret.ip); + break; + + case ptev_smi: + printf("smi"); + + if (options->print_event_ip && !event->ip_suppressed) + printf(", ip: %016" PRIx64, + event->variant.smi.ip); + break; + + case ptev_rsm: + printf("rsm"); + + if (options->print_event_ip && !event->ip_suppressed) + printf(", ip: %016" PRIx64, + event->variant.rsm.ip); + break; + + case ptev_sipi: + printf("sipi: %x", event->variant.sipi.vector); + break; + + case ptev_init: + printf("init"); + + if (options->print_event_ip && !event->ip_suppressed) + printf(", ip: %016" PRIx64, + event->variant.init.ip); + break; + + case ptev_vmentry: + printf("vmentry"); + + if (options->print_event_ip && !event->ip_suppressed) + printf(", ip: %016" PRIx64, + event->variant.vmentry.ip); + break; + + case ptev_vmexit: + printf("vmexit"); + + if (event->variant.vmexit.has_vector) + printf(", intr: %u", event->variant.vmexit.vector); + + if (event->variant.vmexit.has_vmxr) + printf(", vmxr: %016" PRIx64, + event->variant.vmexit.vmxr); + + if (event->variant.vmexit.has_vmxq) + printf(", vmxq: %016" PRIx64, + event->variant.vmexit.vmxq); + + if (options->print_event_ip && !event->ip_suppressed) + printf(", ip: %016" PRIx64, + event->variant.vmexit.ip); + break; + + case ptev_shutdown: + printf("shutdown"); + + if (options->print_event_ip && !event->ip_suppressed) + printf(", ip: %016" PRIx64, + event->variant.shutdown.ip); + break; + + case ptev_uintr: + printf("uintr %u", event->variant.uintr.vector); + + if (options->print_event_ip && !event->ip_suppressed) + printf(", ip: %016" PRIx64, + event->variant.uintr.ip); + break; + + case ptev_uiret: + printf("uiret"); + + if (options->print_event_ip && !event->ip_suppressed) + printf(", ip: %016" PRIx64, + event->variant.uiret.ip); + break; +#endif } printf("\n"); @@ -1320,7 +1516,12 @@ /* Even in case of errors, we may have succeeded * in decoding the current instruction. */ - if (insn.iclass != ptic_error) { +#if (LIBIPT_VERSION >= 0x201) + if (insn.iclass != ptic_unknown) +#else + if (insn.iclass != ptic_error) +#endif + { if (!options->quiet) print_insn(&insn, &xed, options, offset, time); @@ -1841,8 +2042,7 @@ switch (decoder->type) { case pdt_insn_decoder: - if (options->enable_tick_events) - config.flags.variant.insn.enable_tick_events = 1; + config.flags = decoder->insn.flags; decoder->variant.insn = pt_insn_alloc_decoder(&config); if (!decoder->variant.insn) { @@ -1860,8 +2060,7 @@ break; case pdt_block_decoder: - if (options->enable_tick_events) - config.flags.variant.block.enable_tick_events = 1; + config.flags = decoder->block.flags; decoder->variant.block = pt_blk_alloc_decoder(&config); if (!decoder->variant.block) { @@ -2004,6 +2203,58 @@ return 0; } +static int pt_parse_sample_config(struct pt_sb_pevent_config *pevent, + const char *arg) +{ + struct pev_sample_config *sample_config; + uint64_t identifier, sample_type; + uint8_t nstypes; + char *rest; + + if (!pevent || !arg) + return -pte_internal; + + errno = 0; + identifier = strtoull(arg, &rest, 0); + if (errno || (rest == arg)) + return -pte_invalid; + + arg = rest; + if (arg0 != ':') + return -pte_invalid; + + arg += 1; + sample_type = strtoull(arg, &rest, 0); + if (errno || *rest) + return -pte_invalid; + + sample_config = pevent->sample_config; + if (!sample_config) { + sample_config = malloc(sizeof(*sample_config)); + if (!sample_config) + return -pte_nomem; + + memset(sample_config, 0, sizeof(*sample_config)); + pevent->sample_config = sample_config; + } + + nstypes = sample_config->nstypes; + sample_config = realloc(sample_config, + sizeof(*sample_config) + + ((nstypes + 1) * + sizeof(struct pev_sample_type))); + if (!sample_config) + return -pte_nomem; + + sample_config->stypesnstypes.identifier = identifier; + sample_config->stypesnstypes.sample_type = sample_type; + sample_config->nstypes = nstypes + 1; + + pevent->sample_config = sample_config; + + return 0; +} + #endif /* defined(FEATURE_PEVENT) */ #endif /* defined(FEATURE_SIDEBAND) */ @@ -2290,7 +2541,17 @@ continue; } if (strcmp(arg, "--event:tick") == 0) { - options.enable_tick_events = 1; + decoder.block.flags.variant.block. + enable_tick_events = 1; + decoder.insn.flags.variant.insn.enable_tick_events = 1; + + continue; + } + if (strcmp(arg, "--event:iflags") == 0) { + decoder.block.flags.variant.block. + enable_iflags_events = 1; + decoder.insn.flags.variant.insn. + enable_iflags_events = 1; continue; } @@ -2564,6 +2825,20 @@ continue; } + if (strcmp(arg, "--pevent:sample-config") == 0) { + arg = argvi++; + + errcode = pt_parse_sample_config(&decoder.pevent, arg); + if (errcode < 0) { + fprintf(stderr, + "%s: bad sample config %s: %s.\n", + prog, arg, + pt_errstr(pt_errcode(errcode))); + goto err; + } + + continue; + } if (strcmp(arg, "--pevent:time-zero") == 0) { if (!get_arg_uint64(&decoder.pevent.time_zero, "--pevent:time-zero", @@ -2694,18 +2969,6 @@ } arg = argvi++; - if (strcmp(arg, "auto") == 0) { - errcode = pt_cpu_read(&config.cpu); - if (errcode < 0) { - fprintf(stderr, - "%s: error reading cpu: %s.\n", - prog, - pt_errstr(pt_errcode(errcode))); - return 1; - } - continue; - } - if (strcmp(arg, "none") == 0) { memset(&config.cpu, 0, sizeof(config.cpu)); continue; @@ -2767,6 +3030,13 @@ continue; } +#if (LIBIPT_VERSION >= 0x201) + if (strcmp(arg, "--insn:keep-tcal-on-ovf") == 0) { + decoder.insn.flags.variant.insn.keep_tcal_on_ovf = 1; + continue; + } +#endif + if (strcmp(arg, "--block-decoder") == 0) { if (ptxed_have_decoder(&decoder)) { fprintf(stderr, @@ -2785,15 +3055,21 @@ } if (strcmp(arg, "--block:end-on-call") == 0) { - config.flags.variant.block.end_on_call = 1; + decoder.block.flags.variant.block.end_on_call = 1; continue; } if (strcmp(arg, "--block:end-on-jump") == 0) { - config.flags.variant.block.end_on_jump = 1; + decoder.block.flags.variant.block.end_on_jump = 1; continue; } +#if (LIBIPT_VERSION >= 0x201) + if (strcmp(arg, "--block:keep-tcal-on-ovf") == 0) { + decoder.block.flags.variant.block.keep_tcal_on_ovf = 1; + continue; + } +#endif fprintf(stderr, "%s: unknown option: %s.\n", prog, arg); goto err; }
View file
_service:tar_scm:v2.0.5.tar.gz/script/perf-copy-mapped-files.bash -> _service:tar_scm:v2.1.tar.gz/script/perf-copy-mapped-files.bash
Changed
@@ -1,6 +1,7 @@ #! /bin/bash # -# Copyright (c) 2015-2022, Intel Corporation +# Copyright (c) 2015-2023, Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/script/perf-get-opts.bash -> _service:tar_scm:v2.1.tar.gz/script/perf-get-opts.bash
Changed
@@ -1,6 +1,7 @@ #! /bin/bash # -# Copyright (c) 2015-2022, Intel Corporation +# Copyright (c) 2015-2023, Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: @@ -113,35 +114,58 @@ gawk_sample_type() { echo $1 | gawk -- ' - BEGIN { RS = "|\n" } - /^TID$/ { config += 0x00002 } - /^TIME$/ { config += 0x00004 } - /^ID$/ { config += 0x00040 } - /^CPU$/ { config += 0x00080 } - /^STREAM$/ { config += 0x00200 } - /^IDENTIFIER$/ { config += 0x10000 } + BEGIN { RS = "|\n" } + /^IP$/ { config += 0x0000001 } + /^TID$/ { config += 0x0000002 } + /^TIME$/ { config += 0x0000004 } + /^ADDR$/ { config += 0x0000008 } + /^READ$/ { config += 0x0000010 } + /^CALLCHAIN$/ { config += 0x0000020 } + /^ID$/ { config += 0x0000040 } + /^CPU$/ { config += 0x0000080 } + /^PERIOD$/ { config += 0x0000100 } + /^STREAM$/ { config += 0x0000200 } + /^STREAM_ID$/ { config += 0x0000200 } + /^RAW$/ { config += 0x0000400 } + /^BRANCH_STACK$/ { config += 0x0000800 } + /^REGS_USER$/ { config += 0x0001000 } + /^STACK_USER$/ { config += 0x0002000 } + /^WEIGHT$/ { config += 0x0004000 } + /^DATA_SRC$/ { config += 0x0008000 } + /^IDENTIFIER$/ { config += 0x0010000 } + /^TRANSACTION$/ { config += 0x0020000 } + /^REGS_INTR$/ { config += 0x0040000 } + /^PHYS_ADDR$/ { config += 0x0080000 } + /^AUX$/ { config += 0x0100000 } + /^CGROUP$/ { config += 0x0200000 } + /^DATA_PAGE_SIZE$/ { config += 0x0400000 } + /^CODE_PAGE_SIZE$/ { config += 0x0800000 } + /^WEIGHT_STRUCT$/ { config += 0x1000000 } END { - if (config != 0) { - printf(" --pevent:sample-type 0x%x", config) - } + printf("0x%lx", config) } ' } -attr_sample_types=$(perf evlist -v -i $file | gawk -F' ' -- ' - BEGIN { RS = "," } - /sample_type/ { print $2 } -' | sort | uniq) - -for attr in $attr_sample_types; do - # We assume at most one attr with and at most one attr without CPU - # - if $(echo $attr | grep -e CPU) ; then - gawk_sample_type $attr - else - gawk_sample_type $attr - fi -done +zero_config=1 +perf script --header-only -i $file | grep -e '^# *event *:' | \ + sed 's/.*id = {\(^}*\)}.*sample_type = \(^,*\),.*/\1:\2/' | \ + while read -r conf; do + ids=$(echo $conf | sed 's/\(^:*\):.*/\1/' | sed 's/,//g') + sts=$(echo $conf | sed 's/.*:\(.*\)/\1/') + + for id in $ids; do + # The reserved zero identifier used for synthesized event + # records uses the same sample type as the first identifier in + # the first event. + # + if (( $zero_config )); then + echo -n " --pevent:sample-config 0:$(gawk_sample_type $sts)" + zero_config=0 + fi + echo -n " --pevent:sample-config $id:$(gawk_sample_type $sts)" + done + done perf evlist -v -i $file | grep intel_pt | gawk -F' ' -- ' BEGIN { RS = "," } @@ -206,8 +230,18 @@ ' fi -for sbfile in $(ls -1 "$(basename $file)"-sideband*.pevent 2>/dev/null); do - if -z "$master" || "$sbfile" == "$master" ; then +fbase="$(basename "$file")" +mbase="$(basename "$master")" +sdir="$(dirname "$master")" +if "$mbase" == "$master" ; then + sdir="$(dirname "$file")" +fi +for sbfile in "$sdir/$fbase"-sideband*.pevent; do + if ! -e "$sbfile" ; then + break + fi + + if -z "$master" || "$sbfile" == "$sdir/$mbase" ; then echo -n " --pevent:primary $sbfile" else echo -n " --pevent:secondary $sbfile"
View file
_service:tar_scm:v2.0.5.tar.gz/script/perf-read-aux.bash -> _service:tar_scm:v2.1.tar.gz/script/perf-read-aux.bash
Changed
@@ -1,6 +1,7 @@ #! /bin/bash # -# Copyright (c) 2015-2022, Intel Corporation +# Copyright (c) 2015-2023, Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/script/perf-read-sideband.bash -> _service:tar_scm:v2.1.tar.gz/script/perf-read-sideband.bash
Changed
@@ -1,6 +1,7 @@ #! /bin/bash # -# Copyright (c) 2015-2022, Intel Corporation +# Copyright (c) 2015-2023, Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/script/test.bash -> _service:tar_scm:v2.1.tar.gz/script/test.bash
Changed
@@ -1,6 +1,7 @@ #! /bin/bash # -# Copyright (c) 2013-2022, Intel Corporation +# Copyright (c) 2013-2023, Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: @@ -152,8 +153,8 @@ lst=$base.lst - # execute pttc - remove the extra \r in Windows line endings - files=`run "$pttc_cmd" $pttc_arg $cpu "$ptt" | sed 's/\r\n/\n/g'` + # execute pttc to produce input and expected output files + files=`run "$pttc_cmd" $pttc_arg $cpu "$ptt"` ret=$? if $ret != 0 ; then echo "$ptt: $pttc_cmd $pttc_arg failed with $ret" >&2
View file
_service:tar_scm:v2.0.5.tar.gz/sideband/CMakeLists.txt -> _service:tar_scm:v2.1.tar.gz/sideband/CMakeLists.txt
Changed
@@ -1,4 +1,5 @@ -# Copyright (c) 2017-2022, Intel Corporation +# Copyright (c) 2017-2023, Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: @@ -56,9 +57,12 @@ set_target_properties(libipt-sb PROPERTIES PREFIX "" + IMPORT_PREFIX "" PUBLIC_HEADER ${CMAKE_CURRENT_BINARY_DIR}/include/libipt-sb.h VERSION ${PT_VERSION} SOVERSION ${PT_VERSION_MAJOR} + C_STANDARD 11 + C_STANDARD_REQUIRED ON ) target_link_libraries(libipt-sb libipt)
View file
_service:tar_scm:v2.0.5.tar.gz/sideband/include/libipt-sb.h.in -> _service:tar_scm:v2.1.tar.gz/sideband/include/libipt-sb.h.in
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2017-2022, Intel Corporation + * Copyright (c) 2017-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -33,15 +34,12 @@ #include <stdint.h> #include <stdio.h> +#include "intel-pt.h" + #ifdef __cplusplus extern "C" { #endif -struct pt_image_section_cache; -struct pt_image; -struct pt_event; - - /* A macro to mark functions as exported. */ #ifndef pt_sb_export # if defined(__GNUC__) @@ -185,7 +183,7 @@ * Initialize decoders that have been added since pt_sb_alloc() or since the * last pt_sb_init_decoders() call by fetching their first sideband record. * - * Returns zero on success, a negative error code otherwise. + * Returns zero on success, a negative pt_error_code otherwise. */ extern pt_sb_export int pt_sb_init_decoders(struct pt_sb_session *session); @@ -204,7 +202,7 @@ * to @stream according to @flags. Pass a NULL @stream to ask decoders to not * print anything. * - * Returns zero on success, a negative error code otherwise. + * Returns zero on success, a negative pt_error_code otherwise. */ extern pt_sb_export int pt_sb_event(struct pt_sb_session *session, struct pt_image **image, @@ -219,7 +217,7 @@ * * Decoders that return an error will be removed from @session and freed. * - * Returns zero on success, a negative error code otherwise. + * Returns zero on success, a negative pt_error_code otherwise. */ extern pt_sb_export int pt_sb_dump(struct pt_sb_session *session, FILE *stream, uint32_t flags, uint64_t tsc); @@ -265,7 +263,7 @@ * Adds a section of @size bytes from @filename starting at @offset to @context's * image at @vaddr. * - * Returns zero on success, a negative error code otherwise. + * Returns zero on success, a negative pt_error_code otherwise. */ extern pt_sb_export int pt_sb_ctx_mmap(struct pt_sb_session *session, struct pt_sb_context *context, @@ -277,7 +275,7 @@ * Install @context->image in @image. The caller is responsible for holding a * reference to @context as long as its image is in use. * - * Returns zero on success, a negative error code otherwise. + * Returns zero on success, a negative pt_error_code otherwise. */ extern pt_sb_export int pt_sb_ctx_switch_to(struct pt_image **image, struct pt_sb_session *session, @@ -310,7 +308,7 @@ * This does not provide a new reference to @context. Use pt_sb_ctx_get() if * you need to keep the context. * - * Returns zero on success, a negative error code otherwise. + * Returns zero on success, a negative pt_error_code otherwise. */ extern pt_sb_export int pt_sb_get_context_by_pid(struct pt_sb_context **context, @@ -325,7 +323,7 @@ * Provide a NULL process context in @context if a context for @pid does not * exist in @session. * - * Returns zero on success, a negative error code otherwise. + * Returns zero on success, a negative pt_error_code otherwise. */ extern pt_sb_export int pt_sb_find_context_by_pid(struct pt_sb_context **context, @@ -337,7 +335,7 @@ * Future lookups won't find @context but it won't be freed until the last user * puts it. * - * Returns zero on success, a negative error code otherwise. + * Returns zero on success, a negative pt_error_code otherwise. */ extern pt_sb_export int pt_sb_remove_context(struct pt_sb_session *session, struct pt_sb_context *context); @@ -369,7 +367,7 @@ /* Fetch the next sideband record and provide its timestamp. * - * Return zero on success, a negative error code otherwise. + * Return zero on success, a negative pt_error_code otherwise. */ int (*fetch)(struct pt_sb_session *session, uint64_t *tsc, void *priv); @@ -400,7 +398,7 @@ * of their next record's timestamp. This allows sideband decoders to * postpone actions until a suitable event. * - * Return zero on success, a negative error code otherwise. + * Return zero on success, a negative pt_error_code otherwise. */ int (*apply)(struct pt_sb_session *session, struct pt_image **image, const struct pt_event *event, void *priv); @@ -411,7 +409,7 @@ * of enum pt_sb_print_flag. A value of zero means that only errors * shall be printed. * - * Return zero on success, a negative error code otherwise. + * Return zero on success, a negative pt_error_code otherwise. */ int (*print)(struct pt_sb_session *session, FILE *stream, uint32_t flags, void *priv); @@ -444,6 +442,35 @@ const struct pt_sb_decoder_config *config); +#if (LIBIPT_SB_VERSION >= 0x201) + +/* A perf event sample type. */ +struct pev_sample_type { + /* The sample identifier. + * + * This corresponds to the PERF_SAMPLE_IDENTIFIER sample that can be + * found at the very end of the event record. + */ + uint64_t identifier; + + /* The sample type. + * + * At least PERF_SAMPLE_IDENTIFIER must be set. + */ + uint64_t sample_type; +}; + +/* A perf event sample configuration. */ +struct pev_sample_config { + /* The number of sample types in this configuration. */ + uint8_t nstypes; + + /* An array of \@nstypes sample types. */ + struct pev_sample_type stypes; +}; + +#endif /* (LIBIPT_SB_VERSION >= 0x201) */ + /* The configuration for a Linux perf event sideband decoder. */ struct pt_sb_pevent_config { /* The size of the config structure in bytes. */ @@ -487,6 +514,8 @@ /* The respective field in struct perf_event_attr. * * We require sample_id_all in struct perf_event_attr to be set. + * + * This field is only valid if \@sample_config is NULL. */ uint64_t sample_type; @@ -511,6 +540,11 @@ * - whether this is a primary decoder (secondary if clear). */ uint32_t primary:1; + +#if (LIBIPT_SB_VERSION >= 0x201) + /* The sample configuration. */ + struct pev_sample_config *sample_config; +#endif }; /* Allocate a Linux perf event sideband decoder. @@ -518,7 +552,7 @@ * Allocates a sideband decoder for the Linux perf event format based on @config * and adds it to @session. * - * Returns zero on success, a negative error code otherwise. + * Returns zero on success, a negative pt_error_code otherwise. */ extern pt_sb_export int pt_sb_alloc_pevent_decoder(struct pt_sb_session *session,
View file
_service:tar_scm:v2.0.5.tar.gz/sideband/internal/include/pt_sb_context.h -> _service:tar_scm:v2.1.tar.gz/sideband/internal/include/pt_sb_context.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2017-2022, Intel Corporation + * Copyright (c) 2017-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/sideband/internal/include/pt_sb_decoder.h -> _service:tar_scm:v2.1.tar.gz/sideband/internal/include/pt_sb_decoder.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2017-2022, Intel Corporation + * Copyright (c) 2017-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/sideband/internal/include/pt_sb_file.h -> _service:tar_scm:v2.1.tar.gz/sideband/internal/include/pt_sb_file.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2017-2022, Intel Corporation + * Copyright (c) 2017-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/sideband/internal/include/pt_sb_pevent.h -> _service:tar_scm:v2.1.tar.gz/sideband/internal/include/pt_sb_pevent.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2017-2022, Intel Corporation + * Copyright (c) 2017-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/sideband/internal/include/pt_sb_session.h -> _service:tar_scm:v2.1.tar.gz/sideband/internal/include/pt_sb_session.h
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2017-2022, Intel Corporation + * Copyright (c) 2017-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/sideband/src/pt_sb_context.c -> _service:tar_scm:v2.1.tar.gz/sideband/src/pt_sb_context.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2017-2022, Intel Corporation + * Copyright (c) 2017-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,7 +31,6 @@ #include "pt_sb_session.h" #include "libipt-sb.h" -#include "intel-pt.h" #include <stdlib.h>
View file
_service:tar_scm:v2.0.5.tar.gz/sideband/src/pt_sb_file.c -> _service:tar_scm:v2.1.tar.gz/sideband/src/pt_sb_file.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2017-2022, Intel Corporation + * Copyright (c) 2017-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/sideband/src/pt_sb_pevent.c -> _service:tar_scm:v2.1.tar.gz/sideband/src/pt_sb_pevent.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2017-2022, Intel Corporation + * Copyright (c) 2017-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -28,8 +29,6 @@ #include "libipt-sb.h" -#include "intel-pt.h" - #ifndef FEATURE_PEVENT @@ -352,6 +351,11 @@ priv->tsc_offset = config->tsc_offset; priv->location = ploc_unknown; +#if (LIBIPT_SB_VERSION >= 0x201) + if (pev_config_has(config, sample_config)) + priv->pev.sample_config = config->sample_config; +#endif + return 0; } @@ -880,12 +884,10 @@ if (errcode < 0) return errcode; - /* Print samples if configured. */ - if (priv->pev.sample_type) { - errcode = pt_sb_pevent_print_samples(event, stream, flags); - if (errcode < 0) - return errcode; - } + /* Print samples that were configured for the record. */ + errcode = pt_sb_pevent_print_samples(event, stream, flags); + if (errcode < 0) + return errcode; if (flags) fprintf(stream, "\n"); @@ -1539,6 +1541,88 @@ event->variant.tick.ip); break; + + case ptev_tip: + return ploc_from_ip(loc, priv, event->variant.tip.ip); + +#if (LIBIPT_VERSION >= 0x201) + case ptev_iflags: + if (!event->ip_suppressed) + return ploc_from_ip(loc, priv, + event->variant.iflags.ip); + + break; + + case ptev_interrupt: + if (!event->ip_suppressed) + return ploc_from_ip(loc, priv, + event->variant.interrupt.ip); + + break; + + case ptev_iret: + if (!event->ip_suppressed) + return ploc_from_ip(loc, priv, + event->variant.iret.ip); + + break; + + case ptev_smi: + if (!event->ip_suppressed) + return ploc_from_ip(loc, priv, + event->variant.smi.ip); + + break; + + case ptev_rsm: + if (!event->ip_suppressed) + return ploc_from_ip(loc, priv, + event->variant.rsm.ip); + + break; + + case ptev_init: + if (!event->ip_suppressed) + return ploc_from_ip(loc, priv, + event->variant.init.ip); + + break; + + case ptev_vmentry: + if (!event->ip_suppressed) + return ploc_from_ip(loc, priv, + event->variant.vmentry.ip); + + break; + + case ptev_vmexit: + if (!event->ip_suppressed) + return ploc_from_ip(loc, priv, + event->variant.vmexit.ip); + + break; + + case ptev_shutdown: + if (!event->ip_suppressed) + return ploc_from_ip(loc, priv, + event->variant.shutdown.ip); + + break; + + case ptev_uintr: + if (!event->ip_suppressed) + return ploc_from_ip(loc, priv, + event->variant.uintr.ip); + + break; + + case ptev_uiret: + if (!event->ip_suppressed) + return ploc_from_ip(loc, priv, + event->variant.uiret.ip); + + break; +#endif } *loc = ploc_unknown; @@ -1637,7 +1721,7 @@ } break; - }; + } return 0; }
View file
_service:tar_scm:v2.0.5.tar.gz/sideband/src/pt_sb_session.c -> _service:tar_scm:v2.1.tar.gz/sideband/src/pt_sb_session.c
Changed
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2017-2022, Intel Corporation + * Copyright (c) 2017-2023, Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -31,7 +32,6 @@ #include "pt_sb_decoder.h" #include "libipt-sb.h" -#include "intel-pt.h" #include <string.h> #include <stdlib.h>
View file
_service:tar_scm:v2.0.5.tar.gz/test/CMakeLists.txt -> _service:tar_scm:v2.1.tar.gz/test/CMakeLists.txt
Changed
@@ -1,4 +1,5 @@ -# Copyright (c) 2015-2022, Intel Corporation +# Copyright (c) 2015-2023, Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/pevent/CMakeLists.txt -> _service:tar_scm:v2.1.tar.gz/test/pevent/CMakeLists.txt
Changed
@@ -1,4 +1,5 @@ -# Copyright (c) 2015-2022, Intel Corporation +# Copyright (c) 2015-2023, Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/pevent/src/pevent-comm_exec-mmap-tsc-iret.ptt -> _service:tar_scm:v2.1.tar.gz/test/pevent/src/pevent-comm_exec-mmap-tsc-iret.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2015-2022, Intel Corporation +; Copyright (c) 2015-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/pevent/src/pevent-dump.ptt -> _service:tar_scm:v2.1.tar.gz/test/pevent/src/pevent-dump.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2017-2022, Intel Corporation +; Copyright (c) 2017-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/pevent/src/pevent-dump_verbose.ptt -> _service:tar_scm:v2.1.tar.gz/test/pevent/src/pevent-dump_verbose.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2017-2022, Intel Corporation +; Copyright (c) 2017-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/pevent/src/pevent-fork.ptt -> _service:tar_scm:v2.1.tar.gz/test/pevent/src/pevent-fork.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2017-2022, Intel Corporation +; Copyright (c) 2017-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/pevent/src/pevent-mmap-tip_cached.ptt -> _service:tar_scm:v2.1.tar.gz/test/pevent/src/pevent-mmap-tip_cached.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2018-2022, Intel Corporation +; Copyright (c) 2018-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/pevent/src/pevent-mmap_secondary-tsc.ptt -> _service:tar_scm:v2.1.tar.gz/test/pevent/src/pevent-mmap_secondary-tsc.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2015-2022, Intel Corporation +; Copyright (c) 2015-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/pevent/src/pevent-split.ptt -> _service:tar_scm:v2.1.tar.gz/test/pevent/src/pevent-split.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2017-2022, Intel Corporation +; Copyright (c) 2017-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/pevent/src/pevent-tip_pgd-comm_exec-mmap-tsc-tip_pge.ptt -> _service:tar_scm:v2.1.tar.gz/test/pevent/src/pevent-tip_pgd-comm_exec-mmap-tsc-tip_pge.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2015-2022, Intel Corporation +; Copyright (c) 2015-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/pevent/src/pevent-tip_pgd-mmap-tsc-tip_pge.ptt -> _service:tar_scm:v2.1.tar.gz/test/pevent/src/pevent-tip_pgd-mmap-tsc-tip_pge.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2015-2022, Intel Corporation +; Copyright (c) 2015-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/pevent/src/pevent-tip_pgd-switch-tsc-tip_pge.ptt -> _service:tar_scm:v2.1.tar.gz/test/pevent/src/pevent-tip_pgd-switch-tsc-tip_pge.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2015-2022, Intel Corporation +; Copyright (c) 2015-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/pevent/src/pevent-tip_pgd-switch_cpu_wide-tsc-tip_pge.ptt -> _service:tar_scm:v2.1.tar.gz/test/pevent/src/pevent-tip_pgd-switch_cpu_wide-tsc-tip_pge.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2017-2022, Intel Corporation +; Copyright (c) 2017-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met: @@ -30,7 +31,7 @@ ; timing is off - delay the event application ; ; opt:ptdump --sb:compact --sb:offset -; opt:ptxed --event:tick --sb:compact --sb:offset --sb:switch +; opt:ptxed --event:tick --event:iflags --sb:compact --sb:offset --sb:switch ; org 0x1000
View file
_service:tar_scm:v2.0.5.tar.gz/test/pevent/src/pevent-warn.ptt -> _service:tar_scm:v2.1.tar.gz/test/pevent/src/pevent-warn.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2017-2022, Intel Corporation +; Copyright (c) 2017-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/apl11.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/apl11.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2017-2022, Intel Corporation +; Copyright (c) 2017-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met: @@ -42,6 +43,15 @@ ; cpu 6/151 ; cpu 6/154 ; cpu 6/191 +; cpu 6/182 +; cpu 6/175 +; cpu 6/183 +; cpu 6/181 +; cpu 6/170 +; cpu 6/172 +; cpu 6/186 +; cpu 6/204 +; cpu 6/221 ; org 0x1000
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/apl12-psb.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/apl12-psb.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2017-2022, Intel Corporation +; Copyright (c) 2017-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/apl12-tip_pge.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/apl12-tip_pge.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2017-2022, Intel Corporation +; Copyright (c) 2017-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/bad_cpu.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/bad_cpu.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2018-2022, Intel Corporation +; Copyright (c) 2018-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/bdm64-tip-xabort.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/bdm64-tip-xabort.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/bdm64-tnt-cond-xabort.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/bdm64-tnt-cond-xabort.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/bdm64-tnt-ind_call-xabort.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/bdm64-tnt-ind_call-xabort.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/bdm70-psb_fup-tip_pge.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/bdm70-psb_fup-tip_pge.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2013-2022, Intel Corporation +; Copyright (c) 2013-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met: @@ -55,6 +56,15 @@ ; cpu 6/151 ; cpu 6/154 ; cpu 6/191 +; cpu 6/173 +; cpu 6/174 +; cpu 6/183 +; cpu 6/181 +; cpu 6/170 +; cpu 6/172 +; cpu 6/207 +; cpu 6/186 +; cpu 6/204 ; ; Variant: sync at the PSB directly preceding the TIP.PGE. ;
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/bdm70-tip_pgd-psb_fup-tip_pge.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/bdm70-tip_pgd-psb_fup-tip_pge.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2013-2022, Intel Corporation +; Copyright (c) 2013-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met: @@ -55,6 +56,15 @@ ; cpu 6/151 ; cpu 6/154 ; cpu 6/191 +; cpu 6/173 +; cpu 6/174 +; cpu 6/183 +; cpu 6/181 +; cpu 6/170 +; cpu 6/172 +; cpu 6/207 +; cpu 6/186 +; cpu 6/204 ; ; Variant: sync at an earlier PSB. ;
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/call_direct-ret_compressed-pic.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/call_direct-ret_compressed-pic.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2015-2022, Intel Corporation +; Copyright (c) 2015-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/call_direct-ret_compressed.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/call_direct-ret_compressed.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2013-2022, Intel Corporation +; Copyright (c) 2013-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/call_direct-ret_uncompressed.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/call_direct-ret_uncompressed.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2013-2022, Intel Corporation +; Copyright (c) 2013-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/call_indirect-ret_compressed.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/call_indirect-ret_compressed.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2013-2022, Intel Corporation +; Copyright (c) 2013-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/call_indirect-ret_uncompressed.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/call_indirect-ret_uncompressed.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2013-2022, Intel Corporation +; Copyright (c) 2013-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/call_indirect_deferred-ret_compressed.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/call_indirect_deferred-ret_compressed.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2013-2022, Intel Corporation +; Copyright (c) 2013-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/cbr-cyc.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/cbr-cyc.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/cbr-mtc-cyc-mtc.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/cbr-mtc-cyc-mtc.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/cbr-tsc-cyc-tma.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/cbr-tsc-cyc-tma.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/cbr-tsc-tma-mtc-cyc.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/cbr-tsc-tma-mtc-cyc.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/direct_call-tip_pgd_noip-syscall.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/direct_call-tip_pgd_noip-syscall.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/direct_jump-tip_pgd_noip-far_call.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/direct_jump-tip_pgd_noip-far_call.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/dump-all-packets.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/dump-all-packets.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2013-2022, Intel Corporation +; Copyright (c) 2013-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met: @@ -85,6 +86,14 @@ ; @pt p52: pwrx(hw: c1, c6) ; @pt p53: ptw(0: 0x90abcdef, ip) ; @pt p54: ptw(1: 0x1234567890abcdef) +; @pt p55: mode.exec(16bit, if) +; @pt p56: mode.exec(32bit, if) +; @pt p57: mode.exec(64bit, if) +; @pt p58: cfe(2) +; @pt p59: cfe(3, ip) +; @pt p60: cfe(3: 0xf0, ip) +; @pt p61: cfe(1: 14) +; @pt p62: evd(2: 0xf00baa) ; @pt .exp(ptdump) ;%0p01 psbend @@ -141,3 +150,11 @@ ;%0p52 pwrx hw: c1, c6 ;%0p53 ptw 0: 90abcdef, ip ;%0p54 ptw 1: 1234567890abcdef +;%0p55 mode.exec if +;%0p56 mode.exec cs.d, if +;%0p57 mode.exec cs.l, if +;%0p58 cfe 2 +;%0p59 cfe 3, ip +;%0p60 cfe 3, ip +;%0p61 cfe 1: 14 +;%0p62 evd 2: f00baa
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/exstop_ip-tip_pgd.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/exstop_ip-tip_pgd.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2015-2022, Intel Corporation +; Copyright (c) 2015-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/fup-pip-vmcs-tip.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/fup-pip-vmcs-tip.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2016-2022, Intel Corporation +; Copyright (c) 2016-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/fup-pip-vmcs-tip_pgd.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/fup-pip-vmcs-tip_pgd.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2017-2022, Intel Corporation +; Copyright (c) 2017-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/fup-tip-eos.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/fup-tip-eos.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2016-2022, Intel Corporation +; Copyright (c) 2016-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/fup-tip-fup-tip_pgd.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/fup-tip-fup-tip_pgd.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2016-2022, Intel Corporation +; Copyright (c) 2016-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/fup-tip.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/fup-tip.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2013-2022, Intel Corporation +; Copyright (c) 2013-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/fup-tip_pgd-stop.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/fup-tip_pgd-stop.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2013-2022, Intel Corporation +; Copyright (c) 2013-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/fup-tip_pgd-tip_pge.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/fup-tip_pgd-tip_pge.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2013-2022, Intel Corporation +; Copyright (c) 2013-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/fup-tip_pgd-tip_pge_other_ip.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/fup-tip_pgd-tip_pge_other_ip.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/fup-tip_pgd.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/fup-tip_pgd.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2013-2022, Intel Corporation +; Copyright (c) 2013-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/fup-tip_pgd_noip.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/fup-tip_pgd_noip.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2013-2022, Intel Corporation +; Copyright (c) 2013-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/int-iret-cpl_0.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/int-iret-cpl_0.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/int-iret-cpl_3.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/int-iret-cpl_3.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/int-iret.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/int-iret.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/linear-fup-tip_pgd.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/linear-fup-tip_pgd.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2016-2022, Intel Corporation +; Copyright (c) 2016-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/linear-tip.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/linear-tip.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2016-2022, Intel Corporation +; Copyright (c) 2016-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/loop-tnt-64.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/loop-tnt-64.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2013-2022, Intel Corporation +; Copyright (c) 2013-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/loop-tnt-tnt.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/loop-tnt-tnt.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2013-2022, Intel Corporation +; Copyright (c) 2013-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/loop-tnt.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/loop-tnt.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2013-2022, Intel Corporation +; Copyright (c) 2013-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/mode_exec-tip.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/mode_exec-tip.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2016-2022, Intel Corporation +; Copyright (c) 2016-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/mtc-cyc_calibrate.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/mtc-cyc_calibrate.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.1.tar.gz/test/src/mtc-ovf_keep-cyc.ptt
Added
@@ -0,0 +1,112 @@ +; Copyright (c) 2018-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; +; * Redistributions of source code must retain the above copyright notice, +; this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright notice, +; this list of conditions and the following disclaimer in the documentation +; and/or other materials provided with the distribution. +; * Neither the name of Intel Corporation nor the names of its contributors +; may be used to endorse or promote products derived from this software +; without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; POSSIBILITY OF SUCH DAMAGE. + +; Test MTC and CYC-based timing and OVF. +; +; Variant: calibration preserved on OVF. +; +; opt:ptdump --time --time-delta --keep-tcal-on-ovf +; opt:ptdump --mtc-freq 4 --cpuid-0x15.eax 1 --cpuid-0x15.ebx 4 +; +; opt:ptxed --event:tick --event:time +; opt:ptxed --mtc-freq 4 --cpuid-0x15.eax 1 --cpuid-0x15.ebx 4 +; opt:ptxed --insn:keep-tcal-on-ovf --block:keep-tcal-on-ovf + +org 0x100000 +bits 64 + +; @pt p0: psb() +; @pt p1: mode.exec(64bit) +; @pt p2: fup(3: %l0) +; @pt p3: tsc(0x1000) +; @pt p4: tma(0x10, 0x40) +; @pt p5: psbend() +l0: nop + +; @pt p6: mtc(0x2) +; @pt p7: cyc(0x100) +; @pt p8: mtc(0x3) + +; @pt p9: cyc(0x80) +; @pt p10: tnt(t) +l1: jne l3 +l2: hlt + +; @pt p11: cyc(0x80) +; @pt p12: mtc(0x4) + +; @pt p13: ovf() +; @pt p14: fup(3: %l3) +l3: nop + +; @pt p15: cyc(0x80) +; @pt p16: tnt(t) +l4: jne l6 +l5: hlt + +l6: nop +l7: hlt +; @pt p17: cyc(0x80) +; @pt p18: fup(1: %l7) +; @pt p19: tip.pgd(0: %l7) + + +; @pt .exp(ptdump) +;%0p0 psb +;%0p1 mode.exec cs.l +;%0p2 fup 3: %?l0 +;%0p3 tsc 1000 tsc +1000 +;%0p4 tma 10, 40 tsc +0 +;%0p5 psbend +;%0p6 mtc 2 tsc +0 +;%p7: calibration error: no timing information +;%p7: error updating time: no calibration +;%0p7 cyc 100 tsc +0 +;%0p8 mtc 3 tsc +40 +;%0p9 cyc 80 tsc +20 +;%0p10 tnt.8 ! +;%0p11 cyc 80 tsc +20 +;%0p12 mtc 4 tsc +0 +;%0p13 ovf +;%0p14 fup 3: %?l3 +;%0p15 cyc 80 tsc +20 +;%0p16 tnt.8 ! +;%0p17 cyc 80 tsc +20 +;%0p18 fup 1: %?l7.2 +;%0p19 tip.pgd 0: %?l7.0 + + +; @pt .exp(ptxed) +;%0l0 # nop +;%0l1 # jne l3 +;0000000000001060 tick +;0000000000001080 overflow +;%0l3 # nop +;%0l4 # jne l6 +;00000000000010a0 tick +;%0l6 # nop +;00000000000010c0 disabled
View file
_service:tar_scm:v2.1.tar.gz/test/src/mtc-ovf_reset-cyc.ptt
Added
@@ -0,0 +1,114 @@ +; Copyright (c) 2018-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; +; * Redistributions of source code must retain the above copyright notice, +; this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright notice, +; this list of conditions and the following disclaimer in the documentation +; and/or other materials provided with the distribution. +; * Neither the name of Intel Corporation nor the names of its contributors +; may be used to endorse or promote products derived from this software +; without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; POSSIBILITY OF SUCH DAMAGE. + +; Test MTC and CYC-based timing and OVF. +; +; Variant: calibration reset on OVF. +; +; opt:ptdump --time --time-delta +; opt:ptdump --mtc-freq 4 --cpuid-0x15.eax 1 --cpuid-0x15.ebx 4 +; +; opt:ptxed --event:tick --event:time +; opt:ptxed --mtc-freq 4 --cpuid-0x15.eax 1 --cpuid-0x15.ebx 4 + +org 0x100000 +bits 64 + +; @pt p0: psb() +; @pt p1: mode.exec(64bit) +; @pt p2: fup(3: %l0) +; @pt p3: tsc(0x1000) +; @pt p4: tma(0x10, 0x40) +; @pt p5: psbend() +l0: nop + +; @pt p6: mtc(0x2) +; @pt p7: cyc(0x100) +; @pt p8: mtc(0x3) + +; @pt p9: cyc(0x80) +; @pt p10: tnt(t) +l1: jne l3 +l2: hlt + +; @pt p11: cyc(0x80) +; @pt p12: mtc(0x4) + +; @pt p13: ovf() +; @pt p14: fup(3: %l3) +l3: nop + +; @pt p15: cyc(0x80) +; @pt p16: tnt(t) +l4: jne l6 +l5: hlt + +l6: nop +l7: hlt +; @pt p17: cyc(0x80) +; @pt p18: fup(1: %l7) +; @pt p19: tip.pgd(0: %l7) + + +; @pt .exp(ptdump) +;%0p0 psb +;%0p1 mode.exec cs.l +;%0p2 fup 3: %?l0 +;%0p3 tsc 1000 tsc +1000 +;%0p4 tma 10, 40 tsc +0 +;%0p5 psbend +;%0p6 mtc 2 tsc +0 +;%p7: calibration error: no timing information +;%p7: error updating time: no calibration +;%0p7 cyc 100 tsc +0 +;%0p8 mtc 3 tsc +40 +;%0p9 cyc 80 tsc +20 +;%0p10 tnt.8 ! +;%0p11 cyc 80 tsc +20 +;%0p12 mtc 4 tsc +0 +;%0p13 ovf +;%0p14 fup 3: %?l3 +;%p15: calibration error: no timing information +;%p15: error updating time: no calibration +;%0p15 cyc 80 tsc +0 +;%0p16 tnt.8 ! +;%p17: calibration error: no timing information +;%p17: error updating time: no calibration +;%0p17 cyc 80 tsc +0 +;%0p18 fup 1: %?l7.2 +;%0p19 tip.pgd 0: %?l7.0 + + +; @pt .exp(ptxed) +;%0l0 # nop +;%0l1 # jne l3 +;0000000000001060 tick +;0000000000001080 overflow +;%0l3 # nop +;%0l4 # jne l6 +;%0l6 # nop +;0000000000001080 disabled
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/mtc.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/mtc.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/mwait-pwre-exstop_ip-fup-ovf.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/mwait-pwre-exstop_ip-fup-ovf.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2015-2022, Intel Corporation +; Copyright (c) 2015-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/mwait-pwre-exstop_ip-ovf.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/mwait-pwre-exstop_ip-ovf.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2015-2022, Intel Corporation +; Copyright (c) 2015-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/mwait-pwre-exstop_ip-pwrx.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/mwait-pwre-exstop_ip-pwrx.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2015-2022, Intel Corporation +; Copyright (c) 2015-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/ovf-fup.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/ovf-fup.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2015-2022, Intel Corporation +; Copyright (c) 2015-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/ovf-mnt-fup.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/ovf-mnt-fup.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2017-2022, Intel Corporation +; Copyright (c) 2017-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/ovf-mnt-tip_pge.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/ovf-mnt-tip_pge.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2017-2022, Intel Corporation +; Copyright (c) 2017-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/ovf-pwre-pwrx-tip_pge.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/ovf-pwre-pwrx-tip_pge.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2015-2022, Intel Corporation +; Copyright (c) 2015-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/ovf-timing-fup.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/ovf-timing-fup.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2015-2022, Intel Corporation +; Copyright (c) 2015-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/ovf-timing-tip_pge.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/ovf-timing-tip_pge.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2015-2022, Intel Corporation +; Copyright (c) 2015-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/ovf-tip_pge.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/ovf-tip_pge.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2015-2022, Intel Corporation +; Copyright (c) 2015-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/ovf.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/ovf.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2015-2022, Intel Corporation +; Copyright (c) 2015-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/pip-far_call.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/pip-far_call.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2015-2022, Intel Corporation +; Copyright (c) 2015-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/pip-pip_mov_cr3-fail.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/pip-pip_mov_cr3-fail.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2015-2022, Intel Corporation +; Copyright (c) 2015-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/pip-vmcs-tip_pgd.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/pip-vmcs-tip_pgd.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2017-2022, Intel Corporation +; Copyright (c) 2017-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/pip_mov_cr3-pip_mov_cr3.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/pip_mov_cr3-pip_mov_cr3.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2015-2022, Intel Corporation +; Copyright (c) 2015-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/psb-empty.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/psb-empty.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2013-2022, Intel Corporation +; Copyright (c) 2013-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/psb-exstop.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/psb-exstop.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2016-2022, Intel Corporation +; Copyright (c) 2016-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/psb-fup-psbend.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/psb-fup-psbend.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2013-2022, Intel Corporation +; Copyright (c) 2013-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/psb-fup-tip_pgd-stop.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/psb-fup-tip_pgd-stop.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2013-2022, Intel Corporation +; Copyright (c) 2013-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/psb-fup-tip_pgd.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/psb-fup-tip_pgd.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2013-2022, Intel Corporation +; Copyright (c) 2013-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/psb-mnt-fup-psbend.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/psb-mnt-fup-psbend.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2017-2022, Intel Corporation +; Copyright (c) 2017-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/psb-mnt-psbend.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/psb-mnt-psbend.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2017-2022, Intel Corporation +; Copyright (c) 2017-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/psb-ovf-fup.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/psb-ovf-fup.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2015-2022, Intel Corporation +; Copyright (c) 2015-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/psb-ovf-tip_pge.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/psb-ovf-tip_pge.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2015-2022, Intel Corporation +; Copyright (c) 2015-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/psb-pip-psb.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/psb-pip-psb.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/psb-pip-tip_pge.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/psb-pip-tip_pge.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/psb-psb.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/psb-psb.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2013-2022, Intel Corporation +; Copyright (c) 2013-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/psb-stop.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/psb-stop.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2013-2022, Intel Corporation +; Copyright (c) 2013-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/psb-tnt-psb.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/psb-tnt-psb.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2013-2022, Intel Corporation +; Copyright (c) 2013-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/psb-tsx.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/psb-tsx.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2013-2022, Intel Corporation +; Copyright (c) 2013-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/psb-tsx_abort-tip-fup-tip_pgd.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/psb-tsx_abort-tip-fup-tip_pgd.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2016-2022, Intel Corporation +; Copyright (c) 2016-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/psb-tsx_abort-tip_pgd.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/psb-tsx_abort-tip_pgd.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2016-2022, Intel Corporation +; Copyright (c) 2016-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/psb-tsx_abort.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/psb-tsx_abort.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2016-2022, Intel Corporation +; Copyright (c) 2016-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/psb-vmcs.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/psb-vmcs.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2013-2022, Intel Corporation +; Copyright (c) 2013-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/psb_nofup-psb.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/psb_nofup-psb.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2013-2022, Intel Corporation +; Copyright (c) 2013-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met: @@ -30,32 +31,37 @@ org 0x100000 bits 64 -; @pt p1: psb() -; @pt p2: psbend() - nop +; @pt p0: psb() +; @pt p1: fup(3: %l1) +; @pt p2: mode.exec(64bit) +; @pt p3: psbend() +l1: nop -; @pt p3: psb() -; @pt p4: fup(3: %l2) -; @pt p5: mode.exec(64bit) -; @pt p6: psbend() +; @pt p4: psb() +; @pt p5: fup(3: %l2) +; @pt p6: mode.exec(64bit) +; @pt p7: psbend() l2: nop -; @pt p7: fup(3: %l3) -; @pt p8: tip.pgd(0: 0) +; @pt p8: fup(3: %l3) +; @pt p9: tip.pgd(0: 0) l3: nop ; @pt .exp(ptxed) +;%0l1 # nop ;%0l2 # nop ;disabled ; @pt .exp(ptdump) -;%0p1 psb -;%0p2 psbend -;%0p3 psb -;%0p4 fup 3: %0l2 -;%0p5 mode.exec cs.l -;%0p6 psbend -;%0p7 fup 3: %0l3 -;%0p8 tip.pgd 0: ???????????????? +;%0p0 psb +;%0p1 fup 3: %0l1 +;%0p2 mode.exec cs.l +;%0p3 psbend +;%0p4 psb +;%0p5 fup 3: %0l2 +;%0p6 mode.exec cs.l +;%0p7 psbend +;%0p8 fup 3: %0l3 +;%0p9 tip.pgd 0: ????????????????
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/ptdump-bad_opc-resync.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/ptdump-bad_opc-resync.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2018-2022, Intel Corporation +; Copyright (c) 2018-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/ptdump-exec-mode.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/ptdump-exec-mode.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/ptdump-last-ip.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/ptdump-last-ip.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/ptdump-no-offset-raw.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/ptdump-no-offset-raw.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2016-2022, Intel Corporation +; Copyright (c) 2016-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/ptdump-no-offset.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/ptdump-no-offset.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2016-2022, Intel Corporation +; Copyright (c) 2016-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/ptdump-trunc-resync.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/ptdump-trunc-resync.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2018-2022, Intel Corporation +; Copyright (c) 2018-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.1.tar.gz/test/src/ptet-evd_cr2-cfe_iret.ptt
Added
@@ -0,0 +1,60 @@ +; Copyright (c) 2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; +; * Redistributions of source code must retain the above copyright notice, +; this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright notice, +; this list of conditions and the following disclaimer in the documentation +; and/or other materials provided with the distribution. +; * Neither the name of Intel Corporation nor the names of its contributors +; may be used to endorse or promote products derived from this software +; without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; POSSIBILITY OF SUCH DAMAGE. + +; Test that an unexpected EVD is diagnosed at CFE +; +; Variant: EVD.CR2 followed by CFE.IRET +; + +org 0x100000 +bits 64 + +; @pt p0: psb() +; @pt p1: fup(3: %l0) +; @pt p2: mode.exec(64bit, if) +; @pt p3: psbend() +l0: hlt + +; @pt p4: evd(0: 0xf00) +; @pt p5: cfe(2) +; @pt p6: fup(1: %l0) +; @pt p7: tip.pgd(0: %l0) + + +; @pt .exp(ptdump) +;%0p0 psb +;%0p1 fup 3: %0l0 +;%0p2 mode.exec cs.l, if +;%0p3 psbend +;%0p4 evd 0: f00 +;%0p5 cfe 2 +;%0p6 fup 1: %?l0.2 +;%0p7 tip.pgd 0: %?l0.0 + + +; @pt .exp(ptxed) +;%p5, 0: error: unexpected packet context
View file
_service:tar_scm:v2.1.tar.gz/test/src/ptet-evd_cr2-evd_vmxq.ptt
Added
@@ -0,0 +1,62 @@ +; Copyright (c) 2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; +; * Redistributions of source code must retain the above copyright notice, +; this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright notice, +; this list of conditions and the following disclaimer in the documentation +; and/or other materials provided with the distribution. +; * Neither the name of Intel Corporation nor the names of its contributors +; may be used to endorse or promote products derived from this software +; without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; POSSIBILITY OF SUCH DAMAGE. + +; Test that an unexpected EVD is diagnosed at EVD +; +; Variant: EVD.CR2 followed by EVD.VMXQ +; + +org 0x100000 +bits 64 + +; @pt p0: psb() +; @pt p1: fup(3: %l0) +; @pt p2: mode.exec(64bit, if) +; @pt p3: psbend() +l0: hlt + +; @pt p4: evd(0: 0xf00) +; @pt p5: evd(1: 0) +; @pt p6: cfe(2) +; @pt p7: fup(1: %l0) +; @pt p8: tip.pgd(0: %l0) + + +; @pt .exp(ptdump) +;%0p0 psb +;%0p1 fup 3: %0l0 +;%0p2 mode.exec cs.l, if +;%0p3 psbend +;%0p4 evd 0: f00 +;%0p5 evd 1: 0 +;%0p6 cfe 2 +;%0p7 fup 1: %?l0.2 +;%0p8 tip.pgd 0: %?l0.0 + + +; @pt .exp(ptxed) +;%p5, 0: error: unexpected packet context
View file
_service:tar_scm:v2.1.tar.gz/test/src/ptet-evd_vmxq-cfe_intr.ptt
Added
@@ -0,0 +1,60 @@ +; Copyright (c) 2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; +; * Redistributions of source code must retain the above copyright notice, +; this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright notice, +; this list of conditions and the following disclaimer in the documentation +; and/or other materials provided with the distribution. +; * Neither the name of Intel Corporation nor the names of its contributors +; may be used to endorse or promote products derived from this software +; without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; POSSIBILITY OF SUCH DAMAGE. + +; Test that an unexpected EVD is diagnosed at CFE +; +; Variant: EVD.VMXQ followed by CFE.INTR +; + +org 0x100000 +bits 64 + +; @pt p0: psb() +; @pt p1: fup(3: %l0) +; @pt p2: mode.exec(64bit, if) +; @pt p3: psbend() +l0: hlt + +; @pt p4: evd(1: 0) +; @pt p5: cfe(1: 14) +; @pt p6: fup(1: %l0) +; @pt p7: tip.pgd(0: %l0) + + +; @pt .exp(ptdump) +;%0p0 psb +;%0p1 fup 3: %0l0 +;%0p2 mode.exec cs.l, if +;%0p3 psbend +;%0p4 evd 1: 0 +;%0p5 cfe 1: 14 +;%0p6 fup 1: %?l0.2 +;%0p7 tip.pgd 0: %?l0.0 + + +; @pt .exp(ptxed) +;%p5, 0: error: unexpected packet context
View file
_service:tar_scm:v2.1.tar.gz/test/src/ptet-evd_vmxr-cfe_rsm.ptt
Added
@@ -0,0 +1,60 @@ +; Copyright (c) 2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; +; * Redistributions of source code must retain the above copyright notice, +; this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright notice, +; this list of conditions and the following disclaimer in the documentation +; and/or other materials provided with the distribution. +; * Neither the name of Intel Corporation nor the names of its contributors +; may be used to endorse or promote products derived from this software +; without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; POSSIBILITY OF SUCH DAMAGE. + +; Test that an unexpected EVD is diagnosed at CFE +; +; Variant: EVD.VMXR followed by CFE.RSM +; + +org 0x100000 +bits 64 + +; @pt p0: psb() +; @pt p1: fup(3: %l0) +; @pt p2: mode.exec(64bit, if) +; @pt p3: psbend() +l0: hlt + +; @pt p4: evd(2: 0) +; @pt p5: cfe(4) +; @pt p6: fup(1: %l0) +; @pt p7: tip.pgd(0: %l0) + + +; @pt .exp(ptdump) +;%0p0 psb +;%0p1 fup 3: %0l0 +;%0p2 mode.exec cs.l, if +;%0p3 psbend +;%0p4 evd 2: 0 +;%0p5 cfe 4 +;%0p6 fup 1: %?l0.2 +;%0p7 tip.pgd 0: %?l0.0 + + +; @pt .exp(ptxed) +;%p5, 0: error: unexpected packet context
View file
_service:tar_scm:v2.1.tar.gz/test/src/ptet-evd_vmxr-evd-cr2.ptt
Added
@@ -0,0 +1,62 @@ +; Copyright (c) 2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; +; * Redistributions of source code must retain the above copyright notice, +; this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright notice, +; this list of conditions and the following disclaimer in the documentation +; and/or other materials provided with the distribution. +; * Neither the name of Intel Corporation nor the names of its contributors +; may be used to endorse or promote products derived from this software +; without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; POSSIBILITY OF SUCH DAMAGE. + +; Test that an unexpected EVD is diagnosed at EVD +; +; Variant: EVD.VMXR followed by EVD.CR2 +; + +org 0x100000 +bits 64 + +; @pt p0: psb() +; @pt p1: fup(3: %l0) +; @pt p2: mode.exec(64bit, if) +; @pt p3: psbend() +l0: hlt + +; @pt p4: evd(2: 0) +; @pt p5: evd(0: 0xf00) +; @pt p6: cfe(8) +; @pt p7: fup(1: %l0) +; @pt p8: tip.pgd(0: %l0) + + +; @pt .exp(ptdump) +;%0p0 psb +;%0p1 fup 3: %0l0 +;%0p2 mode.exec cs.l, if +;%0p3 psbend +;%0p4 evd 2: 0 +;%0p5 evd 0: f00 +;%0p6 cfe 8 +;%0p7 fup 1: %?l0.2 +;%0p8 tip.pgd 0: %?l0.0 + + +; @pt .exp(ptxed) +;%p5, 0: error: unexpected packet context
View file
_service:tar_scm:v2.1.tar.gz/test/src/ptet-init-sipi.ptt
Added
@@ -0,0 +1,76 @@ +; Copyright (c) 2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; +; * Redistributions of source code must retain the above copyright notice, +; this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright notice, +; this list of conditions and the following disclaimer in the documentation +; and/or other materials provided with the distribution. +; * Neither the name of Intel Corporation nor the names of its contributors +; may be used to endorse or promote products derived from this software +; without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; POSSIBILITY OF SUCH DAMAGE. + +; Test that an INIT followed by SIPI are decoded correctly. +; +; Variant: event tracing enabled +; + +org 0x100000 +bits 64 +; @pt p0: psb() +; @pt p1: fup(3: %l0) +; @pt p2: mode.exec(64bit, if) +; @pt p3: psbend() +l0: nop + +; @pt p4: cfe(6) +; @pt p5: fup(1: %l1) +; @pt p6: tip.pgd(0: %l1) +l1: nop + +; @pt p7: cfe(5: 0xce) +; @pt p8: tip.pge(3: %l2) +l2: nop + +; @pt p9: fup(1: %l3) +; @pt p10: tip.pgd(0: %l3) +l3: hlt + + +; @pt .exp(ptdump) +;%0p0 psb +;%0p1 fup 3: %0l0 +;%0p2 mode.exec cs.l, if +;%0p3 psbend +;%0p4 cfe 6 +;%0p5 fup 1: %?l1.2 +;%0p6 tip.pgd 0: %?l1.0 +;%0p7 cfe 5: ce +;%0p8 tip.pge 3: %?l2 +;%0p9 fup 1: %?l3.2 +;%0p10 tip.pgd 0: %?l3.0 + + +; @pt .exp(ptxed) +;%0l0 # nop +;init +;disabled +;sipi: ce +;enabled +;%0l2 # nop +;disabled
View file
_service:tar_scm:v2.1.tar.gz/test/src/ptet-int-iret-cpl_0.ptt
Added
@@ -0,0 +1,93 @@ +; Copyright (c) 2022-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; +; * Redistributions of source code must retain the above copyright notice, +; this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright notice, +; this list of conditions and the following disclaimer in the documentation +; and/or other materials provided with the distribution. +; * Neither the name of Intel Corporation nor the names of its contributors +; may be used to endorse or promote products derived from this software +; without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; POSSIBILITY OF SUCH DAMAGE. + +; Test that an INT followed by an IRET are decoded correctly. +; +; Variant: event tracing enabled, cpl-0 tracing +; + +org 0x100000 +bits 64 + +; @pt p0: psb() +; @pt p2: mode.exec(64bit, if) +; @pt p3: psbend() +l0: nop + +; @pt p4: evd(0: 0xf00baa) +; @pt p5: cfe(1: 14) +; @pt p6: tip.pge(3: %l5) +; ... +; @pt p7: cfe(2, ip) +; @pt p8: fup(1: %l5) +; @pt p9: tip.pgd(0: %l1) +l1: mov rax, rbx + +; @pt p10: cfe(1: 0x80) +; @pt p11: tip.pge(3: %l7) +; ... +; @pt p12: cfe(2, ip) +; @pt p13: fup(1: %l7) +; @pt p14: tip.pgd(0: %l3) +l2: int 0x80 +l3: nop + +l5: iret +l6: hlt + +l7: iret +l8: hlt + + +; @pt .exp(ptdump) +;%0p0 psb +;%0p2 mode.exec cs.l, if +;%0p3 psbend +;%0p4 evd 0: f00baa +;%0p5 cfe 1: 14 +;%0p6 tip.pge 3: %?l5 +;%0p7 cfe 2, ip +;%0p8 fup 1: %?l5.2 +;%0p9 tip.pgd 0: %?l1.0 +;%0p10 cfe 1: 128 +;%0p11 tip.pge 3: %?l7 +;%0p12 cfe 2, ip +;%0p13 fup 1: %?l7.2 +;%0p14 tip.pgd 0: %?l3.0 + + +; @pt .exp(ptxed) +;interrupt 14, cr2: 0000000000f00baa # mov rax, rbx +;enabled +;%0l5 # iret +;iret +;disabled +;interrupt 128 # int 0x80 +;enabled +;%0l7 # iret +;iret +;disabled
View file
_service:tar_scm:v2.1.tar.gz/test/src/ptet-int-iret-cpl_3.ptt
Added
@@ -0,0 +1,96 @@ +; Copyright (c) 2022-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; +; * Redistributions of source code must retain the above copyright notice, +; this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright notice, +; this list of conditions and the following disclaimer in the documentation +; and/or other materials provided with the distribution. +; * Neither the name of Intel Corporation nor the names of its contributors +; may be used to endorse or promote products derived from this software +; without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; POSSIBILITY OF SUCH DAMAGE. + +; Test that an INT followed by an IRET are decoded correctly. +; +; Variant: event tracing enabled, cpl-3 tracing +; + +org 0x100000 +bits 64 +; @pt p0: psb() +; @pt p1: fup(3: %l0) +; @pt p2: mode.exec(64bit, if) +; @pt p3: psbend() +l0: nop + +; @pt p4: evd(0: 0xf00baa) +; @pt p5: cfe(1: 14) +; @pt p6: fup(1: %l1) +; @pt p7: tip.pgd(0: %l1) +; ... +; @pt p8: cfe(2) +; @pt p9: tip.pge(3: %l1) +l1: mov rax, rbx + +; @pt p10: cfe(1: 0x80) +; @pt p11: fup(1: %l2) +; @pt p12: tip.pgd(0: %l2) +; ... +; @pt p13: cfe(2) +; @pt p14: tip.pge(3: %l3) +l2: int 0x80 +l3: nop + +; @pt p15: fup(1: %l4) +; @pt p16: tip.pgd(0: %l4) +l4: hlt + + +; @pt .exp(ptdump) +;%0p0 psb +;%0p1 fup 3: %0l0 +;%0p2 mode.exec cs.l, if +;%0p3 psbend +;%0p4 evd 0: f00baa +;%0p5 cfe 1: 14 +;%0p6 fup 1: %?l1.2 +;%0p7 tip.pgd 0: %?l1.0 +;%0p8 cfe 2 +;%0p9 tip.pge 3: %?l1 +;%0p10 cfe 1: 128 +;%0p11 fup 1: %?l2.2 +;%0p12 tip.pgd 0: %?l2.0 +;%0p13 cfe 2 +;%0p14 tip.pge 3: %?l3 +;%0p15 fup 1: %?l4.2 +;%0p16 tip.pgd 0: %?l4.0 + + +; @pt .exp(ptxed) +;%0l0 # nop +;interrupt 14, cr2: 0000000000f00baa # mov rax, rbx +;disabled +;iret +;resumed +;%0l1 # mov rax, rbx +;interrupt 128 # int 0x80 +;disabled +;iret +;enabled +;%0l3 # nop +;disabled
View file
_service:tar_scm:v2.1.tar.gz/test/src/ptet-int-iret.ptt
Added
@@ -0,0 +1,104 @@ +; Copyright (c) 2022-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; +; * Redistributions of source code must retain the above copyright notice, +; this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright notice, +; this list of conditions and the following disclaimer in the documentation +; and/or other materials provided with the distribution. +; * Neither the name of Intel Corporation nor the names of its contributors +; may be used to endorse or promote products derived from this software +; without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; POSSIBILITY OF SUCH DAMAGE. + +; Test that an INT followed by an IRET are decoded correctly. +; +; Variant: event tracing enabled +; test that CVE.IRET could be bound to the IRET instruction (artificial) +; + +org 0x100000 +bits 64 + +; @pt p0: psb() +; @pt p1: fup(3: %l0) +; @pt p2: mode.exec(64bit, if) +; @pt p3: psbend() +l0: nop + +; @pt p4: evd(0: 0xf00baa) +; @pt p5: cfe(1: 14) +; @pt p6: fup(1: %l1) +; @pt p7: tip(3: %l5) +; ... +; @pt p8: cfe(2) +; @pt p9: tip(3: %l1) +l1: mov rax, rbx + +; @pt p10: cfe(1: 0x80) +; @pt p11: fup(1: %l2) +; @pt p12: tip(3: %l7) +; ... +; @pt p13: cfe(2) +; @pt p14: tip(3: %l3) +l2: int 0x80 +l3: nop + +; @pt p15: fup(1: %l4) +; @pt p16: tip.pgd(0: %l4) +l4: hlt + +l5: iret +l6: hlt + +l7: iret +l8: hlt + + +; @pt .exp(ptdump) +;%0p0 psb +;%0p1 fup 3: %0l0 +;%0p2 mode.exec cs.l, if +;%0p3 psbend +;%0p4 evd 0: f00baa +;%0p5 cfe 1: 14 +;%0p6 fup 1: %?l1.2 +;%0p7 tip 3: %?l5 +;%0p8 cfe 2 +;%0p9 tip 3: %?l1 +;%0p10 cfe 1: 128 +;%0p11 fup 1: %?l2.2 +;%0p12 tip 3: %?l7 +;%0p13 cfe 2 +;%0p14 tip 3: %?l3 +;%0p15 fup 1: %?l4.2 +;%0p16 tip.pgd 0: %?l4.0 + + +; @pt .exp(ptxed) +;%0l0 # nop +;interrupt 14, cr2: 0000000000f00baa # mov rax, rbx +;interrupt +;%0l5 +;iret +;%0l1 # mov rax, rbx +;interrupt 128 # int 0x80 +;interrupt +;%0l7 +;iret +;%0l3 # nop +;disabled
View file
_service:tar_scm:v2.1.tar.gz/test/src/ptet-mode_exec-if.ptt
Added
@@ -0,0 +1,80 @@ +; Copyright (c) 2022-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; +; * Redistributions of source code must retain the above copyright notice, +; this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright notice, +; this list of conditions and the following disclaimer in the documentation +; and/or other materials provided with the distribution. +; * Neither the name of Intel Corporation nor the names of its contributors +; may be used to endorse or promote products derived from this software +; without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; POSSIBILITY OF SUCH DAMAGE. + +; Test MODE.EXEC for IF tracing. +; +; opt:ptxed --event:iflags +; + +org 0x1000 +bits 64 + +; @pt p0: psb() +; @pt p1: psbend() + +; @pt p2: mode.exec(64bit) +; @pt p3: tip.pge(3: %l0) +l0: nop + +; @pt p4: mode.exec(64bit, if) +; @pt p5: fup(1: %l2) +l1: sti +l2: nop + +; @pt p6: mode.exec(64bit) +; @pt p7: fup(1: %l4) +l3: cli + +; @pt p8:fup(1: %l4) +; @pt p9:tip.pgd(0: %l4) +l4: hlt + + +; @pt .exp(ptdump) +;%0p0 psb +;%0p1 psbend +;%0p2 mode.exec cs.l +;%0p3 tip.pge 3: %?l0 +;%0p4 mode.exec cs.l, if +;%0p5 fup 1: %?l2.2 +;%0p6 mode.exec cs.l +;%0p7 fup 1: %?l4.2 +;%0p8 fup 1: %?l4.2 +;%0p9 tip.pgd 0: %?l4.0 + + +; @pt .exp(ptxed) +;enabled +;exec mode: 64-bit +;interrupts disabled +;%0l0 # nop +;%0l1 # sti +;interrupts enabled +;%0l2 # nop +;%0l3 # cli +;interrupts disabled +;disabled
View file
_service:tar_scm:v2.1.tar.gz/test/src/ptet-mode_exec-spurious.ptt
Added
@@ -0,0 +1,82 @@ +; Copyright (c) 2022-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; +; * Redistributions of source code must retain the above copyright notice, +; this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright notice, +; this list of conditions and the following disclaimer in the documentation +; and/or other materials provided with the distribution. +; * Neither the name of Intel Corporation nor the names of its contributors +; may be used to endorse or promote products derived from this software +; without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; POSSIBILITY OF SUCH DAMAGE. + +; Test spurious MODE.EXEC. +; +; This is an artificial test to ensure that no event decode internal +; events escape to libipt users. +; +; opt:ptxed --event:iflags +; + +org 0x1000 +bits 64 + +; @pt p0: psb() +; @pt p1: mode.exec(64bit) +; @pt p2: psbend() + +; @pt p3: mode.exec(64bit) +; @pt p4: tip.pge(3: %l0) +l0: nop + +; @pt p5: mode.exec(64bit) +; @pt p6: fup(1: %l2) +l1: nop +l2: call rax +l3: hlt + +; @pt p7: mode.exec(64bit) +; @pt p8: tip(1: %l4) +l4: nop + +; @pt p9:fup(1: %l5) +; @pt p10:tip.pgd(0: %l5) +l5: hlt + + +; @pt .exp(ptdump) +;%0p0 psb +;%0p1 mode.exec cs.l +;%0p2 psbend +;%0p3 mode.exec cs.l +;%0p4 tip.pge 3: %?l0 +;%0p5 mode.exec cs.l +;%0p6 fup 1: %?l2.2 +;%0p7 mode.exec cs.l +;%0p8 tip 1: %?l4.2 +;%0p9 fup 1: %?l5.2 +;%0p10 tip.pgd 0: %?l5.0 + + +; @pt .exp(ptxed) +;enabled +;%0l0 # nop +;%0l1 # nop +;%0l2 # call rax +;%0l4 # nop +;disabled
View file
_service:tar_scm:v2.1.tar.gz/test/src/ptet-smi-rsm.ptt
Added
@@ -0,0 +1,75 @@ +; Copyright (c) 2022-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; +; * Redistributions of source code must retain the above copyright notice, +; this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright notice, +; this list of conditions and the following disclaimer in the documentation +; and/or other materials provided with the distribution. +; * Neither the name of Intel Corporation nor the names of its contributors +; may be used to endorse or promote products derived from this software +; without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; POSSIBILITY OF SUCH DAMAGE. + +; Test that an SMI followed by an RSM are decoded correctly. +; +; Variant: event tracing enabled +; + +org 0x100000 +bits 64 +; @pt p0: psb() +; @pt p1: fup(3: %l0) +; @pt p2: mode.exec(64bit, if) +; @pt p3: psbend() +l0: nop + +; @pt p4: cfe(3) +; @pt p5: fup(1: %l1) +; @pt p6: tip.pgd(0: %l1) +; ... +; @pt p7: cfe(4) +; @pt p8: tip.pge(3: %l1) +l1: nop + +; @pt p9: fup(1: %l2) +; @pt p10: tip.pgd(0: %l2) +l2: hlt + + +; @pt .exp(ptdump) +;%0p0 psb +;%0p1 fup 3: %0l0 +;%0p2 mode.exec cs.l, if +;%0p3 psbend +;%0p4 cfe 3 +;%0p5 fup 1: %?l1.2 +;%0p6 tip.pgd 0: %?l1.0 +;%0p7 cfe 4 +;%0p8 tip.pge 3: %?l1 +;%0p9 fup 1: %?l2.2 +;%0p10 tip.pgd 0: %?l2.0 + + +; @pt .exp(ptxed) +;%0l0 # nop +;smi +;disabled +;rsm +;resumed +;%0l1 # nop +;disabled
View file
_service:tar_scm:v2.1.tar.gz/test/src/ptet-uint-uiret.ptt
Added
@@ -0,0 +1,104 @@ +; Copyright (c) 2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; +; * Redistributions of source code must retain the above copyright notice, +; this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright notice, +; this list of conditions and the following disclaimer in the documentation +; and/or other materials provided with the distribution. +; * Neither the name of Intel Corporation nor the names of its contributors +; may be used to endorse or promote products derived from this software +; without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; POSSIBILITY OF SUCH DAMAGE. + +; Test that an UINTR followed by an UIRET are decoded correctly. +; +; Variant: event tracing enabled +; CVE.UIRET can be bound to UIRET (artificial) +; + +org 0x100000 +bits 64 + +; @pt p0: psb() +; @pt p1: fup(3: %l0) +; @pt p2: mode.exec(64bit, if) +; @pt p3: psbend() +l0: nop + +; @pt p4: cfe(12: 4) +; @pt p5: fup(1: %l1) +; @pt p6: tip(3: %l5) +; ... +; @pt p7: cfe(13, ip) +; @pt p8: fup(1: %l5) +; @pt p9: tip(3: %l1) +l1: nop + +; @pt p10: cfe(12: 5) +; @pt p11: fup(1: %l2) +; @pt p12: tip(3: %l7) +; ... +; @pt p13: cfe(13) +; @pt p14: tip(3: %l3) +l2: nop +l3: nop + +; @pt p15: fup(1: %l4) +; @pt p16: tip.pgd(0: %l4) +l4: hlt + +l5: dd 0xec010ff3; uiret +l6: hlt + +l7: dd 0xec010ff3; uiret +l8: hlt + + +; @pt .exp(ptdump) +;%0p0 psb +;%0p1 fup 3: %0l0 +;%0p2 mode.exec cs.l, if +;%0p3 psbend +;%0p4 cfe 12: 4 +;%0p5 fup 1: %?l1.2 +;%0p6 tip 3: %?l5 +;%0p7 cfe 13, ip +;%0p8 fup 1: %?l5.2 +;%0p9 tip 3: %?l1 +;%0p10 cfe 12: 5 +;%0p11 fup 1: %?l2.2 +;%0p12 tip 3: %?l7 +;%0p13 cfe 13 +;%0p14 tip 3: %?l3 +;%0p15 fup 1: %?l4.2 +;%0p16 tip.pgd 0: %?l4.0 + + +; @pt .exp(ptxed) +;%0l0 +;uintr 4 +;interrupt +;%0l5 +;uiret +;%0l1 +;uintr 5 +;interrupt +;%0l7 +;uiret +;%0l3 +;disabled
View file
_service:tar_scm:v2.1.tar.gz/test/src/ptet-vmexit-vmentry-nonroot.ptt
Added
@@ -0,0 +1,108 @@ +; Copyright (c) 2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; +; * Redistributions of source code must retain the above copyright notice, +; this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright notice, +; this list of conditions and the following disclaimer in the documentation +; and/or other materials provided with the distribution. +; * Neither the name of Intel Corporation nor the names of its contributors +; may be used to endorse or promote products derived from this software +; without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; POSSIBILITY OF SUCH DAMAGE. + +; Test that a VMexit followed by a VMentry are decoded correctly. +; +; Variant: event tracing enabled +; tracing non-root +; + +org 0x100000 +bits 64 + +; @pt p0: psb() +; @pt p1: fup(3: %l0) +; @pt p2: mode.exec(64bit, if) +; @pt p3: psbend() +l0: nop + +; @pt p4: evd(1: 0xf00baa) +; @pt p5: evd(2: 0) +; @pt p6: cfe(9: 14) +; @pt p7: fup(1: %l1) +; @pt p8: tip.pgd(0: %l5) +; ... +; @pt p9: cfe(7) +; @pt p10: tip.pge(3: %l1) +l1: mov rax, rbx + +; @pt p11: evd(2: 10) +; @pt p12: cfe(8) +; @pt p13: fup(1: %l2) +; @pt p14: tip.pgd(0: %l7) +; ... +; @pt p15: cfe(7) +; @pt p16: tip.pge(3: %l3) +l2: cpuid +l3: nop + +; @pt p17: fup(1: %l4) +; @pt p18: tip.pgd(0: %l4) +l4: hlt + +l5: vmresume +l6: hlt + +l7: vmresume +l8: hlt + + +; @pt .exp(ptdump) +;%0p0 psb +;%0p1 fup 3: %0l0 +;%0p2 mode.exec cs.l, if +;%0p3 psbend +;%0p4 evd 1: f00baa +;%0p5 evd 2: 0 +;%0p6 cfe 9: 14 +;%0p7 fup 1: %?l1.2 +;%0p8 tip.pgd 0: %?l5.0 +;%0p9 cfe 7 +;%0p10 tip.pge 3: %?l1 +;%0p11 evd 2: a +;%0p12 cfe 8 +;%0p13 fup 1: %?l2.2 +;%0p14 tip.pgd 0: %?l7.0 +;%0p15 cfe 7 +;%0p16 tip.pge 3: %?l3 +;%0p17 fup 1: %?l4.2 +;%0p18 tip.pgd 0: %?l4.0 + + +; @pt .exp(ptxed) +;%0l0 +;vmexit, intr: 14, vmxr: 0000000000000000, vmxq: 0000000000f00baa +;disabled +;vmentry +;resumed +;%0l1 +;vmexit, vmxr: 000000000000000a +;disabled +;vmentry +;enabled +;%0l3 +;disabled
View file
_service:tar_scm:v2.1.tar.gz/test/src/ptet-vmexit-vmentry-root.ptt
Added
@@ -0,0 +1,88 @@ +; Copyright (c) 2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; +; * Redistributions of source code must retain the above copyright notice, +; this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright notice, +; this list of conditions and the following disclaimer in the documentation +; and/or other materials provided with the distribution. +; * Neither the name of Intel Corporation nor the names of its contributors +; may be used to endorse or promote products derived from this software +; without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; POSSIBILITY OF SUCH DAMAGE. + +; Test that a VMexit followed by a VMentry are decoded correctly. +; +; Variant: event tracing enabled +; tracing root +; + +org 0x100000 +bits 64 + +; @pt p0: psb() +; @pt p2: mode.exec(64bit, if) +; @pt p3: psbend() + +; @pt p4: evd(1: 0xf00baa) +; @pt p5: evd(2: 0) +; @pt p6: cfe(9: 14) +; @pt p8: tip.pge(3: %l5) +; ... +; @pt p9: cfe(7) +; @pt p10: tip.pgd(0: %l1) +l1: mov rax, rbx + +; @pt p14: tip.pge(3: %l7) +; ... +; @pt p15: cfe(7) +; @pt p16: tip.pgd(0: %l3) +l2: cpuid +l3: nop + +l5: vmresume +l6: hlt + +l7: vmresume +l8: hlt + + +; @pt .exp(ptdump) +;%0p0 psb +;%0p2 mode.exec cs.l, if +;%0p3 psbend +;%0p4 evd 1: f00baa +;%0p5 evd 2: 0 +;%0p6 cfe 9: 14 +;%0p8 tip.pge 3: %?l5 +;%0p9 cfe 7 +;%0p10 tip.pgd 0: %?l1.0 +;%0p14 tip.pge 3: %?l7 +;%0p15 cfe 7 +;%0p16 tip.pgd 0: %?l3.0 + + +; @pt .exp(ptxed) +;vmexit, intr: 14, vmxr: 0000000000000000, vmxq: 0000000000f00baa +;enabled +;%0l5 +;vmentry +;disabled +;enabled +;%0l7 +;vmentry +;disabled
View file
_service:tar_scm:v2.1.tar.gz/test/src/ptet-vmexit-vmentry.ptt
Added
@@ -0,0 +1,107 @@ +; Copyright (c) 2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; +; * Redistributions of source code must retain the above copyright notice, +; this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright notice, +; this list of conditions and the following disclaimer in the documentation +; and/or other materials provided with the distribution. +; * Neither the name of Intel Corporation nor the names of its contributors +; may be used to endorse or promote products derived from this software +; without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; POSSIBILITY OF SUCH DAMAGE. + +; Test that a VMexit followed by a VMentry are decoded correctly. +; +; Variant: event tracing enabled +; + +org 0x100000 +bits 64 + +; @pt p0: psb() +; @pt p1: fup(3: %l0) +; @pt p2: mode.exec(64bit, if) +; @pt p3: psbend() +l0: nop + +; @pt p4: evd(1: 0xf00baa) +; @pt p5: evd(2: 0) +; @pt p6: cfe(9: 14) +; @pt p7: fup(1: %l1) +; @pt p8: tip(3: %l5) +; ... +; @pt p9: cfe(7) +; @pt p10: tip(3: %l1) +l1: mov rax, rbx + +; @pt p11: evd(2: 10) +; @pt p12: cfe(8) +; @pt p13: fup(1: %l2) +; @pt p14: tip(3: %l7) +; ... +; @pt p15: cfe(7) +; @pt p16: tip(3: %l3) +l2: cpuid +l3: nop + +; @pt p17: fup(1: %l4) +; @pt p18: tip.pgd(0: %l4) +l4: hlt + +l5: vmresume +l6: hlt + +l7: vmresume +l8: hlt + + +; @pt .exp(ptdump) +;%0p0 psb +;%0p1 fup 3: %0l0 +;%0p2 mode.exec cs.l, if +;%0p3 psbend +;%0p4 evd 1: f00baa +;%0p5 evd 2: 0 +;%0p6 cfe 9: 14 +;%0p7 fup 1: %?l1.2 +;%0p8 tip 3: %?l5 +;%0p9 cfe 7 +;%0p10 tip 3: %?l1 +;%0p11 evd 2: a +;%0p12 cfe 8 +;%0p13 fup 1: %?l2.2 +;%0p14 tip 3: %?l7 +;%0p15 cfe 7 +;%0p16 tip 3: %?l3 +;%0p17 fup 1: %?l4.2 +;%0p18 tip.pgd 0: %?l4.0 + + +; @pt .exp(ptxed) +;%0l0 +;vmexit, intr: 14, vmxr: 0000000000000000, vmxq: 0000000000f00baa +;interrupt +;%0l5 +;vmentry +;%0l1 +;vmexit, vmxr: 000000000000000a +;interrupt +;%0l7 +;vmentry +;%0l3 +;disabled
View file
_service:tar_scm:v2.1.tar.gz/test/src/ptet.ptt
Added
@@ -0,0 +1,179 @@ +; Copyright (c) 2022-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; +; * Redistributions of source code must retain the above copyright notice, +; this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright notice, +; this list of conditions and the following disclaimer in the documentation +; and/or other materials provided with the distribution. +; * Neither the name of Intel Corporation nor the names of its contributors +; may be used to endorse or promote products derived from this software +; without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; POSSIBILITY OF SUCH DAMAGE. + +; Test Event Tracing with BranchEn=0 +; +; We do not stick to a fixed context. The trace contains in-context +; packets as well as context-transition packets in both directions. +; +; opt:ptxed --event:iflags --event:ip +; + +org 0x100000 +bits 64 + +; @pt p0: psb() +; @pt p1: mode.exec(64bit, if) +; @pt p2: psbend() +; @pt p3: mode.exec(32bit) +; @pt p4: fup(3: %l0) +l0: nop +; @pt p5: mode.exec(64bit, if) +; @pt p6: fup(1: %l1) +l1: nop +; @pt p7: evd(0: 0xf00baa) +; @pt p8: cfe(1: 14, ip) +; @pt p9: fup(1: %l2) +l2: nop +; @pt p10: cfe(2) +; @pt p11: cfe(1: 0x80) +; @pt p12: cfe(2, ip) +; @pt p13: fup(1: %l3) +l3: nop +; @pt p14: cfe(3, ip) +; @pt p15: fup(1: %l4) +l4: nop +; @pt p16: cfe(4) +; @pt p17: cfe(6, ip) +; @pt p18: fup(1: %l5) +l5: nop +; @pt p19: cfe(5: 0xce) +; @pt p20: evd(1: 0xf00baa) +; @pt p21: evd(2: 0) +; @pt p22: cfe(9: 14, ip) +; @pt p23: fup(1: %l6) +l6: nop +; @pt p24: cfe(7, ip) +; @pt p25: fup(1: %l6) +; @pt p26: evd(2: 10) +; @pt p27: cfe(8, ip) +; @pt p28: fup(1: %l7) +l7: nop +; @pt p29: cfe(7, ip) +; @pt p30: fup(1: %l8) +l8: nop +; @pt p31: cfe(10, ip) +; @pt p32: fup(1: %l9) +l9: nop +; @pt p33: cfe(12: 4, ip) +; @pt p34: fup(1: %l10) +l10: nop +; @pt p35: cfe(13, ip) +; @pt p36: fup(1: %l11) +l11: nop +; @pt p37: evd(31: 0) +; @pt p38: cfe(1: 128, ip) +; @pt p39: fup(1: %l12) +l12: nop +; @pt p40: evd(31: 0) +; @pt p41: evd(1: 0xf00) +; @pt p42: evd(31: 0) +; @pt p43: evd(2: 0xbaa) +; @pt p44: evd(31: 0) +; @pt p45: cfe(9: 14, ip) +; @pt p46: fup(1: %l13) +l13: nop +; @pt p47: cfe(31, ip) +; @pt p48: fup(1: %l14) +l14: nop +; @pt p49: cfe(31) + +; @pt .exp(ptdump) +;%0p0 psb +;%0p1 mode.exec cs.l, if +;%0p2 psbend +;%0p3 mode.exec cs.d +;%0p4 fup 3: %?l0 +;%0p5 mode.exec cs.l, if +;%0p6 fup 1: %?l1.2 +;%0p7 evd 0: f00baa +;%0p8 cfe 1: 14, ip +;%0p9 fup 1: %?l2.2 +;%0p10 cfe 2 +;%0p11 cfe 1: 128 +;%0p12 cfe 2, ip +;%0p13 fup 1: %?l3.2 +;%0p14 cfe 3, ip +;%0p15 fup 1: %?l4.2 +;%0p16 cfe 4 +;%0p17 cfe 6, ip +;%0p18 fup 1: %?l5.2 +;%0p19 cfe 5: ce +;%0p20 evd 1: f00baa +;%0p21 evd 2: 0 +;%0p22 cfe 9: 14, ip +;%0p23 fup 1: %?l6.2 +;%0p24 cfe 7, ip +;%0p25 fup 1: %?l6.2 +;%0p26 evd 2: a +;%0p27 cfe 8, ip +;%0p28 fup 1: %?l7.2 +;%0p29 cfe 7, ip +;%0p30 fup 1: %?l8.2 +;%0p31 cfe 10, ip +;%0p32 fup 1: %?l9.2 +;%0p33 cfe 12: 4, ip +;%0p34 fup 1: %?l10.2 +;%0p35 cfe 13, ip +;%0p36 fup 1: %?l11.2 +;%0p37 evd 31: 0 +;%0p38 cfe 1: 128, ip +;%0p39 fup 1: %?l12.2 +;%0p40 evd 31: 0 +;%0p41 evd 1: f00 +;%0p42 evd 31: 0 +;%0p43 evd 2: baa +;%0p44 evd 31: 0 +;%0p45 cfe 9: 14, ip +;%0p46 fup 1: %?l13.2 +;%0p47 cfe 31, ip +;%0p48 fup 1: %?l14.2 +;%0p49 cfe 31 + + +; @pt .exp(ptxed) +;exec mode: 32-bit, ip: %0l0 +;interrupts disabled, ip: %0l0 +;exec mode: 64-bit, ip: %0l1 +;interrupts enabled, ip: %0l1 +;interrupt 14, cr2: 0000000000f00baa, ip: %0l2 +;iret +;interrupt 128 +;iret, ip: %0l3 +;smi, ip: %0l4 +;rsm +;init, ip: %0l5 +;sipi: ce +;vmexit, intr: 14, vmxr: 0000000000000000, vmxq: 0000000000f00baa, ip: %0l6 +;vmentry, ip: %0l6 +;vmexit, vmxr: 000000000000000a, ip: %0l7 +;vmentry, ip: %0l8 +;shutdown, ip: %0l9 +;uintr 4, ip: %0l10 +;uiret, ip: %0l11 +;interrupt 128, ip: %0l12 +;vmexit, intr: 14, vmxr: 0000000000000baa, vmxq: 0000000000000f00, ip: %0l13
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/ptw-fup.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/ptw-fup.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2015-2022, Intel Corporation +; Copyright (c) 2015-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/ptw.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/ptw.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2015-2022, Intel Corporation +; Copyright (c) 2015-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/ptxed-block-stat.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/ptxed-block-stat.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2016-2022, Intel Corporation +; Copyright (c) 2016-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/ptxed-block-stat_blocks.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/ptxed-block-stat_blocks.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2016-2022, Intel Corporation +; Copyright (c) 2016-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/ptxed-end_on_call-fup-tip.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/ptxed-end_on_call-fup-tip.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2017-2022, Intel Corporation +; Copyright (c) 2017-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/ptxed-end_on_call-fup-tip_pgd.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/ptxed-end_on_call-fup-tip_pgd.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2016-2022, Intel Corporation +; Copyright (c) 2016-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/ptxed-end_on_call-ret_tip.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/ptxed-end_on_call-ret_tip.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2016-2022, Intel Corporation +; Copyright (c) 2016-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/ptxed-end_on_call-ret_tnt.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/ptxed-end_on_call-ret_tnt.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2016-2022, Intel Corporation +; Copyright (c) 2016-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/ptxed-end_on_call-tip_pgd.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/ptxed-end_on_call-tip_pgd.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2016-2022, Intel Corporation +; Copyright (c) 2016-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/ptxed-end_on_jump-fup-tip_pgd.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/ptxed-end_on_jump-fup-tip_pgd.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2017-2022, Intel Corporation +; Copyright (c) 2017-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/ptxed-insn-stat.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/ptxed-insn-stat.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2016-2022, Intel Corporation +; Copyright (c) 2016-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/ptxed-stat_insn.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/ptxed-stat_insn.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2016-2022, Intel Corporation +; Copyright (c) 2016-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/ptxed-tick.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/ptxed-tick.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2017-2022, Intel Corporation +; Copyright (c) 2017-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/pwre-exstop_ip-pwrx.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/pwre-exstop_ip-pwrx.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2015-2022, Intel Corporation +; Copyright (c) 2015-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/ret_near_far.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/ret_near_far.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/skd007.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/skd007.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2015-2022, Intel Corporation +; Copyright (c) 2015-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met: @@ -69,8 +70,7 @@ ;%0p0 psb ;%0p1 mode.exec cs.l ;%0p2 fup 3: %?l0 -;%0p3 cyc 3e -;%0p4 cyc 1e +;%0p3 ovf ;%0p5 pad ;%0p6 fup 3: %?l1 ;%0p7 fup 1: %?l2.2
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/skd010-mode_tsx-fup.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/skd010-mode_tsx-fup.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2015-2022, Intel Corporation +; Copyright (c) 2015-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/skd010-psb.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/skd010-psb.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2015-2022, Intel Corporation +; Copyright (c) 2015-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/skd010-tip.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/skd010-tip.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2015-2022, Intel Corporation +; Copyright (c) 2015-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/skd010-tip_pgd.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/skd010-tip_pgd.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2015-2022, Intel Corporation +; Copyright (c) 2015-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/skd022.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/skd022.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2015-2022, Intel Corporation +; Copyright (c) 2015-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met: @@ -52,6 +53,15 @@ ; cpu 6/151 ; cpu 6/154 ; cpu 6/191 +; cpu 6/173 +; cpu 6/174 +; cpu 6/183 +; cpu 6/181 +; cpu 6/170 +; cpu 6/172 +; cpu 6/207 +; cpu 6/186 +; cpu 6/204 ; org 0x1000
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/skl014-call.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/skl014-call.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2017-2022, Intel Corporation +; Copyright (c) 2017-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met: @@ -56,6 +57,15 @@ ; cpu 6/151 ; cpu 6/154 ; cpu 6/191 +; cpu 6/173 +; cpu 6/174 +; cpu 6/183 +; cpu 6/181 +; cpu 6/170 +; cpu 6/172 +; cpu 6/207 +; cpu 6/186 +; cpu 6/204 ; org 0x1000
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/skl014-jmp-jmp.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/skl014-jmp-jmp.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2017-2022, Intel Corporation +; Copyright (c) 2017-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met: @@ -56,6 +57,15 @@ ; cpu 6/151 ; cpu 6/154 ; cpu 6/191 +; cpu 6/173 +; cpu 6/174 +; cpu 6/183 +; cpu 6/181 +; cpu 6/170 +; cpu 6/172 +; cpu 6/207 +; cpu 6/186 +; cpu 6/204 ; org 0x1000
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/skl014-jmp.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/skl014-jmp.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2017-2022, Intel Corporation +; Copyright (c) 2017-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met: @@ -56,6 +57,15 @@ ; cpu 6/151 ; cpu 6/154 ; cpu 6/191 +; cpu 6/173 +; cpu 6/174 +; cpu 6/183 +; cpu 6/181 +; cpu 6/170 +; cpu 6/172 +; cpu 6/207 +; cpu 6/186 +; cpu 6/204 ; org 0x1000
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/skl014-no_filter.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/skl014-no_filter.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2017-2022, Intel Corporation +; Copyright (c) 2017-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met: @@ -47,6 +48,15 @@ ; cpu 6/151 ; cpu 6/154 ; cpu 6/191 +; cpu 6/173 +; cpu 6/174 +; cpu 6/183 +; cpu 6/181 +; cpu 6/170 +; cpu 6/172 +; cpu 6/207 +; cpu 6/186 +; cpu 6/204 ; org 0x100000
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/skl168-cyc.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/skl168-cyc.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2018-2022, Intel Corporation +; Copyright (c) 2018-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/skl168-mtc.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/skl168-mtc.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2018-2022, Intel Corporation +; Copyright (c) 2018-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/skz84.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/skz84.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2020-2022, Intel Corporation +; Copyright (c) 2020-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met: @@ -41,6 +42,9 @@ ; cpu 6/106 ; cpu 6/108 ; cpu 6/143 +; cpu 6/173 +; cpu 6/174 +; cpu 6/207 ; org 0x100000
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/syscall-sysret-cpl_0.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/syscall-sysret-cpl_0.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/syscall-sysret-cpl_3.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/syscall-sysret-cpl_3.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/syscall-sysret.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/syscall-sysret.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/sysenter-sysexit-cpl_0.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/sysenter-sysexit-cpl_0.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/sysenter-sysexit-cpl_3.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/sysenter-sysexit-cpl_3.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/sysenter-sysexit.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/sysenter-sysexit.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tip-eos.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tip-eos.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2016-2022, Intel Corporation +; Copyright (c) 2016-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tip_pgd-direct_call.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tip_pgd-direct_call.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2013-2022, Intel Corporation +; Copyright (c) 2013-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tip_pgd-direct_jump.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tip_pgd-direct_jump.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2013-2022, Intel Corporation +; Copyright (c) 2013-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tip_pgd-exstop-tip_pge.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tip_pgd-exstop-tip_pge.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2015-2022, Intel Corporation +; Copyright (c) 2015-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tip_pgd-indirect_call.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tip_pgd-indirect_call.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2013-2022, Intel Corporation +; Copyright (c) 2013-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tip_pgd-indirect_jump.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tip_pgd-indirect_jump.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2013-2022, Intel Corporation +; Copyright (c) 2013-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.1.tar.gz/test/src/tip_pgd-mwait-pwre-exstop-pwrx-tip_pge.ptt
Added
@@ -0,0 +1,82 @@ +; Copyright (c) 2015-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; +; * Redistributions of source code must retain the above copyright notice, +; this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright notice, +; this list of conditions and the following disclaimer in the documentation +; and/or other materials provided with the distribution. +; * Neither the name of Intel Corporation nor the names of its contributors +; may be used to endorse or promote products derived from this software +; without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; POSSIBILITY OF SUCH DAMAGE. + +; Test a power event session while tracing is disabled. +; +; Variant: with MWAIT. +; + +org 0x1000 +bits 64 + +; @pt p0: psb() +; @pt p1: mode.exec(64bit) +; @pt p2: fup(3: %l0) +; @pt p3: psbend() +l0: jle l1 +l1: hlt + +; @pt p4: tip.pgd(1: %l1) + +; @pt p5: mwait(7, 1) +; @pt p6: pwre(c1.0) +; @pt p7: exstop() +; @pt p8: pwrx(int: c1, c0) + +; @pt p9: tip.pge(3: %l2) +l2: nop +l3: nop + +; @pt p10:fup(1: %l3) +; @pt p11:tip.pgd(0: %l4) +l4: hlt + + +; @pt .exp(ptdump) +;%0p0 psb +;%0p1 mode.exec cs.l +;%0p2 fup 3: %?l0 +;%0p3 psbend +;%0p4 tip.pgd 1: %?l1.2 +;%0p5 mwait 00000007, 00000001 +;%0p6 pwre c1.0 +;%0p7 exstop +;%0p8 pwrx int: c1, c0 +;%0p9 tip.pge 3: %?l2 +;%0p10 fup 1: %?l3.2 +;%0p11 tip.pgd 0: %?l4.0 + +; @pt .exp(ptxed) +;%0l0 +;disabled +;pwre c1.0 +;mwait 7 1 +;exstop +;pwrx int: c1 (c0) +;enabled +;%0l2 +;disabled
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tip_pgd-pip-tip_pge.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tip_pgd-pip-tip_pge.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tip_pgd-psb-stop.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tip_pgd-psb-stop.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2013-2022, Intel Corporation +; Copyright (c) 2013-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tip_pgd-stop.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tip_pgd-stop.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2013-2022, Intel Corporation +; Copyright (c) 2013-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tip_pgd-tnt_not_taken.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tip_pgd-tnt_not_taken.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2013-2022, Intel Corporation +; Copyright (c) 2013-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tip_pgd-tnt_taken.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tip_pgd-tnt_taken.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2013-2022, Intel Corporation +; Copyright (c) 2013-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tip_pgd-tsx.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tip_pgd-tsx.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tip_pgd_noip-far_jump.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tip_pgd_noip-far_jump.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2013-2022, Intel Corporation +; Copyright (c) 2013-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tip_pgd_noip-mov_cr3.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tip_pgd_noip-mov_cr3.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2013-2022, Intel Corporation +; Copyright (c) 2013-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tip_pge-exstop.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tip_pge-exstop.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2016-2022, Intel Corporation +; Copyright (c) 2016-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tip_pge-fup-tip_pgd-tip_pge.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tip_pge-fup-tip_pgd-tip_pge.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2013-2022, Intel Corporation +; Copyright (c) 2013-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tip_pge-fup-tip_pgd.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tip_pge-fup-tip_pgd.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2013-2022, Intel Corporation +; Copyright (c) 2013-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tip_pge-ptw-fup-tip_pgd.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tip_pge-ptw-fup-tip_pgd.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2015-2022, Intel Corporation +; Copyright (c) 2015-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tip_pge-ptw-tip_pgd.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tip_pge-ptw-tip_pgd.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2015-2022, Intel Corporation +; Copyright (c) 2015-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tip_pge-pwre-pwrx-tip_pgd.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tip_pge-pwre-pwrx-tip_pgd.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2016-2022, Intel Corporation +; Copyright (c) 2016-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tip_pge-tsx_abort-tip-fup-tip_pgd.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tip_pge-tsx_abort-tip-fup-tip_pgd.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2016-2022, Intel Corporation +; Copyright (c) 2016-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tip_pge-tsx_abort-tip_pgd.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tip_pge-tsx_abort-tip_pgd.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2016-2022, Intel Corporation +; Copyright (c) 2016-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tma-reserved_ctc.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tma-reserved_ctc.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2020-2022, Intel Corporation +; Copyright (c) 2020-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tma-reserved_fc.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tma-reserved_fc.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2020-2022, Intel Corporation +; Copyright (c) 2020-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tnt-tip_pgd_noip-sysret.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tnt-tip_pgd_noip-sysret.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tnt_n-eos.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tnt_n-eos.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2016-2022, Intel Corporation +; Copyright (c) 2016-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tnt_t-eos.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tnt_t-eos.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2016-2022, Intel Corporation +; Copyright (c) 2016-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/truncated.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/truncated.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2016-2022, Intel Corporation +; Copyright (c) 2016-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tsc-cbr-cyc-tsc.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tsc-cbr-cyc-tsc.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tsc-cyc_calibrate.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tsc-cyc_calibrate.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tsc-mtc-tma-mtc.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tsc-mtc-tma-mtc.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tsc-tma-cbr-cyc-mtc.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tsc-tma-cbr-cyc-mtc.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tsc-tma-cbr-cyc.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tsc-tma-cbr-cyc.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tsc-tma-cbr-mtc-cyc-mtc.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tsc-tma-cbr-mtc-cyc-mtc.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tsc-tma-cbr-mtc-cyc-no_cyc.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tsc-tma-cbr-mtc-cyc-no_cyc.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2015-2022, Intel Corporation +; Copyright (c) 2015-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tsc-tma-cbr-mtc-cyc-tsc.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tsc-tma-cbr-mtc-cyc-tsc.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tsc-tma-cbr-mtc-cyc.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tsc-tma-cbr-mtc-cyc.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tsc-tma-cbr-mtc-cyc_calibrate.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tsc-tma-cbr-mtc-cyc_calibrate.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tsc-tma-cbr-mtc-mtc-cyc.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tsc-tma-cbr-mtc-mtc-cyc.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tsc-tma-cyc.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tsc-tma-cyc.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tsc-tma-mtc-cyc_calibrate.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tsc-tma-mtc-cyc_calibrate.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tsc-tma-mtc-mtc-cyc_calibrate.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tsc-tma-mtc-mtc-cyc_calibrate.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tsc-tma-mtc-tsc.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tsc-tma-mtc-tsc.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tsc-tma-mtc_absolute.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tsc-tma-mtc_absolute.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tsc-tma-mtc_infreq.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tsc-tma-mtc_infreq.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2016-2022, Intel Corporation +; Copyright (c) 2016-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tsc-tma-mtc_infreq_wrap.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tsc-tma-mtc_infreq_wrap.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2016-2022, Intel Corporation +; Copyright (c) 2016-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tsc-tma-mtc_relative.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tsc-tma-mtc_relative.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tsc-tma-mtc_wrap.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tsc-tma-mtc_wrap.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tsc-tma_zero_fc-cbr-cyc.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tsc-tma_zero_fc-cbr-cyc.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2016-2022, Intel Corporation +; Copyright (c) 2016-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tsc_tma_mtc_gap.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tsc_tma_mtc_gap.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tsx-abort.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tsx-abort.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2013-2022, Intel Corporation +; Copyright (c) 2013-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tsx-commit.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tsx-commit.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2013-2022, Intel Corporation +; Copyright (c) 2013-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/tsx-no_spurious_commit.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/tsx-no_spurious_commit.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2014-2022, Intel Corporation +; Copyright (c) 2014-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
View file
_service:tar_scm:v2.0.5.tar.gz/test/src/vmcs-far_call.ptt -> _service:tar_scm:v2.1.tar.gz/test/src/vmcs-far_call.ptt
Changed
@@ -1,4 +1,5 @@ -; Copyright (c) 2015-2022, Intel Corporation +; Copyright (c) 2015-2023, Intel Corporation +; SPDX-License-Identifier: BSD-3-Clause ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met:
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2