--- a/tools/perf/util/arm-spe.c
+++ b/tools/perf/util/arm-spe.c
-@@ -655,37 +655,35 @@ static bool arm_spe__is_common_ds_encodi
+@@ -635,37 +635,35 @@ static bool arm_spe__is_common_ds_encodi
u64 *metadata = NULL;
u64 midr = 0;
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
- tools/perf/util/cs-etm.c | 25 +++++++++++++++++++++++--
+ tools/perf/util/cs-etm.c | 25 +++++++++++++++++++++++--
1 file changed, 23 insertions(+), 2 deletions(-)
-diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
-index 9e12084f66099f..36e9e6dc9b526a 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
-@@ -292,8 +292,11 @@ static struct cs_etm_queue *cs_etm__get_queue(struct cs_etm_auxtrace *etm, int c
+@@ -292,8 +292,11 @@ static struct cs_etm_queue *cs_etm__get_
{
if (etm->per_thread_decoding)
return etm->queues.queue_array[0].priv;
}
static int cs_etm__map_trace_id_v0(struct cs_etm_auxtrace *etm, u8 trace_chan_id,
-@@ -306,6 +309,9 @@ static int cs_etm__map_trace_id_v0(struct cs_etm_auxtrace *etm, u8 trace_chan_id
+@@ -306,6 +309,9 @@ static int cs_etm__map_trace_id_v0(struc
* queue associated with that CPU so only one decoder is made.
*/
etmq = cs_etm__get_queue(etm, cpu_metadata[CS_ETM_CPU]);
if (etmq->format == UNFORMATTED)
return cs_etm__insert_trace_id_node(etmq, trace_chan_id,
cpu_metadata);
-@@ -318,6 +324,9 @@ static int cs_etm__map_trace_id_v0(struct cs_etm_auxtrace *etm, u8 trace_chan_id
+@@ -318,6 +324,9 @@ static int cs_etm__map_trace_id_v0(struc
int ret;
etmq = etm->queues.queue_array[i].priv;
ret = cs_etm__insert_trace_id_node(etmq, trace_chan_id,
cpu_metadata);
if (ret)
-@@ -358,6 +367,9 @@ static int cs_etm__process_trace_id_v0_1(struct cs_etm_auxtrace *etm, int cpu,
+@@ -358,6 +367,9 @@ static int cs_etm__process_trace_id_v0_1
u32 sink_id = FIELD_GET(CS_AUX_HW_ID_SINK_ID_MASK, hw_id);
u8 trace_id = FIELD_GET(CS_AUX_HW_ID_TRACE_ID_MASK, hw_id);
/*
* Check sink id hasn't changed in per-cpu mode. In per-thread mode,
* let it pass for now until an actual overlapping trace ID is hit. In
-@@ -375,6 +387,9 @@ static int cs_etm__process_trace_id_v0_1(struct cs_etm_auxtrace *etm, int cpu,
+@@ -375,6 +387,9 @@ static int cs_etm__process_trace_id_v0_1
for (unsigned int i = 0; i < etm->queues.nr_queues; ++i) {
struct cs_etm_queue *other_etmq = etm->queues.queue_array[i].priv;
/* Different sinks, skip */
if (other_etmq->sink_id != etmq->sink_id)
continue;
-@@ -396,6 +411,9 @@ static int cs_etm__process_trace_id_v0_1(struct cs_etm_auxtrace *etm, int cpu,
+@@ -396,6 +411,9 @@ static int cs_etm__process_trace_id_v0_1
}
cpu_data = get_cpu_data(etm, cpu);
ret = cs_etm__insert_trace_id_node(etmq, trace_id, cpu_data);
if (ret)
return ret;
-@@ -3146,6 +3164,9 @@ static int cs_etm__queue_aux_fragment(struct perf_session *session, off_t file_o
+@@ -3128,6 +3146,9 @@ static int cs_etm__queue_aux_fragment(st
aux_offset + aux_size <= auxtrace_event->offset + auxtrace_event->size) {
struct cs_etm_queue *etmq = etm->queues.queue_array[auxtrace_event->idx].priv;
/*
* If this AUX event was inside this buffer somewhere, create a new auxtrace event
* based on the sizes of the aux event, and queue that fragment.
---
-2.53.0
-
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
- .../perf/util/cs-etm-decoder/cs-etm-decoder.c | 21 +-
- tools/perf/util/cs-etm.c | 236 +++++++++++-------
- tools/perf/util/cs-etm.h | 8 +-
+ tools/perf/util/cs-etm-decoder/cs-etm-decoder.c | 21 +-
+ tools/perf/util/cs-etm.c | 236 ++++++++++++++----------
+ tools/perf/util/cs-etm.h | 8
3 files changed, 163 insertions(+), 102 deletions(-)
-diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
-index 9bf09a856b44a3..c1257c5ef42567 100644
--- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
+++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
-@@ -399,6 +399,8 @@ cs_etm_decoder__buffer_packet(struct cs_etm_queue *etmq,
+@@ -399,6 +399,8 @@ cs_etm_decoder__buffer_packet(struct cs_
packet_queue->packet_buffer[et].flags = 0;
packet_queue->packet_buffer[et].exception_number = UINT32_MAX;
packet_queue->packet_buffer[et].trace_chan_id = trace_chan_id;
if (packet_queue->packet_count == CS_ETM_PACKET_MAX_BUFFER - 1)
return OCSD_RESP_WAIT;
-@@ -446,6 +448,7 @@ cs_etm_decoder__buffer_range(struct cs_etm_queue *etmq,
+@@ -446,6 +448,7 @@ cs_etm_decoder__buffer_range(struct cs_e
packet->last_instr_type = elem->last_i_type;
packet->last_instr_subtype = elem->last_i_subtype;
packet->last_instr_cond = elem->last_instr_cond;
if (elem->last_i_type == OCSD_INSTR_BR || elem->last_i_type == OCSD_INSTR_BR_INDIRECT)
packet->last_instr_taken_branch = elem->last_instr_exec;
-@@ -522,7 +525,9 @@ cs_etm_decoder__set_tid(struct cs_etm_queue *etmq,
+@@ -522,7 +525,9 @@ cs_etm_decoder__set_tid(struct cs_etm_qu
const ocsd_generic_trace_elem *elem,
const uint8_t trace_chan_id)
{
/*
* Process the PE_CONTEXT packets if we have a valid contextID or VMID.
-@@ -543,12 +548,18 @@ cs_etm_decoder__set_tid(struct cs_etm_queue *etmq,
+@@ -543,12 +548,18 @@ cs_etm_decoder__set_tid(struct cs_etm_qu
break;
}
/*
* A timestamp is generated after a PE_CONTEXT element so make sure
-@@ -556,7 +567,7 @@ cs_etm_decoder__set_tid(struct cs_etm_queue *etmq,
+@@ -556,7 +567,7 @@ cs_etm_decoder__set_tid(struct cs_etm_qu
*/
cs_etm_decoder__reset_timestamp(packet_queue);
}
static ocsd_datapath_resp_t cs_etm_decoder__gen_trace_elem_printer(
-diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
-index 51994ccbfbcb52..3fd669817eb9bf 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
@@ -86,15 +86,22 @@ struct cs_etm_traceid_queue {
};
enum cs_etm_format {
-@@ -608,10 +615,11 @@ static int cs_etm__init_traceid_queue(struct cs_etm_queue *etmq,
+@@ -608,10 +615,11 @@ static int cs_etm__init_traceid_queue(st
queue = &etmq->etm->queues.queue_array[etmq->queue_nr];
tidq->trace_chan_id = trace_chan_id;
tidq->packet = zalloc(sizeof(struct cs_etm_packet));
if (!tidq->packet)
-@@ -744,21 +752,10 @@ static void cs_etm__packet_swap(struct cs_etm_auxtrace *etm,
+@@ -744,21 +752,10 @@ static void cs_etm__packet_swap(struct c
/*
* Swap PACKET with PREV_PACKET: PACKET becomes PREV_PACKET for
* the next incoming packet.
}
}
-@@ -931,8 +928,8 @@ static void cs_etm__free_traceid_queues(struct cs_etm_queue *etmq)
+@@ -931,8 +928,8 @@ static void cs_etm__free_traceid_queues(
/* Free this traceid_queue from the array */
tidq = etmq->traceid_queues[idx];
zfree(&tidq->event_buf);
zfree(&tidq->last_branch);
zfree(&tidq->last_branch_rb);
-@@ -1077,47 +1074,43 @@ static u8 cs_etm__cpu_mode(struct cs_etm_queue *etmq, u64 address,
+@@ -1077,47 +1074,43 @@ static u8 cs_etm__cpu_mode(struct cs_etm
}
}
goto out;
dso = map__dso(al.map);
-@@ -1132,7 +1125,7 @@ static u32 cs_etm__mem_access(struct cs_etm_queue *etmq, u8 trace_chan_id,
+@@ -1132,7 +1125,7 @@ static u32 cs_etm__mem_access(struct cs_
map__load(al.map);
offset, buffer, size);
if (len <= 0) {
-@@ -1152,6 +1145,30 @@ static u32 cs_etm__mem_access(struct cs_etm_queue *etmq, u8 trace_chan_id,
+@@ -1152,6 +1145,30 @@ out:
return ret;
}
static struct cs_etm_queue *cs_etm__alloc_queue(void)
{
struct cs_etm_queue *etmq = zalloc(sizeof(*etmq));
-@@ -1327,12 +1344,13 @@ void cs_etm__reset_last_branch_rb(struct cs_etm_traceid_queue *tidq)
+@@ -1327,12 +1344,13 @@ void cs_etm__reset_last_branch_rb(struct
}
static inline int cs_etm__t32_instr_size(struct cs_etm_queue *etmq,
/*
* T32 instruction size is indicated by bits[15:11] of the first
* 16-bit word of the instruction: 0b11101, 0b11110 and 0b11111
-@@ -1365,16 +1383,16 @@ u64 cs_etm__last_executed_instr(const struct cs_etm_packet *packet)
+@@ -1365,16 +1383,16 @@ u64 cs_etm__last_executed_instr(const st
}
static inline u64 cs_etm__instr_addr(struct cs_etm_queue *etmq,
offset--;
}
return addr;
-@@ -1484,34 +1502,51 @@ cs_etm__get_trace(struct cs_etm_queue *etmq)
+@@ -1466,34 +1484,51 @@ cs_etm__get_trace(struct cs_etm_queue *e
return etmq->buf_len;
}
return 0;
}
-@@ -1521,8 +1556,8 @@ bool cs_etm__etmq_is_timeless(struct cs_etm_queue *etmq)
+@@ -1503,8 +1538,8 @@ bool cs_etm__etmq_is_timeless(struct cs_
}
static void cs_etm__copy_insn(struct cs_etm_queue *etmq,
struct perf_sample *sample)
{
/*
-@@ -1539,14 +1574,14 @@ static void cs_etm__copy_insn(struct cs_etm_queue *etmq,
+@@ -1521,14 +1556,14 @@ static void cs_etm__copy_insn(struct cs_
* cs_etm__t32_instr_size().
*/
if (packet->isa == CS_ETM_ISA_T32)
}
u64 cs_etm__convert_sample_time(struct cs_etm_queue *etmq, u64 cs_timestamp)
-@@ -1573,6 +1608,7 @@ static inline u64 cs_etm__resolve_sample_time(struct cs_etm_queue *etmq,
+@@ -1555,6 +1590,7 @@ static inline u64 cs_etm__resolve_sample
static int cs_etm__synth_instruction_sample(struct cs_etm_queue *etmq,
struct cs_etm_traceid_queue *tidq,
u64 addr, u64 period)
{
int ret = 0;
-@@ -1581,23 +1617,23 @@ static int cs_etm__synth_instruction_sample(struct cs_etm_queue *etmq,
+@@ -1563,23 +1599,23 @@ static int cs_etm__synth_instruction_sam
struct perf_sample sample = {.ip = 0,};
event->sample.header.type = PERF_RECORD_SAMPLE;
if (etm->synth_opts.last_branch)
sample.branch_stack = tidq->last_branch;
-@@ -1641,15 +1677,15 @@ static int cs_etm__synth_branch_sample(struct cs_etm_queue *etmq,
+@@ -1623,15 +1659,15 @@ static int cs_etm__synth_branch_sample(s
event->sample.header.type = PERF_RECORD_SAMPLE;
event->sample.header.misc = cs_etm__cpu_mode(etmq, ip,
sample.addr = cs_etm__first_executed_instr(tidq->packet);
sample.id = etmq->etm->branches_id;
sample.stream_id = etmq->etm->branches_id;
-@@ -1658,8 +1694,7 @@ static int cs_etm__synth_branch_sample(struct cs_etm_queue *etmq,
+@@ -1640,8 +1676,7 @@ static int cs_etm__synth_branch_sample(s
sample.flags = tidq->prev_packet->flags;
sample.cpumode = event->sample.header.misc;
/*
* perf report cannot handle events without a branch stack
-@@ -1783,7 +1818,6 @@ static int cs_etm__sample(struct cs_etm_queue *etmq,
+@@ -1765,7 +1800,6 @@ static int cs_etm__sample(struct cs_etm_
{
struct cs_etm_auxtrace *etm = etmq->etm;
int ret;
u64 instrs_prev;
/* Get instructions remainder from previous packet */
-@@ -1869,10 +1903,10 @@ static int cs_etm__sample(struct cs_etm_queue *etmq,
+@@ -1851,10 +1885,10 @@ static int cs_etm__sample(struct cs_etm_
* been executed, but PC has not advanced to next
* instruction)
*/
etm->instructions_sample_period);
if (ret)
return ret;
-@@ -1954,7 +1988,7 @@ static int cs_etm__flush(struct cs_etm_queue *etmq,
+@@ -1936,7 +1970,7 @@ static int cs_etm__flush(struct cs_etm_q
addr = cs_etm__last_executed_instr(tidq->prev_packet);
err = cs_etm__synth_instruction_sample(
tidq->period_instructions);
if (err)
return err;
-@@ -2009,7 +2043,7 @@ static int cs_etm__end_block(struct cs_etm_queue *etmq,
+@@ -1991,7 +2025,7 @@ static int cs_etm__end_block(struct cs_e
addr = cs_etm__last_executed_instr(tidq->prev_packet);
err = cs_etm__synth_instruction_sample(
tidq->period_instructions);
if (err)
return err;
-@@ -2046,9 +2080,9 @@ static int cs_etm__get_data_block(struct cs_etm_queue *etmq)
+@@ -2028,9 +2062,9 @@ static int cs_etm__get_data_block(struct
return etmq->buf_len;
}
{
/* Initialise to keep compiler happy */
u16 instr16 = 0;
-@@ -2070,8 +2104,8 @@ static bool cs_etm__is_svc_instr(struct cs_etm_queue *etmq, u8 trace_chan_id,
+@@ -2052,8 +2086,8 @@ static bool cs_etm__is_svc_instr(struct
* so below only read 2 bytes as instruction size for T32.
*/
addr = end_addr - 2;
if ((instr16 & 0xFF00) == 0xDF00)
return true;
-@@ -2086,8 +2120,8 @@ static bool cs_etm__is_svc_instr(struct cs_etm_queue *etmq, u8 trace_chan_id,
+@@ -2068,8 +2102,8 @@ static bool cs_etm__is_svc_instr(struct
* +---------+---------+-------------------------+
*/
addr = end_addr - 4;
if ((instr32 & 0x0F000000) == 0x0F000000 &&
(instr32 & 0xF0000000) != 0xF0000000)
return true;
-@@ -2103,8 +2137,8 @@ static bool cs_etm__is_svc_instr(struct cs_etm_queue *etmq, u8 trace_chan_id,
+@@ -2085,8 +2119,8 @@ static bool cs_etm__is_svc_instr(struct
* +-----------------------+---------+-----------+
*/
addr = end_addr - 4;
if ((instr32 & 0xFFE0001F) == 0xd4000001)
return true;
-@@ -2120,7 +2154,6 @@ static bool cs_etm__is_svc_instr(struct cs_etm_queue *etmq, u8 trace_chan_id,
+@@ -2102,7 +2136,6 @@ static bool cs_etm__is_svc_instr(struct
static bool cs_etm__is_syscall(struct cs_etm_queue *etmq,
struct cs_etm_traceid_queue *tidq, u64 magic)
{
struct cs_etm_packet *packet = tidq->packet;
struct cs_etm_packet *prev_packet = tidq->prev_packet;
-@@ -2135,7 +2168,7 @@ static bool cs_etm__is_syscall(struct cs_etm_queue *etmq,
+@@ -2117,7 +2150,7 @@ static bool cs_etm__is_syscall(struct cs
*/
if (magic == __perf_cs_etmv4_magic) {
if (packet->exception_number == CS_ETMV4_EXC_CALL &&
prev_packet->end_addr))
return true;
}
-@@ -2173,7 +2206,6 @@ static bool cs_etm__is_sync_exception(struct cs_etm_queue *etmq,
+@@ -2155,7 +2188,6 @@ static bool cs_etm__is_sync_exception(st
struct cs_etm_traceid_queue *tidq,
u64 magic)
{
struct cs_etm_packet *packet = tidq->packet;
struct cs_etm_packet *prev_packet = tidq->prev_packet;
-@@ -2199,7 +2231,7 @@ static bool cs_etm__is_sync_exception(struct cs_etm_queue *etmq,
+@@ -2181,7 +2213,7 @@ static bool cs_etm__is_sync_exception(st
* (SMC, HVC) are taken as sync exceptions.
*/
if (packet->exception_number == CS_ETMV4_EXC_CALL &&
prev_packet->end_addr))
return true;
-@@ -2223,7 +2255,6 @@ static int cs_etm__set_sample_flags(struct cs_etm_queue *etmq,
+@@ -2205,7 +2237,6 @@ static int cs_etm__set_sample_flags(stru
{
struct cs_etm_packet *packet = tidq->packet;
struct cs_etm_packet *prev_packet = tidq->prev_packet;
u64 magic;
int ret;
-@@ -2304,11 +2335,11 @@ static int cs_etm__set_sample_flags(struct cs_etm_queue *etmq,
+@@ -2286,11 +2317,11 @@ static int cs_etm__set_sample_flags(stru
if (prev_packet->flags == (PERF_IP_FLAG_BRANCH |
PERF_IP_FLAG_RETURN |
PERF_IP_FLAG_INTERRUPT) &&
break;
case CS_ETM_DISCONTINUITY:
/*
-@@ -2389,6 +2420,7 @@ static int cs_etm__set_sample_flags(struct cs_etm_queue *etmq,
+@@ -2371,6 +2402,7 @@ static int cs_etm__set_sample_flags(stru
PERF_IP_FLAG_RETURN |
PERF_IP_FLAG_INTERRUPT;
break;
case CS_ETM_EMPTY:
default:
break;
-@@ -2464,6 +2496,19 @@ static int cs_etm__process_traceid_queue(struct cs_etm_queue *etmq,
+@@ -2446,6 +2478,19 @@ static int cs_etm__process_traceid_queue
*/
cs_etm__sample(etmq, tidq);
break;
case CS_ETM_EXCEPTION:
case CS_ETM_EXCEPTION_RET:
/*
-@@ -2492,6 +2537,7 @@ static int cs_etm__process_traceid_queue(struct cs_etm_queue *etmq,
+@@ -2474,6 +2519,7 @@ static int cs_etm__process_traceid_queue
}
}
return ret;
}
-@@ -2615,7 +2661,7 @@ static int cs_etm__process_timeless_queues(struct cs_etm_auxtrace *etm,
+@@ -2597,7 +2643,7 @@ static int cs_etm__process_timeless_queu
if (!tidq)
continue;
cs_etm__run_per_thread_timeless_decoder(etmq);
} else
cs_etm__run_per_cpu_timeless_decoder(etmq);
-@@ -3326,7 +3372,7 @@ static int cs_etm__create_queue_decoders(struct cs_etm_queue *etmq)
+@@ -3308,7 +3354,7 @@ static int cs_etm__create_queue_decoders
*/
if (cs_etm_decoder__add_mem_access_cb(etmq->decoder,
0x0L, ((u64) -1L),
goto out_free_decoder;
zfree(&t_params);
-diff --git a/tools/perf/util/cs-etm.h b/tools/perf/util/cs-etm.h
-index a8caeea720aa17..dfc9aeacfd0b62 100644
--- a/tools/perf/util/cs-etm.h
+++ b/tools/perf/util/cs-etm.h
@@ -158,6 +158,7 @@ enum cs_etm_sample_type {
bool cs_etm__etmq_is_timeless(struct cs_etm_queue *etmq);
void cs_etm__etmq_set_traceid_queue_timestamp(struct cs_etm_queue *etmq,
u8 trace_chan_id);
---
-2.53.0
-
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
- tools/perf/util/cs-etm.c | 9 ++++++++-
+ tools/perf/util/cs-etm.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
-diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
-index 776bef4e00156e..e1b2612efa88a8 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
@@ -6,6 +6,7 @@
#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/coresight-pmu.h>
-@@ -3465,7 +3466,13 @@ int cs_etm__process_auxtrace_info_full(union perf_event *event,
+@@ -3447,7 +3448,13 @@ int cs_etm__process_auxtrace_info_full(u
goto err_free_metadata;
}
max_cpu = metadata[j][CS_ETM_CPU];
}
---
-2.53.0
-
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
- tools/perf/util/cs-etm.c | 12 ++++++++++++
+ tools/perf/util/cs-etm.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
-diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
-index e1b2612efa88a8..9e12084f66099f 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
-@@ -3428,6 +3428,18 @@ int cs_etm__process_auxtrace_info_full(union perf_event *event,
+@@ -3410,6 +3410,18 @@ int cs_etm__process_auxtrace_info_full(u
/* First the global part */
ptr = (u64 *) auxtrace_info->priv;
num_cpu = ptr[CS_PMU_TYPE_CPUS] & 0xffffffff;
metadata = zalloc(sizeof(*metadata) * num_cpu);
if (!metadata)
return -ENOMEM;
---
-2.53.0
-
Stable-dep-of: 2ea64782a428 ("perf tools: Use snprintf() in dso__read_running_kernel_build_id()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
- tools/perf/builtin-buildid-list.c | 2 +-
- tools/perf/builtin-inject.c | 36 ++++----
- tools/perf/builtin-report.c | 11 ++-
- tools/perf/include/perf/perf_dlfilter.h | 2 +-
- tools/perf/tests/symbols.c | 4 +-
- tools/perf/util/build-id.c | 4 +-
- tools/perf/util/dso.c | 109 +++++++++++++-----------
- tools/perf/util/dso.h | 75 ++++++++--------
- tools/perf/util/dsos.c | 18 ++--
- tools/perf/util/machine.c | 28 +++---
- tools/perf/util/map.c | 13 ++-
- tools/perf/util/map.h | 5 +-
- tools/perf/util/sort.c | 27 +++---
- tools/perf/util/synthetic-events.c | 18 ++--
- 14 files changed, 197 insertions(+), 155 deletions(-)
+ tools/perf/builtin-buildid-list.c | 2
+ tools/perf/builtin-inject.c | 36 ++++++----
+ tools/perf/builtin-report.c | 11 ++-
+ tools/perf/include/perf/perf_dlfilter.h | 2
+ tools/perf/tests/symbols.c | 4 -
+ tools/perf/util/build-id.c | 4 -
+ tools/perf/util/dso.c | 109 +++++++++++++++++---------------
+ tools/perf/util/dso.h | 75 ++++++++++++----------
+ tools/perf/util/dsos.c | 18 ++---
+ tools/perf/util/machine.c | 28 ++++----
+ tools/perf/util/map.c | 13 +--
+ tools/perf/util/map.h | 5 -
+ tools/perf/util/sort.c | 29 ++++----
+ tools/perf/util/synthetic-events.c | 18 +++--
+ 14 files changed, 198 insertions(+), 156 deletions(-)
-diff --git a/tools/perf/builtin-buildid-list.c b/tools/perf/builtin-buildid-list.c
-index ba8ba0303920c5..151cd84b6dfebd 100644
--- a/tools/perf/builtin-buildid-list.c
+++ b/tools/perf/builtin-buildid-list.c
-@@ -31,7 +31,7 @@ static int buildid__map_cb(struct map *map, void *arg __maybe_unused)
+@@ -31,7 +31,7 @@ static int buildid__map_cb(struct map *m
memset(bid_buf, 0, sizeof(bid_buf));
if (dso__has_build_id(dso))
printf("%s %16" PRIx64 " %16" PRIx64, bid_buf, map__start(map), map__end(map));
if (dso_long_name != NULL)
printf(" %s", dso_long_name);
-diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
-index 82683a57ad6c13..6f49f7fc2b8dfd 100644
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
-@@ -678,15 +678,17 @@ static int perf_event__repipe_mmap2(const struct perf_tool *tool,
+@@ -673,15 +673,17 @@ static int perf_event__repipe_mmap2(cons
struct perf_sample *sample,
struct machine *machine)
{
}
return perf_event__repipe_common_mmap(
-@@ -694,7 +696,7 @@ static int perf_event__repipe_mmap2(const struct perf_tool *tool,
+@@ -689,7 +691,7 @@ static int perf_event__repipe_mmap2(cons
event->mmap2.pid, event->mmap2.tid,
event->mmap2.start, event->mmap2.len, event->mmap2.pgoff,
event->mmap2.flags, event->mmap2.prot,
perf_event__process_mmap2);
}
-@@ -762,19 +764,20 @@ static int perf_event__repipe_tracing_data(struct perf_session *session,
+@@ -757,19 +759,20 @@ static int perf_event__repipe_tracing_da
static int dso__read_build_id(struct dso *dso)
{
struct nscookie nsc;
free(new_name);
}
nsinfo__mountns_exit(&nsc);
-@@ -823,23 +826,26 @@ static bool perf_inject__lookup_known_build_id(struct perf_inject *inject,
+@@ -818,23 +821,26 @@ static bool perf_inject__lookup_known_bu
struct dso *dso)
{
struct str_node *pos;
return true;
}
return false;
-diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
-index 86cbca6285a51a..f8787d635d0f08 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
-@@ -855,17 +855,24 @@ static int maps__fprintf_task_cb(struct map *map, void *data)
+@@ -855,17 +855,24 @@ static int maps__fprintf_task_cb(struct
struct maps__fprintf_task_args *args = data;
const struct dso *dso = map__dso(map);
u32 prot = map__prot(map);
if (ret < 0)
return ret;
-diff --git a/tools/perf/include/perf/perf_dlfilter.h b/tools/perf/include/perf/perf_dlfilter.h
-index 16fc4568ac53bf..2d3540ed3c586e 100644
--- a/tools/perf/include/perf/perf_dlfilter.h
+++ b/tools/perf/include/perf/perf_dlfilter.h
@@ -87,7 +87,7 @@ struct perf_dlfilter_al {
/* Below members are only populated by resolve_ip() */
__u8 filtered; /* True if this sample event will be filtered out */
const char *comm;
-diff --git a/tools/perf/tests/symbols.c b/tools/perf/tests/symbols.c
-index ee20a366f32f50..b07fdf83186828 100644
--- a/tools/perf/tests/symbols.c
+++ b/tools/perf/tests/symbols.c
-@@ -96,8 +96,8 @@ static int create_map(struct test_info *ti, char *filename, struct map **map_p)
+@@ -96,8 +96,8 @@ static int create_map(struct test_info *
dso__put(dso);
/* Create a dummy map at 0x100000 */
if (!*map_p) {
pr_debug("Failed to create map!");
return TEST_FAIL;
-diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
-index ac642c758d5a17..8bf9d82bcbf72e 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
-@@ -236,7 +236,7 @@ char *__dso__build_id_filename(const struct dso *dso, char *bf, size_t size,
+@@ -236,7 +236,7 @@ char *__dso__build_id_filename(const str
if (!dso__has_build_id(dso))
return NULL;
linkname = build_id_cache__linkname(sbuild_id, NULL, 0);
if (!linkname)
return NULL;
-@@ -319,7 +319,7 @@ static int machine__write_buildid_table_cb(struct dso *dso, void *data)
+@@ -319,7 +319,7 @@ static int machine__write_buildid_table_
}
in_kernel = dso__kernel(dso) || is_kernel_module(name, PERF_RECORD_MISC_CPUMODE_UNKNOWN);
in_kernel ? args->kmisc : args->umisc, args->fd);
}
-diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
-index aae754b1cc624a..9792c8d38a314b 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
-@@ -215,7 +215,7 @@ int dso__read_binary_type_filename(const struct dso *dso,
+@@ -215,7 +215,7 @@ int dso__read_binary_type_filename(const
break;
}
len = __symbol__join_symfs(filename, size, "/usr/lib/debug/.build-id/");
snprintf(filename + len, size - len, "%.2s/%s.debug",
build_id_hex, build_id_hex + 2);
-@@ -1376,64 +1376,76 @@ static void dso__set_long_name_id(struct dso *dso, const char *name, bool name_a
+@@ -1376,64 +1376,76 @@ static void dso__set_long_name_id(struct
static int __dso_id__cmp(const struct dso_id *a, const struct dso_id *b)
{
return __dso_id__cmp(a, b);
}
-@@ -1530,7 +1542,6 @@ struct dso *dso__new_id(const char *name, const struct dso_id *id)
+@@ -1530,7 +1542,6 @@ struct dso *dso__new_id(const char *name
dso->loaded = 0;
dso->rel = 0;
dso->sorted_by_name = 0;
dso->has_srcline = 1;
dso->a2l_fails = 1;
dso->kernel = DSO_SPACE__USER;
-@@ -1635,15 +1646,14 @@ int dso__swap_init(struct dso *dso, unsigned char eidata)
+@@ -1635,15 +1646,14 @@ int dso__swap_init(struct dso *dso, unsi
return 0;
}
if (dso_bid->size > bid->size && dso_bid->size == BUILD_ID_SIZE) {
/*
-@@ -1662,18 +1672,20 @@ bool dso__build_id_equal(const struct dso *dso, struct build_id *bid)
+@@ -1662,18 +1672,20 @@ bool dso__build_id_equal(const struct ds
void dso__read_running_kernel_build_id(struct dso *dso, struct machine *machine)
{
char path[PATH_MAX];
/*
* kernel module short names are of the form "[module]" and
* we need just "module" here.
-@@ -1684,9 +1696,8 @@ int dso__kernel_module_get_build_id(struct dso *dso,
+@@ -1684,9 +1696,8 @@ int dso__kernel_module_get_build_id(stru
"%s/sys/module/%.*s/notes/.note.gnu.build-id",
root_dir, (int)strlen(name) - 1, name);
return 0;
}
-diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h
-index 4bca8a3c8b48e2..d957e88afc9cbd 100644
--- a/tools/perf/util/dso.h
+++ b/tools/perf/util/dso.h
@@ -127,14 +127,33 @@ enum dso_load_errno {
/* dso__for_each_symbol - iterate over the symbols of given type
*
-@@ -302,31 +322,11 @@ static inline void dso__set_auxtrace_cache(struct dso *dso, struct auxtrace_cach
+@@ -302,31 +322,11 @@ static inline void dso__set_auxtrace_cac
RC_CHK_ACCESS(dso)->auxtrace_cache = cache;
}
static inline bool dso__has_srcline(const struct dso *dso)
{
return RC_CHK_ACCESS(dso)->has_srcline;
-@@ -402,6 +402,16 @@ static inline const struct dso_id *dso__id_const(const struct dso *dso)
+@@ -402,6 +402,16 @@ static inline const struct dso_id *dso__
return &RC_CHK_ACCESS(dso)->id;
}
static inline struct rb_root_cached *dso__inlined_nodes(struct dso *dso)
{
return &RC_CHK_ACCESS(dso)->inlined_nodes;
-@@ -639,9 +649,6 @@ static inline void dso__set_text_offset(struct dso *dso, u64 val)
+@@ -639,9 +649,6 @@ static inline void dso__set_text_offset(
RC_CHK_ACCESS(dso)->text_offset = val;
}
void dso__read_running_kernel_build_id(struct dso *dso,
struct machine *machine);
int dso__kernel_module_get_build_id(struct dso *dso, const char *root_dir);
-diff --git a/tools/perf/util/dsos.c b/tools/perf/util/dsos.c
-index b2172632b3cdd7..e239a3fa289671 100644
--- a/tools/perf/util/dsos.c
+++ b/tools/perf/util/dsos.c
-@@ -72,6 +72,7 @@ static int dsos__read_build_ids_cb(struct dso *dso, void *data)
+@@ -72,6 +72,7 @@ static int dsos__read_build_ids_cb(struc
{
struct dsos__read_build_ids_cb_args *args = data;
struct nscookie nsc;
if (args->with_hits && !dso__hit(dso) && !dso__is_vdso(dso))
return 0;
-@@ -80,15 +81,15 @@ static int dsos__read_build_ids_cb(struct dso *dso, void *data)
+@@ -80,15 +81,15 @@ static int dsos__read_build_ids_cb(struc
return 0;
}
nsinfo__mountns_enter(dso__nsinfo(dso), &nsc);
}
free(new_name);
}
-@@ -284,7 +285,7 @@ struct dso *dsos__find(struct dsos *dsos, const char *name, bool cmp_short)
+@@ -284,7 +285,7 @@ struct dso *dsos__find(struct dsos *dsos
struct dso *res;
down_read(&dsos->lock);
up_read(&dsos->lock);
return res;
}
-@@ -341,8 +342,8 @@ static struct dso *__dsos__findnew_id(struct dsos *dsos, const char *name, const
+@@ -341,8 +342,8 @@ static struct dso *__dsos__findnew_id(st
{
struct dso *dso = __dsos__find_id(dsos, name, id, false, /*write_locked=*/true);
return dso ? dso : __dsos__addnew_id(dsos, name, id);
}
-@@ -433,7 +434,8 @@ struct dso *dsos__findnew_module_dso(struct dsos *dsos,
+@@ -433,7 +434,8 @@ struct dso *dsos__findnew_module_dso(str
down_write(&dsos->lock);
if (dso) {
up_write(&dsos->lock);
return dso;
-diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
-index 20fd742984e3c4..06a168ce5d9044 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
-@@ -1696,21 +1696,21 @@ int machine__process_mmap2_event(struct machine *machine,
+@@ -1696,21 +1696,21 @@ int machine__process_mmap2_event(struct
{
struct thread *thread;
struct map *map;
}
if (sample->cpumode == PERF_RECORD_MISC_GUEST_KERNEL ||
-@@ -1722,7 +1722,7 @@ int machine__process_mmap2_event(struct machine *machine,
+@@ -1722,7 +1722,7 @@ int machine__process_mmap2_event(struct
};
strlcpy(xm.name, event->mmap2.filename, KMAP_NAME_LEN);
if (ret < 0)
goto out_problem;
return 0;
-@@ -1736,7 +1736,7 @@ int machine__process_mmap2_event(struct machine *machine,
+@@ -1736,7 +1736,7 @@ int machine__process_mmap2_event(struct
map = map__new(machine, event->mmap2.start,
event->mmap2.len, event->mmap2.pgoff,
&dso_id, event->mmap2.prot,
event->mmap2.filename, thread);
if (map == NULL)
-@@ -1794,8 +1794,8 @@ int machine__process_mmap_event(struct machine *machine, union perf_event *event
+@@ -1794,8 +1794,8 @@ int machine__process_mmap_event(struct m
prot = PROT_EXEC;
map = map__new(machine, event->mmap.start,
if (map == NULL)
goto out_problem_map;
-@@ -3155,7 +3155,7 @@ struct dso *machine__findnew_dso_id(struct machine *machine, const char *filenam
+@@ -3155,7 +3155,7 @@ struct dso *machine__findnew_dso_id(stru
struct dso *machine__findnew_dso(struct machine *machine, const char *filename)
{
}
char *machine__resolve_kernel_addr(void *vmachine, unsigned long long *addrp, char **modp)
-diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
-index 0f6b185f95896a..b46c68c24d1c8e 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
-@@ -120,8 +120,8 @@ static void map__init(struct map *map, u64 start, u64 end, u64 pgoff,
+@@ -120,8 +120,8 @@ static void map__init(struct map *map, u
}
struct map *map__new(struct machine *machine, u64 start, u64 len,
char *filename, struct thread *thread)
{
struct map *result;
-@@ -132,7 +132,7 @@ struct map *map__new(struct machine *machine, u64 start, u64 len,
+@@ -132,7 +132,7 @@ struct map *map__new(struct machine *mac
map = zalloc(sizeof(*map));
if (ADD_RC_CHK(result, map)) {
char newfilename[PATH_MAX];
int anon, no_dso, vdso, android;
android = is_android_lib(filename);
-@@ -189,16 +189,15 @@ struct map *map__new(struct machine *machine, u64 start, u64 len,
+@@ -189,16 +189,15 @@ struct map *map__new(struct machine *mac
dso__set_nsinfo(dso, nsi);
mutex_unlock(dso__lock(dso));
if (header_bid_dso && dso__header_build_id(header_bid_dso)) {
dso__set_build_id(dso, dso__bid(header_bid_dso));
dso__set_header_build_id(dso, 1);
-diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h
-index 4262f5a143be26..9cadf533a5615e 100644
--- a/tools/perf/util/map.h
+++ b/tools/perf/util/map.h
@@ -173,11 +173,10 @@ struct thread;
struct map *map__new2(u64 start, struct dso *dso);
void map__delete(struct map *map);
struct map *map__clone(struct map *map);
-diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
-index 013020f33ece0a..913116ffde161a 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
-@@ -1579,22 +1579,27 @@ sort__dcacheline_cmp(struct hist_entry *left, struct hist_entry *right)
+@@ -1579,22 +1579,27 @@ sort__dcacheline_cmp(struct hist_entry *
if (rc)
return rc;
/*
- (!(map__flags(l_map) & MAP_SHARED)) && !dso__id(l_dso)->maj && !dso__id(l_dso)->min &&
- !dso__id(l_dso)->ino && !dso__id(l_dso)->ino_generation) {
- /* userspace anonymous */
-+ if (!dso_id->mmap2_valid)
-+ dso_id = dso__id_const(r_dso);
-
+-
- if (thread__pid(left->thread) > thread__pid(right->thread))
- return -1;
- if (thread__pid(left->thread) < thread__pid(right->thread))
- return 1;
++ if (!dso_id->mmap2_valid)
++ dso_id = dso__id_const(r_dso);
++
+ if (!build_id__is_defined(&dso_id->build_id) &&
+ (!dso_id->mmap2_valid || (dso_id->maj == 0 && dso_id->min == 0))) {
+ /* userspace anonymous */
}
addr:
-@@ -1619,6 +1624,7 @@ static int hist_entry__dcacheline_snprintf(struct hist_entry *he, char *bf,
+@@ -1619,6 +1624,7 @@ static int hist_entry__dcacheline_snprin
if (he->mem_info) {
struct map *map = mem_info__daddr(he->mem_info)->ms.map;
struct dso *dso = map ? map__dso(map) : NULL;
addr = cl_address(mem_info__daddr(he->mem_info)->al_addr, chk_double_cl);
ms = &mem_info__daddr(he->mem_info)->ms;
-@@ -1627,8 +1633,7 @@ static int hist_entry__dcacheline_snprintf(struct hist_entry *he, char *bf,
+@@ -1627,8 +1633,7 @@ static int hist_entry__dcacheline_snprin
if ((he->cpumode != PERF_RECORD_MISC_KERNEL) &&
map && !(map__prot(map) & PROT_EXEC) &&
(map__flags(map) & MAP_SHARED) &&
level = 's';
else if (!map)
level = 'X';
-diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic-events.c
-index ef9ad891ef09b5..8101dd983eb057 100644
--- a/tools/perf/util/synthetic-events.c
+++ b/tools/perf/util/synthetic-events.c
-@@ -371,7 +371,7 @@ static void perf_record_mmap2__read_build_id(struct perf_record_mmap2 *event,
+@@ -371,7 +371,7 @@ static void perf_record_mmap2__read_buil
struct nsinfo *nsi;
struct nscookie nc;
struct dso *dso = NULL;
int rc;
if (is_kernel) {
-@@ -379,12 +379,18 @@ static void perf_record_mmap2__read_build_id(struct perf_record_mmap2 *event,
+@@ -379,12 +379,18 @@ static void perf_record_mmap2__read_buil
goto out;
}
if (dso && dso__has_build_id(dso)) {
bid = *dso__bid(dso);
rc = 0;
---
-2.53.0
-
+++ /dev/null
-From eba47f83066bc843c9348dc0399dae2d03c7f7fa Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 18 May 2026 15:43:24 -0700
-Subject: perf event: Fix size of synthesized sample with branch stacks
-
-From: Ian Rogers <irogers@google.com>
-
-[ Upstream commit 059e9100d82aae2254f1b06835a55755936b1417 ]
-
-Synthesizing branch stacks for Intel-PT highlighted an issue where
-PERF_SAMPLE_BRANCH_HW_INDEX was assumed to always be set in the
-perf_event_attr branch_sample_type. This caused an incorrect size
-calculation.
-
-Fix the writing of the nr and hw_idx values during sample event
-synthesis by passing the branch_sample_type into the sample size
-and synthesis functions. Also update hardware tracers (Intel PT,
-ARM SPE, CS-ETM) to retrieve and pass their branch_sample_type
-dynamically to prevent payload misalignment.
-
-Fixes: d3f85437ad6a5511 ("perf evsel: Support PERF_SAMPLE_BRANCH_HW_INDEX")
-Assisted-by: Gemini:gemini-3.1-pro-preview
-Signed-off-by: Ian Rogers <irogers@google.com>
-Acked-by: Namhyung Kim <namhyung@kernel.org>
-Cc: Adrian Hunter <adrian.hunter@intel.com>
-Cc: Dapeng Mi <dapeng1.mi@linux.intel.com>
-Cc: Ingo Molnar <mingo@redhat.com>
-Cc: James Clark <james.clark@linaro.org>
-Cc: Kan Liang <kan.liang@linux.intel.com>
-Cc: Leo Yan <leo.yan@linux.dev>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Cc: Ravi Bangoria <ravi.bangoria@amd.com>
-Cc: Thomas Falcon <thomas.falcon@intel.com>
-Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- tools/perf/bench/inject-buildid.c | 9 ++++++---
- tools/perf/builtin-inject.c | 12 +++++++++---
- tools/perf/tests/dlfilter-test.c | 8 ++++++--
- tools/perf/tests/sample-parsing.c | 5 +++--
- tools/perf/util/arm-spe.c | 28 ++++++++++++++++++++++++----
- tools/perf/util/cs-etm.c | 28 +++++++++++++++++++++++-----
- tools/perf/util/intel-bts.c | 3 ++-
- tools/perf/util/intel-pt.c | 27 +++++++++++++++++++++++----
- tools/perf/util/synthetic-events.c | 25 ++++++++++++++++++-------
- tools/perf/util/synthetic-events.h | 6 ++++--
- 10 files changed, 118 insertions(+), 33 deletions(-)
-
-diff --git a/tools/perf/bench/inject-buildid.c b/tools/perf/bench/inject-buildid.c
-index a759eb2328bead..a77957b4697a9e 100644
---- a/tools/perf/bench/inject-buildid.c
-+++ b/tools/perf/bench/inject-buildid.c
-@@ -228,9 +228,12 @@ static ssize_t synthesize_sample(struct bench_data *data, struct bench_dso *dso,
-
- event.header.type = PERF_RECORD_SAMPLE;
- event.header.misc = PERF_RECORD_MISC_USER;
-- event.header.size = perf_event__sample_event_size(&sample, bench_sample_type, 0);
--
-- perf_event__synthesize_sample(&event, bench_sample_type, 0, &sample);
-+ event.header.size = perf_event__sample_event_size(&sample, bench_sample_type,
-+ /*read_format=*/0,
-+ /*branch_sample_type=*/0);
-+ perf_event__synthesize_sample(&event, bench_sample_type,
-+ /*read_format=*/0,
-+ /*branch_sample_type=*/0, &sample);
-
- return writen(data->input_pipe[1], &event, event.header.size);
- }
-diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
-index 241d7e36914872..82683a57ad6c13 100644
---- a/tools/perf/builtin-inject.c
-+++ b/tools/perf/builtin-inject.c
-@@ -477,8 +477,13 @@ static int perf_event__convert_sample_callchain(const struct perf_tool *tool,
- /* remove sample_type {STACK,REGS}_USER for synthesize */
- sample_type &= ~(PERF_SAMPLE_STACK_USER | PERF_SAMPLE_REGS_USER);
-
-- perf_event__synthesize_sample(event_copy, sample_type,
-- evsel->core.attr.read_format, sample);
-+ ret = perf_event__synthesize_sample(event_copy, sample_type,
-+ evsel->core.attr.read_format,
-+ evsel->core.attr.branch_sample_type, sample);
-+ if (ret) {
-+ pr_err("Failed to synthesize sample\n");
-+ return ret;
-+ }
- return perf_event__repipe_synth(tool, event_copy);
- }
-
-@@ -1107,7 +1112,8 @@ static int perf_inject__sched_stat(const struct perf_tool *tool,
- sample_sw.period = sample->period;
- sample_sw.time = sample->time;
- perf_event__synthesize_sample(event_sw, evsel->core.attr.sample_type,
-- evsel->core.attr.read_format, &sample_sw);
-+ evsel->core.attr.read_format,
-+ evsel->core.attr.branch_sample_type, &sample_sw);
- build_id__mark_dso_hit(tool, event_sw, &sample_sw, evsel, machine);
- return perf_event__repipe(tool, event_sw, &sample_sw, machine);
- }
-diff --git a/tools/perf/tests/dlfilter-test.c b/tools/perf/tests/dlfilter-test.c
-index 54f59d1246bc53..1e75c5441f48fc 100644
---- a/tools/perf/tests/dlfilter-test.c
-+++ b/tools/perf/tests/dlfilter-test.c
-@@ -189,8 +189,12 @@ static int write_sample(struct test_data *td, u64 sample_type, u64 id, pid_t pid
-
- event->header.type = PERF_RECORD_SAMPLE;
- event->header.misc = PERF_RECORD_MISC_USER;
-- event->header.size = perf_event__sample_event_size(&sample, sample_type, 0);
-- err = perf_event__synthesize_sample(event, sample_type, 0, &sample);
-+ event->header.size = perf_event__sample_event_size(&sample, sample_type,
-+ /*read_format=*/0,
-+ /*branch_sample_type=*/0);
-+ err = perf_event__synthesize_sample(event, sample_type,
-+ /*read_format=*/0,
-+ /*branch_sample_type=*/0, &sample);
- if (err)
- return test_result("perf_event__synthesize_sample() failed", TEST_FAIL);
-
-diff --git a/tools/perf/tests/sample-parsing.c b/tools/perf/tests/sample-parsing.c
-index 25a3f6cece5054..64744f678705d7 100644
---- a/tools/perf/tests/sample-parsing.c
-+++ b/tools/perf/tests/sample-parsing.c
-@@ -294,7 +294,8 @@ static int do_test(u64 sample_type, u64 sample_regs, u64 read_format)
- sample.read.one.lost = 1;
- }
-
-- sz = perf_event__sample_event_size(&sample, sample_type, read_format);
-+ sz = perf_event__sample_event_size(&sample, sample_type, read_format,
-+ evsel.core.attr.branch_sample_type);
- bufsz = sz + 4096; /* Add a bit for overrun checking */
- event = malloc(bufsz);
- if (!event) {
-@@ -308,7 +309,7 @@ static int do_test(u64 sample_type, u64 sample_regs, u64 read_format)
- event->header.size = sz;
-
- err = perf_event__synthesize_sample(event, sample_type, read_format,
-- &sample);
-+ evsel.core.attr.branch_sample_type, &sample);
- if (err) {
- pr_debug("%s failed for sample_type %#"PRIx64", error %d\n",
- "perf_event__synthesize_sample", sample_type, err);
-diff --git a/tools/perf/util/arm-spe.c b/tools/perf/util/arm-spe.c
-index 80fcb8b10f52e4..a63ff5ff364502 100644
---- a/tools/perf/util/arm-spe.c
-+++ b/tools/perf/util/arm-spe.c
-@@ -411,10 +411,30 @@ static void arm_spe__prep_branch_stack(struct arm_spe_queue *speq)
- bstack->hw_idx = -1ULL;
- }
-
--static int arm_spe__inject_event(union perf_event *event, struct perf_sample *sample, u64 type)
-+static int arm_spe__inject_event(struct arm_spe *spe, union perf_event *event,
-+ struct perf_sample *sample, u64 type)
- {
-- event->header.size = perf_event__sample_event_size(sample, type, 0);
-- return perf_event__synthesize_sample(event, type, 0, sample);
-+ struct evsel *evsel = sample->evsel;
-+ u64 branch_sample_type = 0;
-+ size_t sz;
-+
-+ if (!evsel && spe->session && spe->session->evlist)
-+ evsel = evlist__id2evsel(spe->session->evlist, sample->id);
-+
-+ if (evsel)
-+ branch_sample_type = evsel->core.attr.branch_sample_type;
-+
-+ event->header.type = PERF_RECORD_SAMPLE;
-+ sz = perf_event__sample_event_size(sample, type, /*read_format=*/0,
-+ branch_sample_type);
-+ if (sz >= PERF_SAMPLE_MAX_SIZE) {
-+ pr_err("Sample size %zu exceeds max size %d\n", sz, PERF_SAMPLE_MAX_SIZE);
-+ return -EFAULT;
-+ }
-+ event->header.size = sz;
-+
-+ return perf_event__synthesize_sample(event, type, /*read_format=*/0,
-+ branch_sample_type, sample);
- }
-
- static inline int
-@@ -426,7 +446,7 @@ arm_spe_deliver_synth_event(struct arm_spe *spe,
- int ret;
-
- if (spe->synth_opts.inject) {
-- ret = arm_spe__inject_event(event, sample, spe->sample_type);
-+ ret = arm_spe__inject_event(spe, event, sample, spe->sample_type);
- if (ret)
- return ret;
- }
-diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
-index 0bf9e5c27b599b..51994ccbfbcb52 100644
---- a/tools/perf/util/cs-etm.c
-+++ b/tools/perf/util/cs-etm.c
-@@ -1416,11 +1416,29 @@ static void cs_etm__update_last_branch_rb(struct cs_etm_queue *etmq,
- bs->nr += 1;
- }
-
--static int cs_etm__inject_event(union perf_event *event,
-+static int cs_etm__inject_event(struct cs_etm_auxtrace *etm, union perf_event *event,
- struct perf_sample *sample, u64 type)
- {
-- event->header.size = perf_event__sample_event_size(sample, type, 0);
-- return perf_event__synthesize_sample(event, type, 0, sample);
-+ struct evsel *evsel = sample->evsel;
-+ u64 branch_sample_type = 0;
-+ size_t sz;
-+
-+ if (!evsel && etm->session && etm->session->evlist)
-+ evsel = evlist__id2evsel(etm->session->evlist, sample->id);
-+
-+ if (evsel)
-+ branch_sample_type = evsel->core.attr.branch_sample_type;
-+
-+ sz = perf_event__sample_event_size(sample, type, /*read_format=*/0,
-+ branch_sample_type);
-+ if (sz >= PERF_SAMPLE_MAX_SIZE) {
-+ pr_err("Sample size %zu exceeds max size %d\n", sz, PERF_SAMPLE_MAX_SIZE);
-+ return -EFAULT;
-+ }
-+ event->header.size = sz;
-+
-+ return perf_event__synthesize_sample(event, type, /*read_format=*/0,
-+ branch_sample_type, sample);
- }
-
-
-@@ -1585,7 +1603,7 @@ static int cs_etm__synth_instruction_sample(struct cs_etm_queue *etmq,
- sample.branch_stack = tidq->last_branch;
-
- if (etm->synth_opts.inject) {
-- ret = cs_etm__inject_event(event, &sample,
-+ ret = cs_etm__inject_event(etm, event, &sample,
- etm->instructions_sample_type);
- if (ret)
- return ret;
-@@ -1659,7 +1677,7 @@ static int cs_etm__synth_branch_sample(struct cs_etm_queue *etmq,
- }
-
- if (etm->synth_opts.inject) {
-- ret = cs_etm__inject_event(event, &sample,
-+ ret = cs_etm__inject_event(etm, event, &sample,
- etm->branches_sample_type);
- if (ret)
- return ret;
-diff --git a/tools/perf/util/intel-bts.c b/tools/perf/util/intel-bts.c
-index 27d9b5c9fec8be..7f50351fada2ef 100644
---- a/tools/perf/util/intel-bts.c
-+++ b/tools/perf/util/intel-bts.c
-@@ -302,7 +302,8 @@ static int intel_bts_synth_branch_sample(struct intel_bts_queue *btsq,
- event.sample.header.size = bts->branches_event_size;
- ret = perf_event__synthesize_sample(&event,
- bts->branches_sample_type,
-- 0, &sample);
-+ /*read_format=*/0, /*branch_sample_type=*/0,
-+ &sample);
- if (ret)
- return ret;
- }
-diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c
-index 61f10578e12121..627ff17e9b6615 100644
---- a/tools/perf/util/intel-pt.c
-+++ b/tools/perf/util/intel-pt.c
-@@ -1728,11 +1728,30 @@ static void intel_pt_prep_b_sample(struct intel_pt *pt,
- event->sample.header.misc = sample->cpumode;
- }
-
--static int intel_pt_inject_event(union perf_event *event,
-+static int intel_pt_inject_event(struct intel_pt *pt, union perf_event *event,
- struct perf_sample *sample, u64 type)
- {
-- event->header.size = perf_event__sample_event_size(sample, type, 0);
-- return perf_event__synthesize_sample(event, type, 0, sample);
-+ struct evsel *evsel = sample->evsel;
-+ u64 branch_sample_type = 0;
-+ size_t sz;
-+
-+ if (!evsel && pt->session && pt->session->evlist)
-+ evsel = evlist__id2evsel(pt->session->evlist, sample->id);
-+
-+ if (evsel)
-+ branch_sample_type = evsel->core.attr.branch_sample_type;
-+
-+ event->header.type = PERF_RECORD_SAMPLE;
-+ sz = perf_event__sample_event_size(sample, type, /*read_format=*/0,
-+ branch_sample_type);
-+ if (sz >= PERF_SAMPLE_MAX_SIZE) {
-+ pr_err("Sample size %zu exceeds max size %d\n", sz, PERF_SAMPLE_MAX_SIZE);
-+ return -EFAULT;
-+ }
-+ event->header.size = sz;
-+
-+ return perf_event__synthesize_sample(event, type, /*read_format=*/0,
-+ branch_sample_type, sample);
- }
-
- static inline int intel_pt_opt_inject(struct intel_pt *pt,
-@@ -1742,7 +1761,7 @@ static inline int intel_pt_opt_inject(struct intel_pt *pt,
- if (!pt->synth_opts.inject)
- return 0;
-
-- return intel_pt_inject_event(event, sample, type);
-+ return intel_pt_inject_event(pt, event, sample, type);
- }
-
- static int intel_pt_deliver_synth_event(struct intel_pt *pt,
-diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic-events.c
-index a58444c4aed1f1..ef9ad891ef09b5 100644
---- a/tools/perf/util/synthetic-events.c
-+++ b/tools/perf/util/synthetic-events.c
-@@ -1442,7 +1442,8 @@ int perf_event__synthesize_stat_round(const struct perf_tool *tool,
- return process(tool, (union perf_event *) &event, NULL, machine);
- }
-
--size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type, u64 read_format)
-+size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type, u64 read_format,
-+ u64 branch_sample_type)
- {
- size_t sz, result = sizeof(struct perf_record_sample);
-
-@@ -1502,8 +1503,10 @@ size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type,
-
- if (type & PERF_SAMPLE_BRANCH_STACK) {
- sz = sample->branch_stack->nr * sizeof(struct branch_entry);
-- /* nr, hw_idx */
-- sz += 2 * sizeof(u64);
-+ /* nr */
-+ sz += sizeof(u64);
-+ if (branch_sample_type & PERF_SAMPLE_BRANCH_HW_INDEX)
-+ sz += sizeof(u64);
- result += sz;
- }
-
-@@ -1586,7 +1589,7 @@ static __u64 *copy_read_group_values(__u64 *array, __u64 read_format,
- }
-
- int perf_event__synthesize_sample(union perf_event *event, u64 type, u64 read_format,
-- const struct perf_sample *sample)
-+ u64 branch_sample_type, const struct perf_sample *sample)
- {
- __u64 *array;
- size_t sz;
-@@ -1696,9 +1699,17 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type, u64 read_fo
-
- if (type & PERF_SAMPLE_BRANCH_STACK) {
- sz = sample->branch_stack->nr * sizeof(struct branch_entry);
-- /* nr, hw_idx */
-- sz += 2 * sizeof(u64);
-- memcpy(array, sample->branch_stack, sz);
-+
-+ *array++ = sample->branch_stack->nr;
-+
-+ if (branch_sample_type & PERF_SAMPLE_BRANCH_HW_INDEX) {
-+ if (sample->no_hw_idx)
-+ *array++ = 0;
-+ else
-+ *array++ = sample->branch_stack->hw_idx;
-+ }
-+
-+ memcpy(array, perf_sample__branch_entries((struct perf_sample *)sample), sz);
- array = (void *)array + sz;
- }
-
-diff --git a/tools/perf/util/synthetic-events.h b/tools/perf/util/synthetic-events.h
-index b9c936b5cfeb9c..ae989b76cb8e4c 100644
---- a/tools/perf/util/synthetic-events.h
-+++ b/tools/perf/util/synthetic-events.h
-@@ -81,7 +81,8 @@ int perf_event__synthesize_mmap_events(const struct perf_tool *tool, union perf_
- int perf_event__synthesize_modules(const struct perf_tool *tool, perf_event__handler_t process, struct machine *machine);
- int perf_event__synthesize_namespaces(const struct perf_tool *tool, union perf_event *event, pid_t pid, pid_t tgid, perf_event__handler_t process, struct machine *machine);
- int perf_event__synthesize_cgroups(const struct perf_tool *tool, perf_event__handler_t process, struct machine *machine);
--int perf_event__synthesize_sample(union perf_event *event, u64 type, u64 read_format, const struct perf_sample *sample);
-+int perf_event__synthesize_sample(union perf_event *event, u64 type, u64 read_format,
-+ u64 branch_sample_type, const struct perf_sample *sample);
- int perf_event__synthesize_stat_config(const struct perf_tool *tool, struct perf_stat_config *config, perf_event__handler_t process, struct machine *machine);
- int perf_event__synthesize_stat_events(struct perf_stat_config *config, const struct perf_tool *tool, struct evlist *evlist, perf_event__handler_t process, bool attrs);
- int perf_event__synthesize_stat_round(const struct perf_tool *tool, u64 time, u64 type, perf_event__handler_t process, struct machine *machine);
-@@ -95,7 +96,8 @@ pid_t perf_event__synthesize_comm(const struct perf_tool *tool, union perf_event
-
- int perf_tool__process_synth_event(const struct perf_tool *tool, union perf_event *event, struct machine *machine, perf_event__handler_t process);
-
--size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type, u64 read_format);
-+size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type,
-+ u64 read_format, u64 branch_sample_type);
-
- int __machine__synthesize_threads(struct machine *machine, const struct perf_tool *tool,
- struct target *target, struct perf_thread_map *threads,
---
-2.53.0
-
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
-@@ -2739,7 +2739,7 @@ int cmd_inject(int argc, const char **ar
+@@ -2733,7 +2733,7 @@ int cmd_inject(int argc, const char **ar
}
evlist__for_each_entry(inject.session->evlist, evsel) {
perf-arm-spe-correctly-set-sample-flags.patch
perf-arm-spe-add-branch-stack.patch
perf-inject-add-convert-callchain-option.patch
-perf-event-fix-size-of-synthesized-sample-with-branc.patch
staging-most-video-avoid-double-free-on-video-regist.patch
usb-host-max3421-fix-shift-out-of-bounds-in-max3421_.patch
usb-host-max3421-reject-hub-port-requests-for-non-ex.patch
}
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
-@@ -555,7 +555,8 @@ static int perf_event__convert_sample_ca
+@@ -452,7 +452,8 @@ static int perf_event__convert_sample_ca
node = cursor->first;
for (k = 0; k < cursor->nr && i < PERF_MAX_STACK_DEPTH; k++) {
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
- tools/perf/util/cs-etm.c | 25 +++++++++++++++++++++++--
+ tools/perf/util/cs-etm.c | 25 +++++++++++++++++++++++--
1 file changed, 23 insertions(+), 2 deletions(-)
-diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
-index f2ea3cbea0fdfe..7a3c122fbcaebc 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
-@@ -292,8 +292,11 @@ static struct cs_etm_queue *cs_etm__get_queue(struct cs_etm_auxtrace *etm, int c
+@@ -292,8 +292,11 @@ static struct cs_etm_queue *cs_etm__get_
{
if (etm->per_thread_decoding)
return etm->queues.queue_array[0].priv;
}
static int cs_etm__map_trace_id_v0(struct cs_etm_auxtrace *etm, u8 trace_chan_id,
-@@ -306,6 +309,9 @@ static int cs_etm__map_trace_id_v0(struct cs_etm_auxtrace *etm, u8 trace_chan_id
+@@ -306,6 +309,9 @@ static int cs_etm__map_trace_id_v0(struc
* queue associated with that CPU so only one decoder is made.
*/
etmq = cs_etm__get_queue(etm, cpu_metadata[CS_ETM_CPU]);
if (etmq->format == UNFORMATTED)
return cs_etm__insert_trace_id_node(etmq, trace_chan_id,
cpu_metadata);
-@@ -318,6 +324,9 @@ static int cs_etm__map_trace_id_v0(struct cs_etm_auxtrace *etm, u8 trace_chan_id
+@@ -318,6 +324,9 @@ static int cs_etm__map_trace_id_v0(struc
int ret;
etmq = etm->queues.queue_array[i].priv;
ret = cs_etm__insert_trace_id_node(etmq, trace_chan_id,
cpu_metadata);
if (ret)
-@@ -358,6 +367,9 @@ static int cs_etm__process_trace_id_v0_1(struct cs_etm_auxtrace *etm, int cpu,
+@@ -358,6 +367,9 @@ static int cs_etm__process_trace_id_v0_1
u32 sink_id = FIELD_GET(CS_AUX_HW_ID_SINK_ID_MASK, hw_id);
u8 trace_id = FIELD_GET(CS_AUX_HW_ID_TRACE_ID_MASK, hw_id);
/*
* Check sink id hasn't changed in per-cpu mode. In per-thread mode,
* let it pass for now until an actual overlapping trace ID is hit. In
-@@ -375,6 +387,9 @@ static int cs_etm__process_trace_id_v0_1(struct cs_etm_auxtrace *etm, int cpu,
+@@ -375,6 +387,9 @@ static int cs_etm__process_trace_id_v0_1
for (unsigned int i = 0; i < etm->queues.nr_queues; ++i) {
struct cs_etm_queue *other_etmq = etm->queues.queue_array[i].priv;
/* Different sinks, skip */
if (other_etmq->sink_id != etmq->sink_id)
continue;
-@@ -396,6 +411,9 @@ static int cs_etm__process_trace_id_v0_1(struct cs_etm_auxtrace *etm, int cpu,
+@@ -396,6 +411,9 @@ static int cs_etm__process_trace_id_v0_1
}
cpu_data = get_cpu_data(etm, cpu);
ret = cs_etm__insert_trace_id_node(etmq, trace_id, cpu_data);
if (ret)
return ret;
-@@ -3155,6 +3173,9 @@ static int cs_etm__queue_aux_fragment(struct perf_session *session, off_t file_o
+@@ -3137,6 +3155,9 @@ static int cs_etm__queue_aux_fragment(st
aux_offset + aux_size <= auxtrace_event->offset + auxtrace_event->size) {
struct cs_etm_queue *etmq = cs_etm__get_queue(etm, auxtrace_event->cpu);
/*
* If this AUX event was inside this buffer somewhere, create a new auxtrace event
* based on the sizes of the aux event, and queue that fragment.
---
-2.53.0
-
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
- .../perf/util/cs-etm-decoder/cs-etm-decoder.c | 21 +-
- tools/perf/util/cs-etm.c | 236 +++++++++++-------
- tools/perf/util/cs-etm.h | 8 +-
+ tools/perf/util/cs-etm-decoder/cs-etm-decoder.c | 21 +-
+ tools/perf/util/cs-etm.c | 236 ++++++++++++++----------
+ tools/perf/util/cs-etm.h | 8
3 files changed, 163 insertions(+), 102 deletions(-)
-diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
-index 43ac711a4e2ae7..4f66ff9fe7f615 100644
--- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
+++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
-@@ -399,6 +399,8 @@ cs_etm_decoder__buffer_packet(struct cs_etm_queue *etmq,
+@@ -399,6 +399,8 @@ cs_etm_decoder__buffer_packet(struct cs_
packet_queue->packet_buffer[et].flags = 0;
packet_queue->packet_buffer[et].exception_number = UINT32_MAX;
packet_queue->packet_buffer[et].trace_chan_id = trace_chan_id;
if (packet_queue->packet_count == CS_ETM_PACKET_MAX_BUFFER - 1)
return OCSD_RESP_WAIT;
-@@ -446,6 +448,7 @@ cs_etm_decoder__buffer_range(struct cs_etm_queue *etmq,
+@@ -446,6 +448,7 @@ cs_etm_decoder__buffer_range(struct cs_e
packet->last_instr_type = elem->last_i_type;
packet->last_instr_subtype = elem->last_i_subtype;
packet->last_instr_cond = elem->last_instr_cond;
if (elem->last_i_type == OCSD_INSTR_BR || elem->last_i_type == OCSD_INSTR_BR_INDIRECT)
packet->last_instr_taken_branch = elem->last_instr_exec;
-@@ -522,7 +525,9 @@ cs_etm_decoder__set_tid(struct cs_etm_queue *etmq,
+@@ -522,7 +525,9 @@ cs_etm_decoder__set_tid(struct cs_etm_qu
const ocsd_generic_trace_elem *elem,
const uint8_t trace_chan_id)
{
/*
* Process the PE_CONTEXT packets if we have a valid contextID or VMID.
-@@ -543,12 +548,18 @@ cs_etm_decoder__set_tid(struct cs_etm_queue *etmq,
+@@ -543,12 +548,18 @@ cs_etm_decoder__set_tid(struct cs_etm_qu
break;
}
/*
* A timestamp is generated after a PE_CONTEXT element so make sure
-@@ -556,7 +567,7 @@ cs_etm_decoder__set_tid(struct cs_etm_queue *etmq,
+@@ -556,7 +567,7 @@ cs_etm_decoder__set_tid(struct cs_etm_qu
*/
cs_etm_decoder__reset_timestamp(packet_queue);
}
static ocsd_datapath_resp_t cs_etm_decoder__gen_trace_elem_printer(
-diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
-index 0d4c510a33febe..0e30d67ec18464 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
@@ -86,15 +86,22 @@ struct cs_etm_traceid_queue {
};
enum cs_etm_format {
-@@ -615,10 +622,11 @@ static int cs_etm__init_traceid_queue(struct cs_etm_queue *etmq,
+@@ -615,10 +622,11 @@ static int cs_etm__init_traceid_queue(st
queue = &etmq->etm->queues.queue_array[etmq->queue_nr];
tidq->trace_chan_id = trace_chan_id;
tidq->packet = zalloc(sizeof(struct cs_etm_packet));
if (!tidq->packet)
-@@ -751,21 +759,10 @@ static void cs_etm__packet_swap(struct cs_etm_auxtrace *etm,
+@@ -751,21 +759,10 @@ static void cs_etm__packet_swap(struct c
/*
* Swap PACKET with PREV_PACKET: PACKET becomes PREV_PACKET for
* the next incoming packet.
}
}
-@@ -938,8 +935,8 @@ static void cs_etm__free_traceid_queues(struct cs_etm_queue *etmq)
+@@ -938,8 +935,8 @@ static void cs_etm__free_traceid_queues(
/* Free this traceid_queue from the array */
tidq = etmq->traceid_queues[idx];
zfree(&tidq->event_buf);
zfree(&tidq->last_branch);
zfree(&tidq->last_branch_rb);
-@@ -1084,47 +1081,43 @@ static u8 cs_etm__cpu_mode(struct cs_etm_queue *etmq, u64 address,
+@@ -1084,47 +1081,43 @@ static u8 cs_etm__cpu_mode(struct cs_etm
}
}
goto out;
dso = map__dso(al.map);
-@@ -1139,7 +1132,7 @@ static u32 cs_etm__mem_access(struct cs_etm_queue *etmq, u8 trace_chan_id,
+@@ -1139,7 +1132,7 @@ static u32 cs_etm__mem_access(struct cs_
map__load(al.map);
offset, buffer, size);
if (len <= 0) {
-@@ -1159,6 +1152,30 @@ static u32 cs_etm__mem_access(struct cs_etm_queue *etmq, u8 trace_chan_id,
+@@ -1159,6 +1152,30 @@ out:
return ret;
}
static struct cs_etm_queue *cs_etm__alloc_queue(void)
{
struct cs_etm_queue *etmq = zalloc(sizeof(*etmq));
-@@ -1334,12 +1351,13 @@ void cs_etm__reset_last_branch_rb(struct cs_etm_traceid_queue *tidq)
+@@ -1334,12 +1351,13 @@ void cs_etm__reset_last_branch_rb(struct
}
static inline int cs_etm__t32_instr_size(struct cs_etm_queue *etmq,
/*
* T32 instruction size is indicated by bits[15:11] of the first
* 16-bit word of the instruction: 0b11101, 0b11110 and 0b11111
-@@ -1372,16 +1390,16 @@ u64 cs_etm__last_executed_instr(const struct cs_etm_packet *packet)
+@@ -1372,16 +1390,16 @@ u64 cs_etm__last_executed_instr(const st
}
static inline u64 cs_etm__instr_addr(struct cs_etm_queue *etmq,
offset--;
}
return addr;
-@@ -1491,34 +1509,51 @@ cs_etm__get_trace(struct cs_etm_queue *etmq)
+@@ -1473,34 +1491,51 @@ cs_etm__get_trace(struct cs_etm_queue *e
return etmq->buf_len;
}
return 0;
}
-@@ -1528,8 +1563,8 @@ bool cs_etm__etmq_is_timeless(struct cs_etm_queue *etmq)
+@@ -1510,8 +1545,8 @@ bool cs_etm__etmq_is_timeless(struct cs_
}
static void cs_etm__copy_insn(struct cs_etm_queue *etmq,
struct perf_sample *sample)
{
/*
-@@ -1546,14 +1581,14 @@ static void cs_etm__copy_insn(struct cs_etm_queue *etmq,
+@@ -1528,14 +1563,14 @@ static void cs_etm__copy_insn(struct cs_
* cs_etm__t32_instr_size().
*/
if (packet->isa == CS_ETM_ISA_T32)
}
u64 cs_etm__convert_sample_time(struct cs_etm_queue *etmq, u64 cs_timestamp)
-@@ -1580,6 +1615,7 @@ static inline u64 cs_etm__resolve_sample_time(struct cs_etm_queue *etmq,
+@@ -1562,6 +1597,7 @@ static inline u64 cs_etm__resolve_sample
static int cs_etm__synth_instruction_sample(struct cs_etm_queue *etmq,
struct cs_etm_traceid_queue *tidq,
u64 addr, u64 period)
{
int ret = 0;
-@@ -1589,23 +1625,23 @@ static int cs_etm__synth_instruction_sample(struct cs_etm_queue *etmq,
+@@ -1571,23 +1607,23 @@ static int cs_etm__synth_instruction_sam
perf_sample__init(&sample, /*all=*/true);
event->sample.header.type = PERF_RECORD_SAMPLE;
if (etm->synth_opts.last_branch)
sample.branch_stack = tidq->last_branch;
-@@ -1650,15 +1686,15 @@ static int cs_etm__synth_branch_sample(struct cs_etm_queue *etmq,
+@@ -1632,15 +1668,15 @@ static int cs_etm__synth_branch_sample(s
event->sample.header.type = PERF_RECORD_SAMPLE;
event->sample.header.misc = cs_etm__cpu_mode(etmq, ip,
sample.addr = cs_etm__first_executed_instr(tidq->packet);
sample.id = etmq->etm->branches_id;
sample.stream_id = etmq->etm->branches_id;
-@@ -1667,8 +1703,7 @@ static int cs_etm__synth_branch_sample(struct cs_etm_queue *etmq,
+@@ -1649,8 +1685,7 @@ static int cs_etm__synth_branch_sample(s
sample.flags = tidq->prev_packet->flags;
sample.cpumode = event->sample.header.misc;
/*
* perf report cannot handle events without a branch stack
-@@ -1792,7 +1827,6 @@ static int cs_etm__sample(struct cs_etm_queue *etmq,
+@@ -1774,7 +1809,6 @@ static int cs_etm__sample(struct cs_etm_
{
struct cs_etm_auxtrace *etm = etmq->etm;
int ret;
u64 instrs_prev;
/* Get instructions remainder from previous packet */
-@@ -1878,10 +1912,10 @@ static int cs_etm__sample(struct cs_etm_queue *etmq,
+@@ -1860,10 +1894,10 @@ static int cs_etm__sample(struct cs_etm_
* been executed, but PC has not advanced to next
* instruction)
*/
etm->instructions_sample_period);
if (ret)
return ret;
-@@ -1963,7 +1997,7 @@ static int cs_etm__flush(struct cs_etm_queue *etmq,
+@@ -1945,7 +1979,7 @@ static int cs_etm__flush(struct cs_etm_q
addr = cs_etm__last_executed_instr(tidq->prev_packet);
err = cs_etm__synth_instruction_sample(
tidq->period_instructions);
if (err)
return err;
-@@ -2018,7 +2052,7 @@ static int cs_etm__end_block(struct cs_etm_queue *etmq,
+@@ -2000,7 +2034,7 @@ static int cs_etm__end_block(struct cs_e
addr = cs_etm__last_executed_instr(tidq->prev_packet);
err = cs_etm__synth_instruction_sample(
tidq->period_instructions);
if (err)
return err;
-@@ -2055,9 +2089,9 @@ static int cs_etm__get_data_block(struct cs_etm_queue *etmq)
+@@ -2037,9 +2071,9 @@ static int cs_etm__get_data_block(struct
return etmq->buf_len;
}
{
/* Initialise to keep compiler happy */
u16 instr16 = 0;
-@@ -2079,8 +2113,8 @@ static bool cs_etm__is_svc_instr(struct cs_etm_queue *etmq, u8 trace_chan_id,
+@@ -2061,8 +2095,8 @@ static bool cs_etm__is_svc_instr(struct
* so below only read 2 bytes as instruction size for T32.
*/
addr = end_addr - 2;
if ((instr16 & 0xFF00) == 0xDF00)
return true;
-@@ -2095,8 +2129,8 @@ static bool cs_etm__is_svc_instr(struct cs_etm_queue *etmq, u8 trace_chan_id,
+@@ -2077,8 +2111,8 @@ static bool cs_etm__is_svc_instr(struct
* +---------+---------+-------------------------+
*/
addr = end_addr - 4;
if ((instr32 & 0x0F000000) == 0x0F000000 &&
(instr32 & 0xF0000000) != 0xF0000000)
return true;
-@@ -2112,8 +2146,8 @@ static bool cs_etm__is_svc_instr(struct cs_etm_queue *etmq, u8 trace_chan_id,
+@@ -2094,8 +2128,8 @@ static bool cs_etm__is_svc_instr(struct
* +-----------------------+---------+-----------+
*/
addr = end_addr - 4;
if ((instr32 & 0xFFE0001F) == 0xd4000001)
return true;
-@@ -2129,7 +2163,6 @@ static bool cs_etm__is_svc_instr(struct cs_etm_queue *etmq, u8 trace_chan_id,
+@@ -2111,7 +2145,6 @@ static bool cs_etm__is_svc_instr(struct
static bool cs_etm__is_syscall(struct cs_etm_queue *etmq,
struct cs_etm_traceid_queue *tidq, u64 magic)
{
struct cs_etm_packet *packet = tidq->packet;
struct cs_etm_packet *prev_packet = tidq->prev_packet;
-@@ -2144,7 +2177,7 @@ static bool cs_etm__is_syscall(struct cs_etm_queue *etmq,
+@@ -2126,7 +2159,7 @@ static bool cs_etm__is_syscall(struct cs
*/
if (magic == __perf_cs_etmv4_magic) {
if (packet->exception_number == CS_ETMV4_EXC_CALL &&
prev_packet->end_addr))
return true;
}
-@@ -2182,7 +2215,6 @@ static bool cs_etm__is_sync_exception(struct cs_etm_queue *etmq,
+@@ -2164,7 +2197,6 @@ static bool cs_etm__is_sync_exception(st
struct cs_etm_traceid_queue *tidq,
u64 magic)
{
struct cs_etm_packet *packet = tidq->packet;
struct cs_etm_packet *prev_packet = tidq->prev_packet;
-@@ -2208,7 +2240,7 @@ static bool cs_etm__is_sync_exception(struct cs_etm_queue *etmq,
+@@ -2190,7 +2222,7 @@ static bool cs_etm__is_sync_exception(st
* (SMC, HVC) are taken as sync exceptions.
*/
if (packet->exception_number == CS_ETMV4_EXC_CALL &&
prev_packet->end_addr))
return true;
-@@ -2232,7 +2264,6 @@ static int cs_etm__set_sample_flags(struct cs_etm_queue *etmq,
+@@ -2214,7 +2246,6 @@ static int cs_etm__set_sample_flags(stru
{
struct cs_etm_packet *packet = tidq->packet;
struct cs_etm_packet *prev_packet = tidq->prev_packet;
u64 magic;
int ret;
-@@ -2313,11 +2344,11 @@ static int cs_etm__set_sample_flags(struct cs_etm_queue *etmq,
+@@ -2295,11 +2326,11 @@ static int cs_etm__set_sample_flags(stru
if (prev_packet->flags == (PERF_IP_FLAG_BRANCH |
PERF_IP_FLAG_RETURN |
PERF_IP_FLAG_INTERRUPT) &&
break;
case CS_ETM_DISCONTINUITY:
/*
-@@ -2398,6 +2429,7 @@ static int cs_etm__set_sample_flags(struct cs_etm_queue *etmq,
+@@ -2380,6 +2411,7 @@ static int cs_etm__set_sample_flags(stru
PERF_IP_FLAG_RETURN |
PERF_IP_FLAG_INTERRUPT;
break;
case CS_ETM_EMPTY:
default:
break;
-@@ -2473,6 +2505,19 @@ static int cs_etm__process_traceid_queue(struct cs_etm_queue *etmq,
+@@ -2455,6 +2487,19 @@ static int cs_etm__process_traceid_queue
*/
cs_etm__sample(etmq, tidq);
break;
case CS_ETM_EXCEPTION:
case CS_ETM_EXCEPTION_RET:
/*
-@@ -2501,6 +2546,7 @@ static int cs_etm__process_traceid_queue(struct cs_etm_queue *etmq,
+@@ -2483,6 +2528,7 @@ static int cs_etm__process_traceid_queue
}
}
return ret;
}
-@@ -2624,7 +2670,7 @@ static int cs_etm__process_timeless_queues(struct cs_etm_auxtrace *etm,
+@@ -2606,7 +2652,7 @@ static int cs_etm__process_timeless_queu
if (!tidq)
continue;
cs_etm__run_per_thread_timeless_decoder(etmq);
} else
cs_etm__run_per_cpu_timeless_decoder(etmq);
-@@ -3340,7 +3386,7 @@ static int cs_etm__create_queue_decoders(struct cs_etm_queue *etmq)
+@@ -3322,7 +3368,7 @@ static int cs_etm__create_queue_decoders
*/
if (cs_etm_decoder__add_mem_access_cb(etmq->decoder,
0x0L, ((u64) -1L),
goto out_free_decoder;
zfree(&t_params);
-diff --git a/tools/perf/util/cs-etm.h b/tools/perf/util/cs-etm.h
-index a8caeea720aa17..dfc9aeacfd0b62 100644
--- a/tools/perf/util/cs-etm.h
+++ b/tools/perf/util/cs-etm.h
@@ -158,6 +158,7 @@ enum cs_etm_sample_type {
bool cs_etm__etmq_is_timeless(struct cs_etm_queue *etmq);
void cs_etm__etmq_set_traceid_queue_timestamp(struct cs_etm_queue *etmq,
u8 trace_chan_id);
---
-2.53.0
-
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
- tools/perf/util/cs-etm.c | 9 ++++++++-
+ tools/perf/util/cs-etm.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
-diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
-index f939eb9edf7c7f..4e5b38db7b01be 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
@@ -6,6 +6,7 @@
#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/coresight-pmu.h>
-@@ -3479,7 +3480,13 @@ int cs_etm__process_auxtrace_info_full(union perf_event *event,
+@@ -3461,7 +3462,13 @@ int cs_etm__process_auxtrace_info_full(u
goto err_free_metadata;
}
max_cpu = metadata[j][CS_ETM_CPU];
}
---
-2.53.0
-
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
- tools/perf/util/cs-etm.c | 12 ++++++++++++
+ tools/perf/util/cs-etm.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
-diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
-index 4e5b38db7b01be..f2ea3cbea0fdfe 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
-@@ -3442,6 +3442,18 @@ int cs_etm__process_auxtrace_info_full(union perf_event *event,
+@@ -3424,6 +3424,18 @@ int cs_etm__process_auxtrace_info_full(u
/* First the global part */
ptr = (u64 *) auxtrace_info->priv;
num_cpu = ptr[CS_PMU_TYPE_CPUS] & 0xffffffff;
metadata = zalloc(sizeof(*metadata) * num_cpu);
if (!metadata)
return -ENOMEM;
---
-2.53.0
-
+++ /dev/null
-From 3d263c867b78699db7c46e24fbd1cdd5e18c3889 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 18 May 2026 15:43:24 -0700
-Subject: perf event: Fix size of synthesized sample with branch stacks
-
-From: Ian Rogers <irogers@google.com>
-
-[ Upstream commit 059e9100d82aae2254f1b06835a55755936b1417 ]
-
-Synthesizing branch stacks for Intel-PT highlighted an issue where
-PERF_SAMPLE_BRANCH_HW_INDEX was assumed to always be set in the
-perf_event_attr branch_sample_type. This caused an incorrect size
-calculation.
-
-Fix the writing of the nr and hw_idx values during sample event
-synthesis by passing the branch_sample_type into the sample size
-and synthesis functions. Also update hardware tracers (Intel PT,
-ARM SPE, CS-ETM) to retrieve and pass their branch_sample_type
-dynamically to prevent payload misalignment.
-
-Fixes: d3f85437ad6a5511 ("perf evsel: Support PERF_SAMPLE_BRANCH_HW_INDEX")
-Assisted-by: Gemini:gemini-3.1-pro-preview
-Signed-off-by: Ian Rogers <irogers@google.com>
-Acked-by: Namhyung Kim <namhyung@kernel.org>
-Cc: Adrian Hunter <adrian.hunter@intel.com>
-Cc: Dapeng Mi <dapeng1.mi@linux.intel.com>
-Cc: Ingo Molnar <mingo@redhat.com>
-Cc: James Clark <james.clark@linaro.org>
-Cc: Kan Liang <kan.liang@linux.intel.com>
-Cc: Leo Yan <leo.yan@linux.dev>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Cc: Ravi Bangoria <ravi.bangoria@amd.com>
-Cc: Thomas Falcon <thomas.falcon@intel.com>
-Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- tools/perf/bench/inject-buildid.c | 9 ++++++---
- tools/perf/builtin-inject.c | 12 +++++++++---
- tools/perf/tests/dlfilter-test.c | 8 ++++++--
- tools/perf/tests/sample-parsing.c | 5 +++--
- tools/perf/util/arm-spe.c | 28 ++++++++++++++++++++++++----
- tools/perf/util/cs-etm.c | 28 +++++++++++++++++++++++-----
- tools/perf/util/intel-bts.c | 3 ++-
- tools/perf/util/intel-pt.c | 27 +++++++++++++++++++++++----
- tools/perf/util/synthetic-events.c | 25 ++++++++++++++++++-------
- tools/perf/util/synthetic-events.h | 6 ++++--
- 10 files changed, 118 insertions(+), 33 deletions(-)
-
-diff --git a/tools/perf/bench/inject-buildid.c b/tools/perf/bench/inject-buildid.c
-index 12387ea88b9a9c..44c471682c3c4c 100644
---- a/tools/perf/bench/inject-buildid.c
-+++ b/tools/perf/bench/inject-buildid.c
-@@ -228,9 +228,12 @@ static ssize_t synthesize_sample(struct bench_data *data, struct bench_dso *dso,
-
- event.header.type = PERF_RECORD_SAMPLE;
- event.header.misc = PERF_RECORD_MISC_USER;
-- event.header.size = perf_event__sample_event_size(&sample, bench_sample_type, 0);
--
-- perf_event__synthesize_sample(&event, bench_sample_type, 0, &sample);
-+ event.header.size = perf_event__sample_event_size(&sample, bench_sample_type,
-+ /*read_format=*/0,
-+ /*branch_sample_type=*/0);
-+ perf_event__synthesize_sample(&event, bench_sample_type,
-+ /*read_format=*/0,
-+ /*branch_sample_type=*/0, &sample);
-
- return writen(data->input_pipe[1], &event, event.header.size);
- }
-diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
-index 9606b4bf109792..95517f17863751 100644
---- a/tools/perf/builtin-inject.c
-+++ b/tools/perf/builtin-inject.c
-@@ -477,8 +477,13 @@ static int perf_event__convert_sample_callchain(const struct perf_tool *tool,
- /* remove sample_type {STACK,REGS}_USER for synthesize */
- sample_type &= ~(PERF_SAMPLE_STACK_USER | PERF_SAMPLE_REGS_USER);
-
-- perf_event__synthesize_sample(event_copy, sample_type,
-- evsel->core.attr.read_format, sample);
-+ ret = perf_event__synthesize_sample(event_copy, sample_type,
-+ evsel->core.attr.read_format,
-+ evsel->core.attr.branch_sample_type, sample);
-+ if (ret) {
-+ pr_err("Failed to synthesize sample\n");
-+ return ret;
-+ }
- return perf_event__repipe_synth(tool, event_copy);
- }
-
-@@ -1113,7 +1118,8 @@ static int perf_inject__sched_stat(const struct perf_tool *tool,
- sample_sw.period = sample->period;
- sample_sw.time = sample->time;
- perf_event__synthesize_sample(event_sw, evsel->core.attr.sample_type,
-- evsel->core.attr.read_format, &sample_sw);
-+ evsel->core.attr.read_format,
-+ evsel->core.attr.branch_sample_type, &sample_sw);
- build_id__mark_dso_hit(tool, event_sw, &sample_sw, evsel, machine);
- return perf_event__repipe(tool, event_sw, &sample_sw, machine);
- }
-diff --git a/tools/perf/tests/dlfilter-test.c b/tools/perf/tests/dlfilter-test.c
-index 80a1c941138d31..2261aa4080d317 100644
---- a/tools/perf/tests/dlfilter-test.c
-+++ b/tools/perf/tests/dlfilter-test.c
-@@ -189,8 +189,12 @@ static int write_sample(struct test_data *td, u64 sample_type, u64 id, pid_t pid
-
- event->header.type = PERF_RECORD_SAMPLE;
- event->header.misc = PERF_RECORD_MISC_USER;
-- event->header.size = perf_event__sample_event_size(&sample, sample_type, 0);
-- err = perf_event__synthesize_sample(event, sample_type, 0, &sample);
-+ event->header.size = perf_event__sample_event_size(&sample, sample_type,
-+ /*read_format=*/0,
-+ /*branch_sample_type=*/0);
-+ err = perf_event__synthesize_sample(event, sample_type,
-+ /*read_format=*/0,
-+ /*branch_sample_type=*/0, &sample);
- if (err)
- return test_result("perf_event__synthesize_sample() failed", TEST_FAIL);
-
-diff --git a/tools/perf/tests/sample-parsing.c b/tools/perf/tests/sample-parsing.c
-index a7327c942ca209..55f0b73ca20e05 100644
---- a/tools/perf/tests/sample-parsing.c
-+++ b/tools/perf/tests/sample-parsing.c
-@@ -310,7 +310,8 @@ static int do_test(u64 sample_type, u64 sample_regs, u64 read_format)
- sample.read.one.lost = 1;
- }
-
-- sz = perf_event__sample_event_size(&sample, sample_type, read_format);
-+ sz = perf_event__sample_event_size(&sample, sample_type, read_format,
-+ evsel.core.attr.branch_sample_type);
- bufsz = sz + 4096; /* Add a bit for overrun checking */
- event = malloc(bufsz);
- if (!event) {
-@@ -324,7 +325,7 @@ static int do_test(u64 sample_type, u64 sample_regs, u64 read_format)
- event->header.size = sz;
-
- err = perf_event__synthesize_sample(event, sample_type, read_format,
-- &sample);
-+ evsel.core.attr.branch_sample_type, &sample);
- if (err) {
- pr_debug("%s failed for sample_type %#"PRIx64", error %d\n",
- "perf_event__synthesize_sample", sample_type, err);
-diff --git a/tools/perf/util/arm-spe.c b/tools/perf/util/arm-spe.c
-index 71be979f507718..a6fa6c546bdac4 100644
---- a/tools/perf/util/arm-spe.c
-+++ b/tools/perf/util/arm-spe.c
-@@ -466,10 +466,30 @@ static void arm_spe__prep_branch_stack(struct arm_spe_queue *speq)
- bstack->hw_idx = -1ULL;
- }
-
--static int arm_spe__inject_event(union perf_event *event, struct perf_sample *sample, u64 type)
-+static int arm_spe__inject_event(struct arm_spe *spe, union perf_event *event,
-+ struct perf_sample *sample, u64 type)
- {
-- event->header.size = perf_event__sample_event_size(sample, type, 0);
-- return perf_event__synthesize_sample(event, type, 0, sample);
-+ struct evsel *evsel = sample->evsel;
-+ u64 branch_sample_type = 0;
-+ size_t sz;
-+
-+ if (!evsel && spe->session && spe->session->evlist)
-+ evsel = evlist__id2evsel(spe->session->evlist, sample->id);
-+
-+ if (evsel)
-+ branch_sample_type = evsel->core.attr.branch_sample_type;
-+
-+ event->header.type = PERF_RECORD_SAMPLE;
-+ sz = perf_event__sample_event_size(sample, type, /*read_format=*/0,
-+ branch_sample_type);
-+ if (sz >= PERF_SAMPLE_MAX_SIZE) {
-+ pr_err("Sample size %zu exceeds max size %d\n", sz, PERF_SAMPLE_MAX_SIZE);
-+ return -EFAULT;
-+ }
-+ event->header.size = sz;
-+
-+ return perf_event__synthesize_sample(event, type, /*read_format=*/0,
-+ branch_sample_type, sample);
- }
-
- static inline int
-@@ -481,7 +501,7 @@ arm_spe_deliver_synth_event(struct arm_spe *spe,
- int ret;
-
- if (spe->synth_opts.inject) {
-- ret = arm_spe__inject_event(event, sample, spe->sample_type);
-+ ret = arm_spe__inject_event(spe, event, sample, spe->sample_type);
- if (ret)
- return ret;
- }
-diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
-index 06eb1a56430cbe..0d4c510a33febe 100644
---- a/tools/perf/util/cs-etm.c
-+++ b/tools/perf/util/cs-etm.c
-@@ -1423,11 +1423,29 @@ static void cs_etm__update_last_branch_rb(struct cs_etm_queue *etmq,
- bs->nr += 1;
- }
-
--static int cs_etm__inject_event(union perf_event *event,
-+static int cs_etm__inject_event(struct cs_etm_auxtrace *etm, union perf_event *event,
- struct perf_sample *sample, u64 type)
- {
-- event->header.size = perf_event__sample_event_size(sample, type, 0);
-- return perf_event__synthesize_sample(event, type, 0, sample);
-+ struct evsel *evsel = sample->evsel;
-+ u64 branch_sample_type = 0;
-+ size_t sz;
-+
-+ if (!evsel && etm->session && etm->session->evlist)
-+ evsel = evlist__id2evsel(etm->session->evlist, sample->id);
-+
-+ if (evsel)
-+ branch_sample_type = evsel->core.attr.branch_sample_type;
-+
-+ sz = perf_event__sample_event_size(sample, type, /*read_format=*/0,
-+ branch_sample_type);
-+ if (sz >= PERF_SAMPLE_MAX_SIZE) {
-+ pr_err("Sample size %zu exceeds max size %d\n", sz, PERF_SAMPLE_MAX_SIZE);
-+ return -EFAULT;
-+ }
-+ event->header.size = sz;
-+
-+ return perf_event__synthesize_sample(event, type, /*read_format=*/0,
-+ branch_sample_type, sample);
- }
-
-
-@@ -1593,7 +1611,7 @@ static int cs_etm__synth_instruction_sample(struct cs_etm_queue *etmq,
- sample.branch_stack = tidq->last_branch;
-
- if (etm->synth_opts.inject) {
-- ret = cs_etm__inject_event(event, &sample,
-+ ret = cs_etm__inject_event(etm, event, &sample,
- etm->instructions_sample_type);
- if (ret)
- return ret;
-@@ -1668,7 +1686,7 @@ static int cs_etm__synth_branch_sample(struct cs_etm_queue *etmq,
- }
-
- if (etm->synth_opts.inject) {
-- ret = cs_etm__inject_event(event, &sample,
-+ ret = cs_etm__inject_event(etm, event, &sample,
- etm->branches_sample_type);
- if (ret)
- return ret;
-diff --git a/tools/perf/util/intel-bts.c b/tools/perf/util/intel-bts.c
-index 3625c622475024..6ae65fe3fbe6bd 100644
---- a/tools/perf/util/intel-bts.c
-+++ b/tools/perf/util/intel-bts.c
-@@ -303,7 +303,8 @@ static int intel_bts_synth_branch_sample(struct intel_bts_queue *btsq,
- event.sample.header.size = bts->branches_event_size;
- ret = perf_event__synthesize_sample(&event,
- bts->branches_sample_type,
-- 0, &sample);
-+ /*read_format=*/0, /*branch_sample_type=*/0,
-+ &sample);
- if (ret)
- return ret;
- }
-diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c
-index 9b1011fe482671..c56d8d38b1e8fc 100644
---- a/tools/perf/util/intel-pt.c
-+++ b/tools/perf/util/intel-pt.c
-@@ -1728,11 +1728,30 @@ static void intel_pt_prep_b_sample(struct intel_pt *pt,
- event->sample.header.misc = sample->cpumode;
- }
-
--static int intel_pt_inject_event(union perf_event *event,
-+static int intel_pt_inject_event(struct intel_pt *pt, union perf_event *event,
- struct perf_sample *sample, u64 type)
- {
-- event->header.size = perf_event__sample_event_size(sample, type, 0);
-- return perf_event__synthesize_sample(event, type, 0, sample);
-+ struct evsel *evsel = sample->evsel;
-+ u64 branch_sample_type = 0;
-+ size_t sz;
-+
-+ if (!evsel && pt->session && pt->session->evlist)
-+ evsel = evlist__id2evsel(pt->session->evlist, sample->id);
-+
-+ if (evsel)
-+ branch_sample_type = evsel->core.attr.branch_sample_type;
-+
-+ event->header.type = PERF_RECORD_SAMPLE;
-+ sz = perf_event__sample_event_size(sample, type, /*read_format=*/0,
-+ branch_sample_type);
-+ if (sz >= PERF_SAMPLE_MAX_SIZE) {
-+ pr_err("Sample size %zu exceeds max size %d\n", sz, PERF_SAMPLE_MAX_SIZE);
-+ return -EFAULT;
-+ }
-+ event->header.size = sz;
-+
-+ return perf_event__synthesize_sample(event, type, /*read_format=*/0,
-+ branch_sample_type, sample);
- }
-
- static inline int intel_pt_opt_inject(struct intel_pt *pt,
-@@ -1742,7 +1761,7 @@ static inline int intel_pt_opt_inject(struct intel_pt *pt,
- if (!pt->synth_opts.inject)
- return 0;
-
-- return intel_pt_inject_event(event, sample, type);
-+ return intel_pt_inject_event(pt, event, sample, type);
- }
-
- static int intel_pt_deliver_synth_event(struct intel_pt *pt,
-diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic-events.c
-index c85d219928d47c..12f268032b492b 100644
---- a/tools/perf/util/synthetic-events.c
-+++ b/tools/perf/util/synthetic-events.c
-@@ -1455,7 +1455,8 @@ int perf_event__synthesize_stat_round(const struct perf_tool *tool,
- return process(tool, (union perf_event *) &event, NULL, machine);
- }
-
--size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type, u64 read_format)
-+size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type, u64 read_format,
-+ u64 branch_sample_type)
- {
- size_t sz, result = sizeof(struct perf_record_sample);
-
-@@ -1515,8 +1516,10 @@ size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type,
-
- if (type & PERF_SAMPLE_BRANCH_STACK) {
- sz = sample->branch_stack->nr * sizeof(struct branch_entry);
-- /* nr, hw_idx */
-- sz += 2 * sizeof(u64);
-+ /* nr */
-+ sz += sizeof(u64);
-+ if (branch_sample_type & PERF_SAMPLE_BRANCH_HW_INDEX)
-+ sz += sizeof(u64);
- result += sz;
- }
-
-@@ -1605,7 +1608,7 @@ static __u64 *copy_read_group_values(__u64 *array, __u64 read_format,
- }
-
- int perf_event__synthesize_sample(union perf_event *event, u64 type, u64 read_format,
-- const struct perf_sample *sample)
-+ u64 branch_sample_type, const struct perf_sample *sample)
- {
- __u64 *array;
- size_t sz;
-@@ -1719,9 +1722,17 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type, u64 read_fo
-
- if (type & PERF_SAMPLE_BRANCH_STACK) {
- sz = sample->branch_stack->nr * sizeof(struct branch_entry);
-- /* nr, hw_idx */
-- sz += 2 * sizeof(u64);
-- memcpy(array, sample->branch_stack, sz);
-+
-+ *array++ = sample->branch_stack->nr;
-+
-+ if (branch_sample_type & PERF_SAMPLE_BRANCH_HW_INDEX) {
-+ if (sample->no_hw_idx)
-+ *array++ = 0;
-+ else
-+ *array++ = sample->branch_stack->hw_idx;
-+ }
-+
-+ memcpy(array, perf_sample__branch_entries((struct perf_sample *)sample), sz);
- array = (void *)array + sz;
- }
-
-diff --git a/tools/perf/util/synthetic-events.h b/tools/perf/util/synthetic-events.h
-index ee29615d68e57f..5d9ab190a15d67 100644
---- a/tools/perf/util/synthetic-events.h
-+++ b/tools/perf/util/synthetic-events.h
-@@ -81,7 +81,8 @@ int perf_event__synthesize_mmap_events(const struct perf_tool *tool, union perf_
- int perf_event__synthesize_modules(const struct perf_tool *tool, perf_event__handler_t process, struct machine *machine);
- int perf_event__synthesize_namespaces(const struct perf_tool *tool, union perf_event *event, pid_t pid, pid_t tgid, perf_event__handler_t process, struct machine *machine);
- int perf_event__synthesize_cgroups(const struct perf_tool *tool, perf_event__handler_t process, struct machine *machine);
--int perf_event__synthesize_sample(union perf_event *event, u64 type, u64 read_format, const struct perf_sample *sample);
-+int perf_event__synthesize_sample(union perf_event *event, u64 type, u64 read_format,
-+ u64 branch_sample_type, const struct perf_sample *sample);
- int perf_event__synthesize_stat_config(const struct perf_tool *tool, struct perf_stat_config *config, perf_event__handler_t process, struct machine *machine);
- int perf_event__synthesize_stat_events(struct perf_stat_config *config, const struct perf_tool *tool, struct evlist *evlist, perf_event__handler_t process, bool attrs);
- int perf_event__synthesize_stat_round(const struct perf_tool *tool, u64 time, u64 type, perf_event__handler_t process, struct machine *machine);
-@@ -97,7 +98,8 @@ void perf_event__synthesize_final_bpf_metadata(struct perf_session *session,
-
- int perf_tool__process_synth_event(const struct perf_tool *tool, union perf_event *event, struct machine *machine, perf_event__handler_t process);
-
--size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type, u64 read_format);
-+size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type,
-+ u64 read_format, u64 branch_sample_type);
-
- int __machine__synthesize_threads(struct machine *machine, const struct perf_tool *tool,
- struct target *target, struct perf_thread_map *threads,
---
-2.53.0
-
+++ /dev/null
-From 10bf8d074c3e4f1e320e827156a3a394fb4100d2 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 18 May 2026 15:43:25 -0700
-Subject: perf inject: Fix itrace branch stack synthesis
-
-From: Ian Rogers <irogers@google.com>
-
-[ Upstream commit daac18e7c42c012e289bfd310503f9417e4a9481 ]
-
-When using "perf inject --itrace=L" to synthesize branch stacks from
-AUX data, several issues caused failures with the generated file:
-
-1. The synthesized samples were delivered without the
- PERF_SAMPLE_BRANCH_STACK flag if it was not in the original event's
- sample_type. Fixed by using sample_type | evsel->synth_sample_type
- in intel_pt_do_synth_pebs_sample.
-
-2. Modifying evsel->core.attr.sample_type early in __cmd_inject caused
- parse failures for subsequent records in the input file. Fixed by
- moving this modification to just before writing the header.
-
-3. perf_event__repipe_sample was narrowed to only synthesize samples
- when branch stack injection was requested, and restored the use of
- perf_inject__cut_auxtrace_sample as a fallback to preserve
- functionality.
-
-4. Potential Heap Overflow in perf_event__repipe_sample: Addressed by
- adding a check that prints an error and returns -EFAULT if the
- calculated event size exceeds PERF_SAMPLE_MAX_SIZE.
-
-5. Header vs Payload Mismatch in __cmd_inject: Addressed by narrowing
- the condition so that HEADER_BRANCH_STACK is only set in the file
- header if add_last_branch was true.
-
-6. NULL Pointer Dereference in intel-pt.c: When branch stack injection
- is requested (add_last_branch is true) but last_branch is false
- (e.g., perf inject --itrace=L), ptq->last_branch was not allocated.
- However, PEBS branch stack synthesis (via synth_sample_type) still
- forced LBR handling in do_synth_pebs_sample(), dereferencing the
- NULL ptq->last_branch pointer. Guarding the dereference is not
- sufficient because downstream sample size calculation and synthesis
- strictly require a non-NULL branch_stack when the bit is set.
- Fixed by ensuring ptq->last_branch is allocated in
- intel_pt_alloc_queue() when add_last_branch is requested.
-
-7. Modifying event attributes in perf_event__repipe_attr in-place caused
- SIGSEGV on read-only mmap buffers in file mode and downstream parser
- breakage in pipe mode. Fixed by processing the unmodified attribute
- first, returning immediately in non-pipe mode, and correctly
- synthesizing a new attribute event for pipe output using
- perf_event__synthesize_attr. Also:
- - Added a size validation check and integer underflow protection when
- parsing n_ids.
- - Prevented Trailing ID memory corruption by zero-initializing the
- local attr copy and safely copying using min_t(size_t, sizeof(attr),
- event->attr.attr.size).
- - Resolved ID array parsing mismatch downstream by expanding attr.size
- to sizeof(struct perf_event_attr) before synthesis to guarantee
- perfect header/attribute size alignment.
-
-8. Potential dangling pointer vulnerability in perf_event__repipe_sample:
- Addressed by restoring the original sample->branch_stack pointer
- before returning, including on early error return paths.
-
-9. Off-by-one error in sample size check in perf_event__repipe_sample:
- Fixed by checking if sz >= PERF_SAMPLE_MAX_SIZE instead of >.
-
-10. Unadvertised size field left in payload by cut_auxtrace_sample:
- Addressed by excluding the 8-byte size field from the copied
- payload to correctly match the cleared PERF_SAMPLE_AUX bit. Cut
- the AUX sample payload even if size is 0.
-
-11. Inaccurate sample size calculation and uninitialized memory leaks in
- convert_sample_callchain: Fixed by replacing manual arithmetic with
- perf_event__sample_event_size and adding a bounds check against
- PERF_SAMPLE_MAX_SIZE.
-
-12. Omission of branch_sample_type in file headers: Addressed by
- expanding older, smaller attributes to PERF_ATTR_SIZE_VER2 in
- __cmd_inject to ensure branch_sample_type is not silently omitted.
-
-Fixes: 0f0aa5e0693ce400 ("perf inject: Add Instruction Tracing support")
-Assisted-by: Gemini:gemini-3.1-pro-preview
-Signed-off-by: Ian Rogers <irogers@google.com>
-Cc: Adrian Hunter <adrian.hunter@intel.com>
-Cc: Dapeng Mi <dapeng1.mi@linux.intel.com>
-Cc: Ingo Molnar <mingo@redhat.com>
-Cc: James Clark <james.clark@linaro.org>
-Cc: Leo Yan <leo.yan@linux.dev>
-Cc: Namhyung Kim <namhyung@kernel.org>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Cc: Ravi Bangoria <ravi.bangoria@amd.com>
-Cc: Thomas Falcon <thomas.falcon@intel.com>
-Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- tools/perf/builtin-inject.c | 153 ++++++++++++++++++++++++++++++++----
- tools/perf/util/intel-pt.c | 8 +-
- 2 files changed, 142 insertions(+), 19 deletions(-)
-
-diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
-index 95517f17863751..015c9e6865dd97 100644
---- a/tools/perf/builtin-inject.c
-+++ b/tools/perf/builtin-inject.c
-@@ -213,12 +213,23 @@ static int perf_event__repipe_op4_synth(struct perf_session *session,
- return perf_event__repipe_synth(session->tool, event);
- }
-
-+static int perf_event__repipe_synth_cb(const struct perf_tool *tool,
-+ union perf_event *event,
-+ struct perf_sample *sample __maybe_unused,
-+ struct machine *machine __maybe_unused)
-+{
-+ return perf_event__repipe_synth(tool, event);
-+}
-+
- static int perf_event__repipe_attr(const struct perf_tool *tool,
- union perf_event *event,
- struct evlist **pevlist)
- {
- struct perf_inject *inject = container_of(tool, struct perf_inject,
- tool);
-+ struct perf_event_attr attr;
-+ size_t n_ids;
-+ u64 *ids;
- int ret;
-
- ret = perf_event__process_attr(tool, event, pevlist);
-@@ -229,7 +240,37 @@ static int perf_event__repipe_attr(const struct perf_tool *tool,
- if (!inject->output.is_pipe)
- return 0;
-
-- return perf_event__repipe_synth(tool, event);
-+ if (!inject->itrace_synth_opts.set)
-+ return perf_event__repipe_synth(tool, event);
-+
-+ if (event->header.size < sizeof(struct perf_event_header) + sizeof(u64)) {
-+ pr_err("Attribute event size %u is too small\n", event->header.size);
-+ return -EINVAL;
-+ }
-+
-+ if (event->header.size - sizeof(event->header) < event->attr.attr.size) {
-+ pr_err("Attribute event size %u is too small for attr.size %u\n",
-+ event->header.size, event->attr.attr.size);
-+ return -EINVAL;
-+ }
-+
-+ memset(&attr, 0, sizeof(attr));
-+ memcpy(&attr, &event->attr.attr,
-+ min_t(size_t, sizeof(attr), (size_t)event->attr.attr.size));
-+
-+ n_ids = event->header.size - sizeof(event->header) - event->attr.attr.size;
-+ n_ids /= sizeof(u64);
-+ ids = perf_record_header_attr_id(event);
-+
-+ attr.size = sizeof(struct perf_event_attr);
-+ attr.sample_type &= ~PERF_SAMPLE_AUX;
-+
-+ if (inject->itrace_synth_opts.add_last_branch) {
-+ attr.sample_type |= PERF_SAMPLE_BRANCH_STACK;
-+ attr.branch_sample_type |= PERF_SAMPLE_BRANCH_HW_INDEX;
-+ }
-+ return perf_event__synthesize_attr(tool, &attr, (u32)n_ids, ids,
-+ perf_event__repipe_synth_cb);
- }
-
- static int perf_event__repipe_event_update(const struct perf_tool *tool,
-@@ -344,8 +385,8 @@ perf_inject__cut_auxtrace_sample(struct perf_inject *inject,
- union perf_event *event,
- struct perf_sample *sample)
- {
-- size_t sz1 = sample->aux_sample.data - (void *)event;
-- size_t sz2 = event->header.size - sample->aux_sample.size - sz1;
-+ size_t sz1 = sample->aux_sample.data - (void *)event - sizeof(u64);
-+ size_t sz2 = event->header.size - sample->aux_sample.size - (sz1 + sizeof(u64));
- union perf_event *ev;
-
- if (inject->event_copy == NULL) {
-@@ -356,13 +397,12 @@ perf_inject__cut_auxtrace_sample(struct perf_inject *inject,
- ev = (union perf_event *)inject->event_copy;
- if (sz1 > event->header.size || sz2 > event->header.size ||
- sz1 + sz2 > event->header.size ||
-- sz1 < sizeof(struct perf_event_header) + sizeof(u64))
-+ sz1 < sizeof(struct perf_event_header))
- return event;
-
- memcpy(ev, event, sz1);
- memcpy((void *)ev + sz1, (void *)event + event->header.size - sz2, sz2);
- ev->header.size = sz1 + sz2;
-- ((u64 *)((void *)ev + sz1))[-1] = 0;
-
- return ev;
- }
-@@ -382,14 +422,77 @@ static int perf_event__repipe_sample(const struct perf_tool *tool,
- struct perf_inject *inject = container_of(tool, struct perf_inject,
- tool);
-
-- if (evsel && evsel->handler) {
-+ if (evsel == NULL)
-+ return perf_event__repipe_synth(tool, event);
-+
-+ if (evsel->handler) {
- inject_handler f = evsel->handler;
- return f(tool, event, sample, evsel, machine);
- }
-
- build_id__mark_dso_hit(tool, event, sample, evsel, machine);
-
-- if (inject->itrace_synth_opts.set && sample->aux_sample.size) {
-+ if (inject->itrace_synth_opts.set &&
-+ (inject->itrace_synth_opts.last_branch ||
-+ inject->itrace_synth_opts.add_last_branch)) {
-+ union perf_event *event_copy = (void *)inject->event_copy;
-+ struct branch_stack dummy_bs = { .nr = 0, .hw_idx = 0 };
-+ int err;
-+ size_t sz;
-+ u64 orig_type = evsel->core.attr.sample_type;
-+ u64 orig_branch_type = evsel->core.attr.branch_sample_type;
-+
-+ struct branch_stack *orig_bs = sample->branch_stack;
-+
-+ if (event_copy == NULL) {
-+ inject->event_copy = malloc(PERF_SAMPLE_MAX_SIZE);
-+ if (!inject->event_copy)
-+ return -ENOMEM;
-+
-+ event_copy = (void *)inject->event_copy;
-+ }
-+
-+ if (!sample->branch_stack)
-+ sample->branch_stack = &dummy_bs;
-+
-+ if (inject->itrace_synth_opts.add_last_branch) {
-+ /* Temporarily add in type bits for synthesis. */
-+ evsel->core.attr.sample_type |= PERF_SAMPLE_BRANCH_STACK;
-+ evsel->core.attr.branch_sample_type |= PERF_SAMPLE_BRANCH_HW_INDEX;
-+ }
-+ evsel->core.attr.sample_type &= ~PERF_SAMPLE_AUX;
-+
-+ sz = perf_event__sample_event_size(sample, evsel->core.attr.sample_type,
-+ evsel->core.attr.read_format,
-+ evsel->core.attr.branch_sample_type);
-+
-+ if (sz >= PERF_SAMPLE_MAX_SIZE) {
-+ pr_err("Sample size %zu exceeds max size %d\n", sz, PERF_SAMPLE_MAX_SIZE);
-+ evsel->core.attr.sample_type = orig_type;
-+ evsel->core.attr.branch_sample_type = orig_branch_type;
-+ sample->branch_stack = orig_bs;
-+ return -EFAULT;
-+ }
-+
-+ event_copy->header.type = PERF_RECORD_SAMPLE;
-+ event_copy->header.misc = event->header.misc;
-+ event_copy->header.size = sz;
-+
-+ err = perf_event__synthesize_sample(event_copy, evsel->core.attr.sample_type,
-+ evsel->core.attr.read_format,
-+ evsel->core.attr.branch_sample_type, sample);
-+
-+ evsel->core.attr.sample_type = orig_type;
-+ evsel->core.attr.branch_sample_type = orig_branch_type;
-+ sample->branch_stack = orig_bs;
-+
-+ if (err) {
-+ pr_err("Failed to synthesize sample\n");
-+ return err;
-+ }
-+ event = event_copy;
-+ } else if (inject->itrace_synth_opts.set &&
-+ (evsel->core.attr.sample_type & PERF_SAMPLE_AUX)) {
- event = perf_inject__cut_auxtrace_sample(inject, event, sample);
- if (IS_ERR(event))
- return PTR_ERR(event);
-@@ -410,7 +513,7 @@ static int perf_event__convert_sample_callchain(const struct perf_tool *tool,
- struct callchain_cursor_node *node;
- struct thread *thread;
- u64 sample_type = evsel->core.attr.sample_type;
-- u32 sample_size = event->header.size;
-+ size_t sz;
- u64 i, k;
- int ret;
-
-@@ -468,15 +571,18 @@ static int perf_event__convert_sample_callchain(const struct perf_tool *tool,
- out:
- memcpy(event_copy, event, sizeof(event->header));
-
-- /* adjust sample size for stack and regs */
-- sample_size -= sample->user_stack.size;
-- sample_size -= (hweight64(evsel->core.attr.sample_regs_user) + 1) * sizeof(u64);
-- sample_size += (sample->callchain->nr + 1) * sizeof(u64);
-- event_copy->header.size = sample_size;
--
- /* remove sample_type {STACK,REGS}_USER for synthesize */
- sample_type &= ~(PERF_SAMPLE_STACK_USER | PERF_SAMPLE_REGS_USER);
-
-+ sz = perf_event__sample_event_size(sample, sample_type,
-+ evsel->core.attr.read_format,
-+ evsel->core.attr.branch_sample_type);
-+ if (sz >= PERF_SAMPLE_MAX_SIZE) {
-+ pr_err("Sample size %zu exceeds max size %d\n", sz, PERF_SAMPLE_MAX_SIZE);
-+ return -EFAULT;
-+ }
-+ event_copy->header.size = sz;
-+
- ret = perf_event__synthesize_sample(event_copy, sample_type,
- evsel->core.attr.read_format,
- evsel->core.attr.branch_sample_type, sample);
-@@ -2426,12 +2532,27 @@ static int __cmd_inject(struct perf_inject *inject)
- * synthesized hardware events, so clear the feature flag.
- */
- if (inject->itrace_synth_opts.set) {
-+ struct evsel *evsel;
-+
- perf_header__clear_feat(&session->header,
- HEADER_AUXTRACE);
-- if (inject->itrace_synth_opts.last_branch ||
-- inject->itrace_synth_opts.add_last_branch)
-+
-+ evlist__for_each_entry(session->evlist, evsel) {
-+ evsel->core.attr.sample_type &= ~PERF_SAMPLE_AUX;
-+ }
-+
-+ if (inject->itrace_synth_opts.add_last_branch) {
- perf_header__set_feat(&session->header,
- HEADER_BRANCH_STACK);
-+
-+ evlist__for_each_entry(session->evlist, evsel) {
-+ evsel->core.attr.sample_type |= PERF_SAMPLE_BRANCH_STACK;
-+ if (evsel->core.attr.size < PERF_ATTR_SIZE_VER2)
-+ evsel->core.attr.size = PERF_ATTR_SIZE_VER2;
-+ evsel->core.attr.branch_sample_type |=
-+ PERF_SAMPLE_BRANCH_HW_INDEX;
-+ }
-+ }
- }
-
- /*
-diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c
-index c56d8d38b1e8fc..9827f23a16dfc2 100644
---- a/tools/perf/util/intel-pt.c
-+++ b/tools/perf/util/intel-pt.c
-@@ -1307,7 +1307,8 @@ static struct intel_pt_queue *intel_pt_alloc_queue(struct intel_pt *pt,
- goto out_free;
- }
-
-- if (pt->synth_opts.last_branch || pt->synth_opts.other_events) {
-+ if (pt->synth_opts.last_branch || pt->synth_opts.add_last_branch ||
-+ pt->synth_opts.other_events) {
- unsigned int entry_cnt = max(LBRS_MAX, pt->br_stack_sz);
-
- ptq->last_branch = intel_pt_alloc_br_stack(entry_cnt);
-@@ -2505,7 +2506,7 @@ static int intel_pt_do_synth_pebs_sample(struct intel_pt_queue *ptq, struct evse
- intel_pt_add_xmm(intr_regs, pos, items, regs_mask);
- }
-
-- if (sample_type & PERF_SAMPLE_BRANCH_STACK) {
-+ if ((sample_type | evsel->synth_sample_type) & PERF_SAMPLE_BRANCH_STACK) {
- if (items->mask[INTEL_PT_LBR_0_POS] ||
- items->mask[INTEL_PT_LBR_1_POS] ||
- items->mask[INTEL_PT_LBR_2_POS]) {
-@@ -2576,7 +2577,8 @@ static int intel_pt_do_synth_pebs_sample(struct intel_pt_queue *ptq, struct evse
- sample.transaction = txn;
- }
-
-- ret = intel_pt_deliver_synth_event(pt, event, &sample, sample_type);
-+ ret = intel_pt_deliver_synth_event(pt, event, &sample,
-+ sample_type | evsel->synth_sample_type);
- perf_sample__exit(&sample);
- return ret;
- }
---
-2.53.0
-
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
-@@ -2862,7 +2862,7 @@ int cmd_inject(int argc, const char **ar
+@@ -2735,7 +2735,7 @@ int cmd_inject(int argc, const char **ar
}
evlist__for_each_entry(inject.session->evlist, evsel) {
Stable-dep-of: f973e52a9977 ("perf dso: Fix heap overflow in dso__get_filename() on decompressed path")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
- tools/perf/bench/inject-buildid.c | 2 +-
- tools/perf/builtin-buildid-cache.c | 8 ++++----
- tools/perf/builtin-inject.c | 4 ++--
- tools/perf/tests/pe-file-parsing.c | 4 ++--
- tools/perf/tests/sdt.c | 2 +-
- tools/perf/util/build-id.c | 4 ++--
- tools/perf/util/debuginfo.c | 2 +-
- tools/perf/util/dsos.c | 4 ++--
- tools/perf/util/libbfd.c | 9 +++++++--
- tools/perf/util/libbfd.h | 5 ++---
- tools/perf/util/symbol-elf.c | 13 +++++++------
- tools/perf/util/symbol-minimal.c | 11 ++++++++---
- tools/perf/util/symbol.c | 5 ++---
- tools/perf/util/symbol.h | 2 +-
- tools/perf/util/synthetic-events.c | 2 +-
+ tools/perf/bench/inject-buildid.c | 2 +-
+ tools/perf/builtin-buildid-cache.c | 8 ++++----
+ tools/perf/builtin-inject.c | 4 ++--
+ tools/perf/tests/pe-file-parsing.c | 4 ++--
+ tools/perf/tests/sdt.c | 2 +-
+ tools/perf/util/build-id.c | 4 ++--
+ tools/perf/util/debuginfo.c | 2 +-
+ tools/perf/util/dsos.c | 4 ++--
+ tools/perf/util/libbfd.c | 9 +++++++--
+ tools/perf/util/libbfd.h | 5 ++---
+ tools/perf/util/symbol-elf.c | 13 +++++++------
+ tools/perf/util/symbol-minimal.c | 11 ++++++++---
+ tools/perf/util/symbol.c | 5 ++---
+ tools/perf/util/symbol.h | 2 +-
+ tools/perf/util/synthetic-events.c | 2 +-
15 files changed, 43 insertions(+), 34 deletions(-)
-diff --git a/tools/perf/bench/inject-buildid.c b/tools/perf/bench/inject-buildid.c
-index 44c471682c3c4c..bfd2c5ec9488e0 100644
--- a/tools/perf/bench/inject-buildid.c
+++ b/tools/perf/bench/inject-buildid.c
-@@ -85,7 +85,7 @@ static int add_dso(const char *fpath, const struct stat *sb __maybe_unused,
+@@ -85,7 +85,7 @@ static int add_dso(const char *fpath, co
if (typeflag == FTW_D || typeflag == FTW_SL)
return 0;
return 0;
dso->name = realpath(fpath, NULL);
-diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c
-index 2e0f2004696ae9..c98104481c8a19 100644
--- a/tools/perf/builtin-buildid-cache.c
+++ b/tools/perf/builtin-buildid-cache.c
-@@ -180,7 +180,7 @@ static int build_id_cache__add_file(const char *filename, struct nsinfo *nsi)
+@@ -180,7 +180,7 @@ static int build_id_cache__add_file(cons
struct nscookie nsc;
nsinfo__mountns_enter(nsi, &nsc);
nsinfo__mountns_exit(&nsc);
if (err < 0) {
pr_debug("Couldn't read a build-id in %s\n", filename);
-@@ -204,7 +204,7 @@ static int build_id_cache__remove_file(const char *filename, struct nsinfo *nsi)
+@@ -204,7 +204,7 @@ static int build_id_cache__remove_file(c
int err;
nsinfo__mountns_enter(nsi, &nsc);
nsinfo__mountns_exit(&nsc);
if (err < 0) {
pr_debug("Couldn't read a build-id in %s\n", filename);
-@@ -280,7 +280,7 @@ static bool dso__missing_buildid_cache(struct dso *dso, int parm __maybe_unused)
+@@ -280,7 +280,7 @@ static bool dso__missing_buildid_cache(s
if (!dso__build_id_filename(dso, filename, sizeof(filename), false))
return true;
if (errno == ENOENT)
return false;
-@@ -309,7 +309,7 @@ static int build_id_cache__update_file(const char *filename, struct nsinfo *nsi)
+@@ -309,7 +309,7 @@ static int build_id_cache__update_file(c
int err;
nsinfo__mountns_enter(nsi, &nsc);
nsinfo__mountns_exit(&nsc);
if (err < 0) {
pr_debug("Couldn't read a build-id in %s\n", filename);
-diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
-index 015c9e6865dd97..0eb52982bef11b 100644
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
-@@ -877,12 +877,12 @@ static int dso__read_build_id(struct dso *dso)
+@@ -766,12 +766,12 @@ static int dso__read_build_id(struct dso
mutex_lock(dso__lock(dso));
nsinfo__mountns_enter(dso__nsinfo(dso), &nsc);
dso__set_build_id(dso, &bid);
free(new_name);
}
-diff --git a/tools/perf/tests/pe-file-parsing.c b/tools/perf/tests/pe-file-parsing.c
-index 8b31d1d05f905f..30c7da79e109b4 100644
--- a/tools/perf/tests/pe-file-parsing.c
+++ b/tools/perf/tests/pe-file-parsing.c
@@ -37,7 +37,7 @@ static int run_dir(const char *d)
TEST_ASSERT_VAL("Failed to read debug file build_id",
ret == sizeof(expect_build_id));
TEST_ASSERT_VAL("Wrong build_id", !memcmp(bid.data, expect_build_id,
-diff --git a/tools/perf/tests/sdt.c b/tools/perf/tests/sdt.c
-index 6132f1af3e22d3..93baee2eae42ab 100644
--- a/tools/perf/tests/sdt.c
+++ b/tools/perf/tests/sdt.c
-@@ -31,7 +31,7 @@ static int build_id_cache__add_file(const char *filename)
+@@ -31,7 +31,7 @@ static int build_id_cache__add_file(cons
struct build_id bid = { .size = 0, };
int err;
if (err < 0) {
pr_debug("Failed to read build id of %s\n", filename);
return err;
-diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
-index 35505a1ffd1117..fdb35133fde43a 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
-@@ -122,7 +122,7 @@ int filename__snprintf_build_id(const char *pathname, char *sbuild_id, size_t sb
+@@ -122,7 +122,7 @@ int filename__snprintf_build_id(const ch
struct build_id bid = { .size = 0, };
int ret;
if (ret < 0)
return ret;
-@@ -848,7 +848,7 @@ static int filename__read_build_id_ns(const char *filename,
+@@ -848,7 +848,7 @@ static int filename__read_build_id_ns(co
int ret;
nsinfo__mountns_enter(nsi, &nsc);
nsinfo__mountns_exit(&nsc);
return ret;
-diff --git a/tools/perf/util/debuginfo.c b/tools/perf/util/debuginfo.c
-index 07099b50f21926..46fecb7b17e147 100644
--- a/tools/perf/util/debuginfo.c
+++ b/tools/perf/util/debuginfo.c
-@@ -118,7 +118,7 @@ struct debuginfo *debuginfo__new(const char *path)
+@@ -118,7 +118,7 @@ struct debuginfo *debuginfo__new(const c
* incase the path isn't for a regular file.
*/
assert(!dso__has_build_id(dso));
dso__set_build_id(dso, &bid);
for (type = distro_dwarf_types;
-diff --git a/tools/perf/util/dsos.c b/tools/perf/util/dsos.c
-index 64c1d65b014961..0a7645c7fae7d3 100644
--- a/tools/perf/util/dsos.c
+++ b/tools/perf/util/dsos.c
-@@ -81,13 +81,13 @@ static int dsos__read_build_ids_cb(struct dso *dso, void *data)
+@@ -81,13 +81,13 @@ static int dsos__read_build_ids_cb(struc
return 0;
}
nsinfo__mountns_enter(dso__nsinfo(dso), &nsc);
dso__set_build_id(dso, &bid);
args->have_build_id = true;
}
-diff --git a/tools/perf/util/libbfd.c b/tools/perf/util/libbfd.c
-index 2324f6846d510d..d9effc3ada9954 100644
--- a/tools/perf/util/libbfd.c
+++ b/tools/perf/util/libbfd.c
-@@ -418,13 +418,18 @@ int dso__load_bfd_symbols(struct dso *dso, const char *debugfile)
+@@ -418,13 +418,18 @@ out_close:
return err;
}
if (fd < 0)
return -1;
-diff --git a/tools/perf/util/libbfd.h b/tools/perf/util/libbfd.h
-index e300f171d1bd70..953886f3d62f37 100644
--- a/tools/perf/util/libbfd.h
+++ b/tools/perf/util/libbfd.h
-@@ -25,7 +25,7 @@ void dso__free_a2l_libbfd(struct dso *dso);
+@@ -25,7 +25,7 @@ void dso__free_a2l_libbfd(struct dso *ds
int symbol__disassemble_libbfd(const char *filename, struct symbol *sym,
struct annotate_args *args);
int libbfd_filename__read_debuglink(const char *filename, char *debuglink, size_t size);
-@@ -59,8 +59,7 @@ static inline int symbol__disassemble_libbfd(const char *filename __always_unuse
+@@ -59,8 +59,7 @@ static inline int symbol__disassemble_li
}
static inline int libbfd__read_build_id(const char *filename __always_unused,
{
return -1;
}
-diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
-index 108b91844a2dee..26c842ddaf235b 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
-@@ -874,20 +874,20 @@ static int elf_read_build_id(Elf *elf, void *bf, size_t size)
+@@ -874,20 +874,20 @@ out:
return err;
}
if (fd < 0)
goto out;
-@@ -908,7 +908,7 @@ static int read_build_id(const char *filename, struct build_id *bid, bool block)
+@@ -908,7 +908,7 @@ out:
return err;
}
{
struct kmod_path m = { .name = NULL, };
char path[PATH_MAX];
-@@ -916,6 +916,8 @@ int filename__read_build_id(const char *filename, struct build_id *bid, bool blo
+@@ -916,6 +916,8 @@ int filename__read_build_id(const char *
if (!filename)
return -EFAULT;
err = kmod_path__parse(&m, filename);
if (err)
-@@ -932,10 +934,9 @@ int filename__read_build_id(const char *filename, struct build_id *bid, bool blo
+@@ -932,10 +934,9 @@ int filename__read_build_id(const char *
}
close(fd);
filename = path;
if (m.comp)
unlink(filename);
-diff --git a/tools/perf/util/symbol-minimal.c b/tools/perf/util/symbol-minimal.c
-index aa931a0015c10b..2102ed36f2dc2d 100644
--- a/tools/perf/util/symbol-minimal.c
+++ b/tools/perf/util/symbol-minimal.c
-@@ -94,7 +94,7 @@ int filename__read_debuglink(const char *filename __maybe_unused,
+@@ -94,7 +94,7 @@ int filename__read_debuglink(const char
/*
* Just try PT_NOTE header otherwise fails
*/
{
int fd, ret = -1;
bool need_swap = false, elf32;
-@@ -111,7 +111,12 @@ int filename__read_build_id(const char *filename, struct build_id *bid, bool blo
+@@ -111,7 +111,12 @@ int filename__read_build_id(const char *
void *phdr, *buf = NULL;
ssize_t phdr_size, ehdr_size, buf_size = 0;
if (fd < 0)
return -1;
-@@ -335,7 +340,7 @@ int dso__load_sym(struct dso *dso, struct map *map __maybe_unused,
+@@ -335,7 +340,7 @@ int dso__load_sym(struct dso *dso, struc
if (ret >= 0)
RC_CHK_ACCESS(dso)->is_64_bit = ret;
dso__set_build_id(dso, &bid);
return 0;
}
-diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
-index f4abe5dbf1a4c5..7535a78b7fd235 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
-@@ -1755,14 +1755,13 @@ int dso__load(struct dso *dso, struct map *map)
+@@ -1755,14 +1755,13 @@ int dso__load(struct dso *dso, struct ma
/*
* Read the build id if possible. This is required for
dso__set_build_id(dso, &bid);
}
-diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
-index 3471062187992a..3fb5d146d9b15b 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
-@@ -140,7 +140,7 @@ struct symbol *dso__next_symbol(struct symbol *sym);
+@@ -140,7 +140,7 @@ struct symbol *dso__next_symbol(struct s
enum dso_type dso__type_fd(int fd);
int sysfs__read_build_id(const char *filename, struct build_id *bid);
int modules__parse(const char *filename, void *arg,
int (*process_module)(void *arg, const char *name,
-diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic-events.c
-index 12f268032b492b..e08f2fcad42d9f 100644
--- a/tools/perf/util/synthetic-events.c
+++ b/tools/perf/util/synthetic-events.c
-@@ -401,7 +401,7 @@ static void perf_record_mmap2__read_build_id(struct perf_record_mmap2 *event,
+@@ -401,7 +401,7 @@ static void perf_record_mmap2__read_buil
nsi = nsinfo__new(event->pid);
nsinfo__mountns_enter(nsi, &nc);
nsinfo__mountns_exit(&nc);
nsinfo__put(nsi);
---
-2.53.0
-
pci-dwc-fix-signedness-bug-in-fault-injection-test-c.patch
perf-build-id-fix-off-by-one-bug-when-printing-kerne.patch
perf-inject-add-convert-callchain-option.patch
-perf-event-fix-size-of-synthesized-sample-with-branc.patch
-perf-inject-fix-itrace-branch-stack-synthesis.patch
staging-most-video-avoid-double-free-on-video-regist.patch
usb-host-max3421-fix-shift-out-of-bounds-in-max3421_.patch
usb-host-max3421-reject-hub-port-requests-for-non-ex.patch