summaryrefslogtreecommitdiffstats
path: root/tools/perf/util/sample.h
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-08-23 13:28:57 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2026-08-23 13:28:57 -0700
commit4352b8aee98005853aa63f57d6377282de17a33f (patch)
tree27614d7a9ef05c32d089004e104364ce42324837 /tools/perf/util/sample.h
downloadlinux-stable-4352b8aee98005853aa63f57d6377282de17a33f.tar.gz
linux-stable-4352b8aee98005853aa63f57d6377282de17a33f.zip
Merge tag 'i3c/for-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/i3c/linuxgrafted
Pull I3C updates from Alexandre Belloni: "A new driver this cycle, for the AMD AXI I3C controller. There are also new features such as IBI wakeup support, SETAASA device discovery and ACPI support for the the DAA methods, meaning we can now communicate with the SPD devices on DDR5 modules. New driver: - AMD AXI I3C master controller Subsystem: - I3C Common Command Code (CCC) handling improvements, especially around GET CCCs - SETAASA device discovery support - ACPI support for all existing DAA methods like SETDASA, SETNEWDA as well as I2C devices on I3C bus - IBI-based wakeup support Drivers: - dw: SETAASA support - mipi-i3c-hci: advertise IBI wakeup capability, AMD_PT I3C controller support, PIO queue management support for HCI v1.2 - renesas: improve suspend to RAM support, add runtime PM support" * tag 'i3c/for-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/i3c/linux: (70 commits) i3c: dw: reduce do_daa time if there's no client i3c: mipi-i3c-hci: Add support for AMD_PT I3C controller i3c: mipi-i3c-hci: Add PIO queue management support for HCI v1.2 i3c: mipi-i3c-hci: Fix missing STAT_IBI_STATUS_THLD in PIO mode i3c: dw: rename "pclk" to "apb" to match dt-binding i3c: dw: make struct dw_i3c_cmd smaller i3c: dw: use COMMAND_PORT_TRANSFER_ARG instead of hardcoding i3c: renesas: Don't register devices when ENTDAA times out i3c: master: dw-i3c-master: fix OD timing for first broadcast i3c: mipi-i3c-hci: Advertise IBI wakeup capability i3c: mipi-i3c-hci: Factor out i3c_hci_sysdev() i3c: mipi-i3c-hci-pci: Propagate I3C wakeup requirements to PCI i3c: master: Reject IBI requests from non-IBI-capable devices i3c: master: Add helper to query bus wakeup requirements i3c: master: Report wakeup events for IBIs i3c: master: Support IBI-based wakeup capability i3c: master: Fix potential UAF in i3c_device_match() i3c: master: Fix potential UAF in i3c_device_uevent() i3c: Make dev->desc locking assumptions explicit i3c: master: Fix use-after-free of master->this ...
Diffstat (limited to 'tools/perf/util/sample.h')
-rw-r--r--tools/perf/util/sample.h268
1 files changed, 268 insertions, 0 deletions
diff --git a/tools/perf/util/sample.h b/tools/perf/util/sample.h
new file mode 100644
index 000000000..c4eae8b2f
--- /dev/null
+++ b/tools/perf/util/sample.h
@@ -0,0 +1,268 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __PERF_SAMPLE_H
+#define __PERF_SAMPLE_H
+
+#include <linux/perf_event.h>
+#include <linux/types.h>
+
+struct evsel;
+struct machine;
+struct thread;
+
+/* number of register is bound by the number of bits in regs_dump::mask (64) */
+#define PERF_SAMPLE_REGS_CACHE_SIZE (8 * sizeof(u64))
+
+struct regs_dump {
+ u64 abi;
+ u64 mask;
+ u64 *regs;
+
+ /* Cached values/mask filled by first register access. */
+ u64 cache_regs[PERF_SAMPLE_REGS_CACHE_SIZE];
+ u64 cache_mask;
+};
+
+struct stack_dump {
+ u16 offset;
+ u64 size;
+ char *data;
+};
+
+struct sample_read_value {
+ u64 value;
+ u64 id; /* only if PERF_FORMAT_ID */
+ u64 lost; /* only if PERF_FORMAT_LOST */
+};
+
+struct sample_read {
+ u64 time_enabled;
+ u64 time_running;
+ union {
+ struct {
+ u64 nr;
+ struct sample_read_value *values;
+ } group;
+ struct sample_read_value one;
+ };
+};
+
+static inline size_t sample_read_value_size(u64 read_format)
+{
+ /* PERF_FORMAT_ID is forced for PERF_SAMPLE_READ */
+ if (read_format & PERF_FORMAT_LOST)
+ return sizeof(struct sample_read_value);
+ else
+ return offsetof(struct sample_read_value, lost);
+}
+
+static inline struct sample_read_value *next_sample_read_value(struct sample_read_value *v, u64 read_format)
+{
+ return (void *)v + sample_read_value_size(read_format);
+}
+
+#define sample_read_group__for_each(v, nr, rf) \
+ for (int __i = 0; __i < (int)nr; v = next_sample_read_value(v, rf), __i++)
+
+#define MAX_INSN 16
+
+struct aux_sample {
+ u64 size;
+ void *data;
+};
+
+struct simd_flags {
+ u8 arch: 2, /* architecture (isa) */
+ pred: 3, /* predication */
+ resv: 3; /* reserved */
+};
+
+/* simd architecture flags */
+enum simd_op_flags {
+ SIMD_OP_FLAGS_ARCH_NONE = 0x0, /* No SIMD operation */
+ SIMD_OP_FLAGS_ARCH_SVE, /* Arm SVE */
+ SIMD_OP_FLAGS_ARCH_SME, /* Arm SME */
+ SIMD_OP_FLAGS_ARCH_ASE, /* Arm Advanced SIMD */
+};
+
+/* simd predicate flags */
+enum simd_pred_flags {
+ SIMD_OP_FLAGS_PRED_NONE = 0x0, /* Not available */
+ SIMD_OP_FLAGS_PRED_PARTIAL, /* partial predicate */
+ SIMD_OP_FLAGS_PRED_EMPTY, /* empty predicate */
+ SIMD_OP_FLAGS_PRED_FULL, /* full predicate */
+ SIMD_OP_FLAGS_PRED_DISABLED, /* disabled predicate */
+};
+
+/**
+ * struct perf_sample
+ *
+ * A sample is generally filled in by evlist__parse_sample/evsel__parse_sample
+ * which fills in the variables from a "union perf_event *event" which is data
+ * from a perf ring buffer or perf.data file. The "event" sample is variable in
+ * length as determined by the perf_event_attr (in the evsel) and details within
+ * the sample event itself. A struct perf_sample avoids needing to care about
+ * the variable length nature of the original event.
+ *
+ * To avoid being excessively large parts of the struct perf_sample are pointers
+ * into the original sample event. In general the lifetime of a struct
+ * perf_sample needs to be less than the "union perf_event *event" it was
+ * derived from.
+ *
+ * The struct regs_dump user_regs and intr_regs are lazily allocated again for
+ * size reasons, due to them holding a cache of looked up registers. The
+ * function pair of perf_sample__init and perf_sample__exit correctly initialize
+ * and clean up these values.
+ */
+struct perf_sample {
+ /** @evsel: Backward reference to the evsel used when constructing the sample. */
+ struct evsel *evsel;
+ /** @ip: The sample event PERF_SAMPLE_IP value. */
+ u64 ip;
+ /** @pid: The sample event PERF_SAMPLE_TID pid value. */
+ u32 pid;
+ /** @tid: The sample event PERF_SAMPLE_TID tid value. */
+ u32 tid;
+ /** @time: The sample event PERF_SAMPLE_TIME value. */
+ u64 time;
+ /** @addr: The sample event PERF_SAMPLE_ADDR value. */
+ u64 addr;
+ /** @id: The sample event PERF_SAMPLE_ID or PERF_SAMPLE_IDENTIFIER value. */
+ u64 id;
+ /** @stream_id: The sample event PERF_SAMPLE_STREAM_ID value. */
+ u64 stream_id;
+ /** @period: The sample event PERF_SAMPLE_PERIOD value. */
+ u64 period;
+ /** @weight: Data determined by PERF_SAMPLE_WEIGHT or PERF_SAMPLE_WEIGHT_STRUCT. */
+ u64 weight;
+ /** @transaction: The sample event PERF_SAMPLE_TRANSACTION value. */
+ u64 transaction;
+ /** @insn_cnt: Filled in and used by intel-pt. */
+ u64 insn_cnt;
+ /** @cyc_cnt: Filled in and used by intel-pt. */
+ u64 cyc_cnt;
+ /** @cpu: The sample event PERF_SAMPLE_CPU value. */
+ u32 cpu;
+ /**
+ * @raw_size: The size in bytes of raw data from PERF_SAMPLE_RAW. For
+ * alignment reasons this should always be sizeof(u32)
+ * followed by a multiple of sizeof(u64).
+ */
+ u32 raw_size;
+ /** @data_src: The sample event PERF_SAMPLE_DATA_SRC value. */
+ u64 data_src;
+ /** @phys_addr: The sample event PERF_SAMPLE_PHYS_ADDR value. */
+ u64 phys_addr;
+ /** @data_page_size: The sample event PERF_SAMPLE_DATA_PAGE_SIZE value. */
+ u64 data_page_size;
+ /** @code_page_size: The sample event PERF_SAMPLE_CODE_PAGE_SIZE value. */
+ u64 code_page_size;
+ /** @cgroup: The sample event PERF_SAMPLE_CGROUP value. */
+ u64 cgroup;
+ /** @file_offset: Byte offset of this event in the perf.data file. */
+ u64 file_offset;
+ /** @flags: Extra flag data from auxiliary events like intel-pt. */
+ u32 flags;
+ /** @machine_pid: The guest machine pid derived from the sample id. */
+ u32 machine_pid;
+ /** @vcpu: The guest machine vcpu derived from the sample id. */
+ u32 vcpu;
+ /**
+ * @insn_len: Instruction length from auxiliary events like
+ * intel-pt. The instruction itself is held in insn.
+ */
+ u16 insn_len;
+ /** @misc: The entire struct perf_event_header misc variable. */
+ u16 misc;
+ /**
+ * @ins_lat: Instruction latency information from weight2 in
+ * PERF_SAMPLE_WEIGHT_STRUCT or auxiliary events like
+ * intel-pt.
+ */
+ u16 ins_lat;
+ /**
+ * @weight3: From PERF_SAMPLE_WEIGHT_STRUCT. On x86 holds retire_lat, on
+ * powerpc holds p_stage_cyc.
+ */
+ u16 weight3;
+ /**
+ * @cpumode: The cpumode from struct perf_event_header misc variable
+ * masked with CPUMODE_MASK. Gives user, kernel and hypervisor
+ * information.
+ */
+ u8 cpumode;
+ /**
+ * @no_hw_idx: For PERF_SAMPLE_BRANCH_STACK, true when
+ * PERF_SAMPLE_BRANCH_HW_INDEX isn't set.
+ */
+ bool no_hw_idx;
+ /**
+ * @deferred_callchain: When processing PERF_SAMPLE_CALLCHAIN a deferred
+ * user callchain marker was encountered.
+ */
+ bool deferred_callchain;
+ /**
+ * @merged_callchain: A synthesized merged callchain that is allocated
+ * and needs freeing.
+ */
+ bool merged_callchain;
+ /**
+ * @deferred_cookie: Identifier of the deferred callchain in the later
+ * PERF_RECORD_CALLCHAIN_DEFERRED event.
+ */
+ u64 deferred_cookie;
+ /** @insn: A copy of the sampled instruction filled in by perf_sample__fetch_insn. */
+ char insn[MAX_INSN];
+ /** @raw_data: Pointer into the original event for PERF_SAMPLE_RAW data. */
+ void *raw_data;
+ /**
+ * @callchain: Pointer into the original event for PERF_SAMPLE_CALLCHAIN
+ * data. For deferred callchains this may be a copy that
+ * needs freeing, see sample__merge_deferred_callchain.
+ */
+ struct ip_callchain *callchain;
+ /** @branch_stack: Pointer into the original event for PERF_SAMPLE_BRANCH_STACK data. */
+ struct branch_stack *branch_stack;
+ /**
+ * @branch_stack_cntr: Pointer into the original event for
+ * PERF_SAMPLE_BRANCH_COUNTERS data.
+ */
+ u64 *branch_stack_cntr;
+ /** @user_regs: Values and pointers into the sample for PERF_SAMPLE_REGS_USER. */
+ struct regs_dump *user_regs;
+ /** @intr_regs: Values and pointers into the sample for PERF_SAMPLE_REGS_INTR. */
+ struct regs_dump *intr_regs;
+ /** @user_stack: Size and pointer into the sample for PERF_SAMPLE_STACK_USER. */
+ struct stack_dump user_stack;
+ /**
+ * @read: The sample event PERF_SAMPLE_READ counter values. The valid
+ * values depend on the attr.read_format PERF_FORMAT_ values.
+ */
+ struct sample_read read;
+ /**
+ * @aux_sample: Similar to raw data but with a 64-bit size and
+ * alignment, PERF_SAMPLE_AUX data.
+ */
+ struct aux_sample aux_sample;
+ /** @simd_flags: SIMD flag information from ARM SPE auxiliary events. */
+ struct simd_flags simd_flags;
+};
+
+void perf_sample__init(struct perf_sample *sample, bool all);
+void perf_sample__exit(struct perf_sample *sample);
+struct regs_dump *perf_sample__user_regs(struct perf_sample *sample);
+struct regs_dump *perf_sample__intr_regs(struct perf_sample *sample);
+
+void perf_sample__fetch_insn(struct perf_sample *sample,
+ struct thread *thread,
+ struct machine *machine);
+
+/*
+ * raw_data is always 4 bytes from an 8-byte boundary, so subtract 4 to get
+ * 8-byte alignment.
+ */
+static inline void *perf_sample__synth_ptr(struct perf_sample *sample)
+{
+ return sample->raw_data - 4;
+}
+
+#endif /* __PERF_SAMPLE_H */