All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/5] perf cs-etm: Track exception level
@ 2023-06-12 11:13 James Clark
  2023-06-12 11:13 ` [PATCH v3 1/5] perf cs-etm: Only track threads instead of PID and TIDs James Clark
                   ` (5 more replies)
  0 siblings, 6 replies; 12+ messages in thread
From: James Clark @ 2023-06-12 11:13 UTC (permalink / raw)
  To: coresight
  Cc: James Clark, Suzuki K Poulose, Mike Leach, Leo Yan,
	Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Mark Rutland, Alexander Shishkin, Jiri Olsa, Namhyung Kim,
	Ian Rogers, Adrian Hunter, John Garry, Will Deacon,
	linux-arm-kernel, linux-perf-users, linux-kernel

Changes since v2:

  * Rename prev_thread -> prev_packet_thread and prev_el ->
    prev_packet_el
  * Add a comment about tracking the previous packet's thread

Changes since v1:

  * Always assume host kernel when the trace was captured at EL1 (nVHE)
  * Fix EL validation to work with ETMv3
  * Add a commit to make PID format accessible from struct
    cs_etm_auxtrace

======

Some fixes to support an issue reported by Denis Nikitin where decoding
trace that contains different EL1 and EL2 kernels can crash or go into
an infinite loop because the wrong kernel maps are used for the decode.

This still doesn't support distinguishing guest and host userspace,
we'd still have to fix the timestamps and do a bit more work to
correlate that. And I've removed PERF_RECORD_MISC_HYPERVISOR as a
possible outcome of cs_etm__cpu_mode(). As far as I know this could
never have been returned anyway because machine__is_host(machine) was
always true due to session.machines.host being hard coded. And I'm not
sure of the relevance of the difference between PERF_RECORD_MISC_KERNEL
and PERF_RECORD_MISC_HYPERVISOR in this scenario.

The first commit is a tidy up, second fixes a bug that I found when
comparing the exception level and thread of branch records, the third
is the main fix, and the last commit is some extra error checking. 

Applies to acme/perf-tools-next (42713dafc)

James Clark (5):
  perf cs-etm: Only track threads instead of PID and TIDs
  perf cs-etm: Use previous thread for branch sample source IP
  perf cs-etm: Make PID format accessible from struct cs_etm_auxtrace
  perf cs-etm: Track exception level
  perf cs-etm: Add exception level consistency check

 .../perf/util/cs-etm-decoder/cs-etm-decoder.c |  33 +-
 .../perf/util/cs-etm-decoder/cs-etm-decoder.h |   4 +-
 tools/perf/util/cs-etm.c                      | 282 ++++++++++--------
 tools/perf/util/cs-etm.h                      |  13 +-
 4 files changed, 184 insertions(+), 148 deletions(-)

-- 
2.34.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v3 1/5] perf cs-etm: Only track threads instead of PID and TIDs
  2023-06-12 11:13 [PATCH v3 0/5] perf cs-etm: Track exception level James Clark
@ 2023-06-12 11:13 ` James Clark
  2023-06-12 11:13 ` [PATCH v3 2/5] perf cs-etm: Use previous thread for branch sample source IP James Clark
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 12+ messages in thread
From: James Clark @ 2023-06-12 11:13 UTC (permalink / raw)
  To: coresight
  Cc: James Clark, Suzuki K Poulose, Mike Leach, Leo Yan,
	Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Mark Rutland, Alexander Shishkin, Jiri Olsa, Namhyung Kim,
	Ian Rogers, Adrian Hunter, John Garry, Will Deacon,
	linux-arm-kernel, linux-perf-users, linux-kernel

PIDs and TIDs are already contained within the thread struct, so to
avoid inconsistencies drop the extra members on the etm queue and only
use the thread struct.

At the same time stop using the 'unknown' thread. In a later commit
we will be making samples from multiple machines so it will be better
to use the idle thread of each machine rather than overlapping unknown
threads. Using the idle thread is also better because kernel addresses
with a previously unknown thread will now be assigned to a real kernel
thread.

Acked-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Reviewed-by: Mike Leach <mike.leach@linaro.org>
Reviewed-by: Leo Yan <leo.yan@linaro.org>
Signed-off-by: James Clark <james.clark@arm.com>
---
 tools/perf/util/cs-etm.c | 124 ++++++++++++---------------------------
 1 file changed, 38 insertions(+), 86 deletions(-)

diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
index 91299cc56bf7..ebffc9052561 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
@@ -46,8 +46,6 @@ struct cs_etm_auxtrace {
 	struct auxtrace_heap heap;
 	struct itrace_synth_opts synth_opts;
 	struct perf_session *session;
-	struct machine *machine;
-	struct thread *unknown_thread;
 	struct perf_tsc_conversion tc;
 
 	/*
@@ -84,7 +82,6 @@ struct cs_etm_auxtrace {
 
 struct cs_etm_traceid_queue {
 	u8 trace_chan_id;
-	pid_t pid, tid;
 	u64 period_instructions;
 	size_t last_branch_pos;
 	union perf_event *event_buf;
@@ -480,9 +477,9 @@ static int cs_etm__init_traceid_queue(struct cs_etm_queue *etmq,
 	cs_etm__clear_packet_queue(&tidq->packet_queue);
 
 	queue = &etmq->etm->queues.queue_array[etmq->queue_nr];
-	tidq->tid = queue->tid;
-	tidq->pid = -1;
 	tidq->trace_chan_id = trace_chan_id;
+	tidq->thread = machine__findnew_thread(&etm->session->machines.host, -1,
+					       queue->tid);
 
 	tidq->packet = zalloc(sizeof(struct cs_etm_packet));
 	if (!tidq->packet)
@@ -863,7 +860,6 @@ static void cs_etm__free(struct perf_session *session)
 	for (i = 0; i < aux->num_cpu; i++)
 		zfree(&aux->metadata[i]);
 
-	thread__zput(aux->unknown_thread);
 	zfree(&aux->metadata);
 	zfree(&aux);
 }
@@ -882,7 +878,7 @@ static u8 cs_etm__cpu_mode(struct cs_etm_queue *etmq, u64 address)
 {
 	struct machine *machine;
 
-	machine = etmq->etm->machine;
+	machine = &etmq->etm->session->machines.host;
 
 	if (address >= machine__kernel_start(machine)) {
 		if (machine__is_host(machine))
@@ -905,8 +901,6 @@ static u32 cs_etm__mem_access(struct cs_etm_queue *etmq, u8 trace_chan_id,
 	u8  cpumode;
 	u64 offset;
 	int len;
-	struct thread *thread;
-	struct machine *machine;
 	struct addr_location al;
 	struct dso *dso;
 	struct cs_etm_traceid_queue *tidq;
@@ -914,20 +908,12 @@ static u32 cs_etm__mem_access(struct cs_etm_queue *etmq, u8 trace_chan_id,
 	if (!etmq)
 		return 0;
 
-	machine = etmq->etm->machine;
 	cpumode = cs_etm__cpu_mode(etmq, address);
 	tidq = cs_etm__etmq_get_traceid_queue(etmq, trace_chan_id);
 	if (!tidq)
 		return 0;
 
-	thread = tidq->thread;
-	if (!thread) {
-		if (cpumode != PERF_RECORD_MISC_KERNEL)
-			return 0;
-		thread = etmq->etm->unknown_thread;
-	}
-
-	if (!thread__find_map(thread, cpumode, address, &al))
+	if (!thread__find_map(tidq->thread, cpumode, address, &al))
 		return 0;
 
 	dso = map__dso(al.map);
@@ -942,7 +928,8 @@ static u32 cs_etm__mem_access(struct cs_etm_queue *etmq, u8 trace_chan_id,
 
 	map__load(al.map);
 
-	len = dso__data_read_offset(dso, machine, offset, buffer, size);
+	len = dso__data_read_offset(dso, maps__machine(tidq->thread->maps),
+				    offset, buffer, size);
 
 	if (len <= 0) {
 		ui__warning_once("CS ETM Trace: Missing DSO. Use 'perf archive' or debuginfod to export data from the traced system.\n"
@@ -1303,39 +1290,31 @@ cs_etm__get_trace(struct cs_etm_queue *etmq)
 	return etmq->buf_len;
 }
 
-static void cs_etm__set_pid_tid_cpu(struct cs_etm_auxtrace *etm,
-				    struct cs_etm_traceid_queue *tidq)
+static void cs_etm__set_thread(struct cs_etm_auxtrace *etm,
+			       struct cs_etm_traceid_queue *tidq, pid_t tid)
 {
-	if ((!tidq->thread) && (tidq->tid != -1))
-		tidq->thread = machine__find_thread(etm->machine, -1,
-						    tidq->tid);
+	struct machine *machine = &etm->session->machines.host;
+
+	if (tid != -1) {
+		thread__zput(tidq->thread);
+		tidq->thread = machine__find_thread(machine, -1, tid);
+	}
 
-	if (tidq->thread)
-		tidq->pid = tidq->thread->pid_;
+	/* Couldn't find a known thread */
+	if (!tidq->thread)
+		tidq->thread = machine__idle_thread(machine);
 }
 
 int cs_etm__etmq_set_tid(struct cs_etm_queue *etmq,
 			 pid_t tid, u8 trace_chan_id)
 {
-	int cpu, err = -EINVAL;
-	struct cs_etm_auxtrace *etm = etmq->etm;
 	struct cs_etm_traceid_queue *tidq;
 
 	tidq = cs_etm__etmq_get_traceid_queue(etmq, trace_chan_id);
 	if (!tidq)
-		return err;
-
-	if (cs_etm__get_cpu(trace_chan_id, &cpu) < 0)
-		return err;
-
-	err = machine__set_current_tid(etm->machine, cpu, tid, tid);
-	if (err)
-		return err;
-
-	tidq->tid = tid;
-	thread__zput(tidq->thread);
+		return -EINVAL;
 
-	cs_etm__set_pid_tid_cpu(etm, tidq);
+	cs_etm__set_thread(etmq->etm, tidq, tid);
 	return 0;
 }
 
@@ -1412,8 +1391,8 @@ static int cs_etm__synth_instruction_sample(struct cs_etm_queue *etmq,
 	sample.time = cs_etm__resolve_sample_time(etmq, tidq);
 
 	sample.ip = addr;
-	sample.pid = tidq->pid;
-	sample.tid = tidq->tid;
+	sample.pid = tidq->thread->pid_;
+	sample.tid = tidq->thread->tid;
 	sample.id = etmq->etm->instructions_id;
 	sample.stream_id = etmq->etm->instructions_id;
 	sample.period = period;
@@ -1471,8 +1450,8 @@ static int cs_etm__synth_branch_sample(struct cs_etm_queue *etmq,
 	sample.time = cs_etm__resolve_sample_time(etmq, tidq);
 
 	sample.ip = ip;
-	sample.pid = tidq->pid;
-	sample.tid = tidq->tid;
+	sample.pid = tidq->thread->pid_;
+	sample.tid = tidq->thread->tid;
 	sample.addr = cs_etm__first_executed_instr(tidq->packet);
 	sample.id = etmq->etm->branches_id;
 	sample.stream_id = etmq->etm->branches_id;
@@ -2466,11 +2445,6 @@ static int cs_etm__process_timeless_queues(struct cs_etm_auxtrace *etm,
 		if (!etmq)
 			continue;
 
-		/*
-		 * Per-cpu mode has contextIDs in the trace and the decoder
-		 * calls cs_etm__set_pid_tid_cpu() automatically so no need
-		 * to do this here
-		 */
 		if (etm->per_thread_decoding) {
 			tidq = cs_etm__etmq_get_traceid_queue(
 				etmq, CS_ETM_PER_THREAD_TRACEID);
@@ -2478,10 +2452,8 @@ static int cs_etm__process_timeless_queues(struct cs_etm_auxtrace *etm,
 			if (!tidq)
 				continue;
 
-			if ((tid == -1) || (tidq->tid == tid)) {
-				cs_etm__set_pid_tid_cpu(etm, tidq);
+			if (tid == -1 || tidq->thread->tid == tid)
 				cs_etm__run_per_thread_timeless_decoder(etmq);
-			}
 		} else
 			cs_etm__run_per_cpu_timeless_decoder(etmq);
 	}
@@ -2611,10 +2583,12 @@ static int cs_etm__process_itrace_start(struct cs_etm_auxtrace *etm,
 		return 0;
 
 	/*
-	 * Add the tid/pid to the log so that we can get a match when
-	 * we get a contextID from the decoder.
+	 * Add the tid/pid to the log so that we can get a match when we get a
+	 * contextID from the decoder. Only track for the host: only kernel
+	 * trace is supported for guests which wouldn't need pids so this should
+	 * be fine.
 	 */
-	th = machine__findnew_thread(etm->machine,
+	th = machine__findnew_thread(&etm->session->machines.host,
 				     event->itrace_start.pid,
 				     event->itrace_start.tid);
 	if (!th)
@@ -2647,10 +2621,12 @@ static int cs_etm__process_switch_cpu_wide(struct cs_etm_auxtrace *etm,
 		return 0;
 
 	/*
-	 * Add the tid/pid to the log so that we can get a match when
-	 * we get a contextID from the decoder.
+	 * Add the tid/pid to the log so that we can get a match when we get a
+	 * contextID from the decoder. Only track for the host: only kernel
+	 * trace is supported for guests which wouldn't need pids so this should
+	 * be fine.
 	 */
-	th = machine__findnew_thread(etm->machine,
+	th = machine__findnew_thread(&etm->session->machines.host,
 				     event->context_switch.next_prev_pid,
 				     event->context_switch.next_prev_tid);
 	if (!th)
@@ -3259,7 +3235,6 @@ int cs_etm__process_auxtrace_info_full(union perf_event *event,
 	}
 
 	etm->session = session;
-	etm->machine = &session->machines.host;
 
 	etm->num_cpu = num_cpu;
 	etm->pmu_type = (unsigned int) ((ptr[CS_PMU_TYPE_CPUS] >> 32) & 0xffffffff);
@@ -3286,27 +3261,6 @@ int cs_etm__process_auxtrace_info_full(union perf_event *event,
 	if (err)
 		return err;
 
-	etm->unknown_thread = thread__new(999999999, 999999999);
-	if (!etm->unknown_thread) {
-		err = -ENOMEM;
-		goto err_free_queues;
-	}
-
-	/*
-	 * Initialize list node so that at thread__zput() we can avoid
-	 * segmentation fault at list_del_init().
-	 */
-	INIT_LIST_HEAD(&etm->unknown_thread->node);
-
-	err = thread__set_comm(etm->unknown_thread, "unknown", 0);
-	if (err)
-		goto err_delete_thread;
-
-	if (thread__init_maps(etm->unknown_thread, etm->machine)) {
-		err = -ENOMEM;
-		goto err_delete_thread;
-	}
-
 	etm->tc.time_shift = tc->time_shift;
 	etm->tc.time_mult = tc->time_mult;
 	etm->tc.time_zero = tc->time_zero;
@@ -3318,7 +3272,7 @@ int cs_etm__process_auxtrace_info_full(union perf_event *event,
 	}
 	err = cs_etm__synth_events(etm, session);
 	if (err)
-		goto err_delete_thread;
+		goto err_free_queues;
 
 	/*
 	 * Map Trace ID values to CPU metadata.
@@ -3348,7 +3302,7 @@ int cs_etm__process_auxtrace_info_full(union perf_event *event,
 					session->header.data_size,
 					cs_etm__process_aux_hw_id_cb, &aux_hw_id_found);
 	if (err)
-		goto err_delete_thread;
+		goto err_free_queues;
 
 	/* if HW ID found then clear any unused metadata ID values */
 	if (aux_hw_id_found)
@@ -3358,17 +3312,15 @@ int cs_etm__process_auxtrace_info_full(union perf_event *event,
 		err = cs_etm__map_trace_ids_metadata(num_cpu, metadata);
 
 	if (err)
-		goto err_delete_thread;
+		goto err_free_queues;
 
 	err = cs_etm__queue_aux_records(session);
 	if (err)
-		goto err_delete_thread;
+		goto err_free_queues;
 
 	etm->data_queued = etm->queues.populated;
 	return 0;
 
-err_delete_thread:
-	thread__zput(etm->unknown_thread);
 err_free_queues:
 	auxtrace_queues__free(&etm->queues);
 	session->auxtrace = NULL;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 2/5] perf cs-etm: Use previous thread for branch sample source IP
  2023-06-12 11:13 [PATCH v3 0/5] perf cs-etm: Track exception level James Clark
  2023-06-12 11:13 ` [PATCH v3 1/5] perf cs-etm: Only track threads instead of PID and TIDs James Clark
@ 2023-06-12 11:13 ` James Clark
  2023-06-12 11:14 ` [PATCH v3 3/5] perf cs-etm: Make PID format accessible from struct cs_etm_auxtrace James Clark
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 12+ messages in thread
From: James Clark @ 2023-06-12 11:13 UTC (permalink / raw)
  To: coresight
  Cc: James Clark, Mike Leach, Suzuki K Poulose, Leo Yan,
	Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Mark Rutland, Alexander Shishkin, Jiri Olsa, Namhyung Kim,
	Ian Rogers, Adrian Hunter, John Garry, Will Deacon,
	linux-arm-kernel, linux-perf-users, linux-kernel

Branch samples currently use the IP of the previous packet as the from
IP, and the IP of the current packet as the to IP. But it incorrectly
uses the current thread. In some cases like a jump into a different
exception level this will attribute to the incorrect process.

Fix it by tracking the previous thread in the same way the previous
packet is tracked.

Reviewed-by: Mike Leach <mike.leach@linaro.org>
Signed-off-by: James Clark <james.clark@arm.com>
---
 tools/perf/util/cs-etm.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
index ebffc9052561..5b909bca294e 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
@@ -86,6 +86,7 @@ struct cs_etm_traceid_queue {
 	size_t last_branch_pos;
 	union perf_event *event_buf;
 	struct thread *thread;
+	struct thread *prev_packet_thread;
 	struct branch_stack *last_branch;
 	struct branch_stack *last_branch_rb;
 	struct cs_etm_packet *prev_packet;
@@ -480,6 +481,7 @@ static int cs_etm__init_traceid_queue(struct cs_etm_queue *etmq,
 	tidq->trace_chan_id = trace_chan_id;
 	tidq->thread = machine__findnew_thread(&etm->session->machines.host, -1,
 					       queue->tid);
+	tidq->prev_packet_thread = machine__idle_thread(&etm->session->machines.host);
 
 	tidq->packet = zalloc(sizeof(struct cs_etm_packet));
 	if (!tidq->packet)
@@ -612,10 +614,20 @@ static void cs_etm__packet_swap(struct cs_etm_auxtrace *etm,
 		/*
 		 * Swap PACKET with PREV_PACKET: PACKET becomes PREV_PACKET for
 		 * the next incoming packet.
+		 *
+		 * Threads and exception levels are also tracked for both the
+		 * previous and current packets. This is because the previous
+		 * packet is used for the 'from' IP for branch samples, so the
+		 * thread at that time must also be assigned to that sample.
+		 * Across discontinuity packets the thread can change, so by
+		 * tracking the thread for the previous packet the branch sample
+		 * will have the correct info.
 		 */
 		tmp = tidq->packet;
 		tidq->packet = tidq->prev_packet;
 		tidq->prev_packet = tmp;
+		thread__put(tidq->prev_packet_thread);
+		tidq->prev_packet_thread = thread__get(tidq->thread);
 	}
 }
 
@@ -791,6 +803,7 @@ static void cs_etm__free_traceid_queues(struct cs_etm_queue *etmq)
 		/* Free this traceid_queue from the array */
 		tidq = etmq->traceid_queues[idx];
 		thread__zput(tidq->thread);
+		thread__zput(tidq->prev_packet_thread);
 		zfree(&tidq->event_buf);
 		zfree(&tidq->last_branch);
 		zfree(&tidq->last_branch_rb);
@@ -1450,8 +1463,8 @@ static int cs_etm__synth_branch_sample(struct cs_etm_queue *etmq,
 	sample.time = cs_etm__resolve_sample_time(etmq, tidq);
 
 	sample.ip = ip;
-	sample.pid = tidq->thread->pid_;
-	sample.tid = tidq->thread->tid;
+	sample.pid = tidq->prev_packet_thread->pid_;
+	sample.tid = tidq->prev_packet_thread->tid;
 	sample.addr = cs_etm__first_executed_instr(tidq->packet);
 	sample.id = etmq->etm->branches_id;
 	sample.stream_id = etmq->etm->branches_id;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 3/5] perf cs-etm: Make PID format accessible from struct cs_etm_auxtrace
  2023-06-12 11:13 [PATCH v3 0/5] perf cs-etm: Track exception level James Clark
  2023-06-12 11:13 ` [PATCH v3 1/5] perf cs-etm: Only track threads instead of PID and TIDs James Clark
  2023-06-12 11:13 ` [PATCH v3 2/5] perf cs-etm: Use previous thread for branch sample source IP James Clark
@ 2023-06-12 11:14 ` James Clark
  2023-06-12 11:14 ` [PATCH v3 4/5] perf cs-etm: Track exception level James Clark
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 12+ messages in thread
From: James Clark @ 2023-06-12 11:14 UTC (permalink / raw)
  To: coresight
  Cc: James Clark, Leo Yan, Suzuki K Poulose, Mike Leach,
	Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Mark Rutland, Alexander Shishkin, Jiri Olsa, Namhyung Kim,
	Ian Rogers, Adrian Hunter, John Garry, Will Deacon,
	linux-arm-kernel, linux-perf-users, linux-kernel

To avoid every user of PID format having to use their own static
local variable, cache it on initialisation and change the accessor to
take struct cs_etm_auxtrace.

Reviewed-by: Leo Yan <leo.yan@linaro.org>
Signed-off-by: James Clark <james.clark@arm.com>
---
 .../perf/util/cs-etm-decoder/cs-etm-decoder.c | 20 ++-------
 tools/perf/util/cs-etm.c                      | 42 ++++++++++++-------
 tools/perf/util/cs-etm.h                      |  8 +++-
 3 files changed, 37 insertions(+), 33 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 82a27ab90c8b..2af641d26866 100644
--- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
+++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
@@ -541,34 +541,22 @@ cs_etm_decoder__set_tid(struct cs_etm_queue *etmq,
 			const uint8_t trace_chan_id)
 {
 	pid_t tid = -1;
-	static u64 pid_fmt;
-	int ret;
-
-	/*
-	 * As all the ETMs run at the same exception level, the system should
-	 * have the same PID format crossing CPUs.  So cache the PID format
-	 * and reuse it for sequential decoding.
-	 */
-	if (!pid_fmt) {
-		ret = cs_etm__get_pid_fmt(trace_chan_id, &pid_fmt);
-		if (ret)
-			return OCSD_RESP_FATAL_SYS_ERR;
-	}
 
 	/*
 	 * Process the PE_CONTEXT packets if we have a valid contextID or VMID.
 	 * If the kernel is running at EL2, the PID is traced in CONTEXTIDR_EL2
 	 * as VMID, Bit ETM_OPT_CTXTID2 is set in this case.
 	 */
-	switch (pid_fmt) {
-	case BIT(ETM_OPT_CTXTID):
+	switch (cs_etm__get_pid_fmt(etmq)) {
+	case CS_ETM_PIDFMT_CTXTID:
 		if (elem->context.ctxt_id_valid)
 			tid = elem->context.context_id;
 		break;
-	case BIT(ETM_OPT_CTXTID2):
+	case CS_ETM_PIDFMT_CTXTID2:
 		if (elem->context.vmid_valid)
 			tid = elem->context.vmid;
 		break;
+	case CS_ETM_PIDFMT_NONE:
 	default:
 		break;
 	}
diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
index 5b909bca294e..afe0a838152d 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
@@ -78,6 +78,7 @@ struct cs_etm_auxtrace {
 	u64 instructions_id;
 	u64 **metadata;
 	unsigned int pmu_type;
+	enum cs_etm_pid_fmt pid_fmt;
 };
 
 struct cs_etm_traceid_queue {
@@ -170,44 +171,46 @@ int cs_etm__get_cpu(u8 trace_chan_id, int *cpu)
 }
 
 /*
- * The returned PID format is presented by two bits:
+ * The returned PID format is presented as an enum:
  *
- *   Bit ETM_OPT_CTXTID: CONTEXTIDR or CONTEXTIDR_EL1 is traced;
- *   Bit ETM_OPT_CTXTID2: CONTEXTIDR_EL2 is traced.
+ *   CS_ETM_PIDFMT_CTXTID: CONTEXTIDR or CONTEXTIDR_EL1 is traced.
+ *   CS_ETM_PIDFMT_CTXTID2: CONTEXTIDR_EL2 is traced.
+ *   CS_ETM_PIDFMT_NONE: No context IDs
  *
  * It's possible that the two bits ETM_OPT_CTXTID and ETM_OPT_CTXTID2
  * are enabled at the same time when the session runs on an EL2 kernel.
  * This means the CONTEXTIDR_EL1 and CONTEXTIDR_EL2 both will be
  * recorded in the trace data, the tool will selectively use
  * CONTEXTIDR_EL2 as PID.
+ *
+ * The result is cached in etm->pid_fmt so this function only needs to be called
+ * when processing the aux info.
  */
-int cs_etm__get_pid_fmt(u8 trace_chan_id, u64 *pid_fmt)
+static enum cs_etm_pid_fmt cs_etm__init_pid_fmt(u64 *metadata)
 {
-	struct int_node *inode;
-	u64 *metadata, val;
-
-	inode = intlist__find(traceid_list, trace_chan_id);
-	if (!inode)
-		return -EINVAL;
-
-	metadata = inode->priv;
+	u64 val;
 
 	if (metadata[CS_ETM_MAGIC] == __perf_cs_etmv3_magic) {
 		val = metadata[CS_ETM_ETMCR];
 		/* CONTEXTIDR is traced */
 		if (val & BIT(ETM_OPT_CTXTID))
-			*pid_fmt = BIT(ETM_OPT_CTXTID);
+			return CS_ETM_PIDFMT_CTXTID;
 	} else {
 		val = metadata[CS_ETMV4_TRCCONFIGR];
 		/* CONTEXTIDR_EL2 is traced */
 		if (val & (BIT(ETM4_CFG_BIT_VMID) | BIT(ETM4_CFG_BIT_VMID_OPT)))
-			*pid_fmt = BIT(ETM_OPT_CTXTID2);
+			return CS_ETM_PIDFMT_CTXTID2;
 		/* CONTEXTIDR_EL1 is traced */
 		else if (val & BIT(ETM4_CFG_BIT_CTXTID))
-			*pid_fmt = BIT(ETM_OPT_CTXTID);
+			return CS_ETM_PIDFMT_CTXTID;
 	}
 
-	return 0;
+	return CS_ETM_PIDFMT_NONE;
+}
+
+enum cs_etm_pid_fmt cs_etm__get_pid_fmt(struct cs_etm_queue *etmq)
+{
+	return etmq->etm->pid_fmt;
 }
 
 static int cs_etm__map_trace_id(u8 trace_chan_id, u64 *cpu_metadata)
@@ -3235,6 +3238,13 @@ int cs_etm__process_auxtrace_info_full(union perf_event *event,
 		goto err_free_metadata;
 	}
 
+	/*
+	 * As all the ETMs run at the same exception level, the system should
+	 * have the same PID format crossing CPUs.  So cache the PID format
+	 * and reuse it for sequential decoding.
+	 */
+	etm->pid_fmt = cs_etm__init_pid_fmt(metadata[0]);
+
 	err = auxtrace_queues__init(&etm->queues);
 	if (err)
 		goto err_free_etm;
diff --git a/tools/perf/util/cs-etm.h b/tools/perf/util/cs-etm.h
index ecca40787ac9..2f47f4ec5b27 100644
--- a/tools/perf/util/cs-etm.h
+++ b/tools/perf/util/cs-etm.h
@@ -244,9 +244,15 @@ int cs_etm__process_auxtrace_info(union perf_event *event,
 				  struct perf_session *session);
 struct perf_event_attr *cs_etm_get_default_config(struct perf_pmu *pmu);
 
+enum cs_etm_pid_fmt {
+	CS_ETM_PIDFMT_NONE,
+	CS_ETM_PIDFMT_CTXTID,
+	CS_ETM_PIDFMT_CTXTID2
+};
+
 #ifdef HAVE_CSTRACE_SUPPORT
 int cs_etm__get_cpu(u8 trace_chan_id, int *cpu);
-int cs_etm__get_pid_fmt(u8 trace_chan_id, u64 *pid_fmt);
+enum pid_fmt cs_etm__get_pid_fmt(struct cs_etm_queue *etmq);
 int cs_etm__etmq_set_tid(struct cs_etm_queue *etmq,
 			 pid_t tid, u8 trace_chan_id);
 bool cs_etm__etmq_is_timeless(struct cs_etm_queue *etmq);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 4/5] perf cs-etm: Track exception level
  2023-06-12 11:13 [PATCH v3 0/5] perf cs-etm: Track exception level James Clark
                   ` (2 preceding siblings ...)
  2023-06-12 11:14 ` [PATCH v3 3/5] perf cs-etm: Make PID format accessible from struct cs_etm_auxtrace James Clark
@ 2023-06-12 11:14 ` James Clark
  2023-06-12 11:14 ` [PATCH v3 5/5] perf cs-etm: Add exception level consistency check James Clark
  2023-06-12 18:32   ` Arnaldo Carvalho de Melo
  5 siblings, 0 replies; 12+ messages in thread
From: James Clark @ 2023-06-12 11:14 UTC (permalink / raw)
  To: coresight
  Cc: James Clark, Leo Yan, Suzuki K Poulose, Mike Leach,
	Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Mark Rutland, Alexander Shishkin, Jiri Olsa, Namhyung Kim,
	Ian Rogers, Adrian Hunter, John Garry, Will Deacon,
	linux-arm-kernel, linux-perf-users, linux-kernel

Currently we assume all trace belongs to the host machine so when
the decoder should be looking at the guest kernel maps it can crash
because it looks at the host ones instead.

Avoid one scenario (guest kernel running at EL1) by assigning the
default guest machine to this trace. For userspace trace it's still not
possible to determine guest vs host, but the PIDs should help in this
case.

Reviewed-by: Leo Yan <leo.yan@linaro.org>
Signed-off-by: James Clark <james.clark@arm.com>
---
 .../perf/util/cs-etm-decoder/cs-etm-decoder.c |  7 +-
 tools/perf/util/cs-etm.c                      | 76 +++++++++++++++----
 tools/perf/util/cs-etm.h                      |  7 +-
 3 files changed, 68 insertions(+), 22 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 2af641d26866..44c49acd6bff 100644
--- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
+++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
@@ -561,12 +561,13 @@ cs_etm_decoder__set_tid(struct cs_etm_queue *etmq,
 		break;
 	}
 
+	if (cs_etm__etmq_set_tid_el(etmq, tid, trace_chan_id,
+				    elem->context.exception_level))
+		return OCSD_RESP_FATAL_SYS_ERR;
+
 	if (tid == -1)
 		return OCSD_RESP_CONT;
 
-	if (cs_etm__etmq_set_tid(etmq, tid, trace_chan_id))
-		return OCSD_RESP_FATAL_SYS_ERR;
-
 	/*
 	 * A timestamp is generated after a PE_CONTEXT element so make sure
 	 * to rely on that coming one.
diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
index afe0a838152d..bd724f3b7e35 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
@@ -14,7 +14,6 @@
 #include <linux/types.h>
 #include <linux/zalloc.h>
 
-#include <opencsd/ocsd_if_types.h>
 #include <stdlib.h>
 
 #include "auxtrace.h"
@@ -88,6 +87,8 @@ struct cs_etm_traceid_queue {
 	union perf_event *event_buf;
 	struct thread *thread;
 	struct thread *prev_packet_thread;
+	ocsd_ex_level prev_packet_el;
+	ocsd_ex_level el;
 	struct branch_stack *last_branch;
 	struct branch_stack *last_branch_rb;
 	struct cs_etm_packet *prev_packet;
@@ -482,6 +483,7 @@ static int cs_etm__init_traceid_queue(struct cs_etm_queue *etmq,
 
 	queue = &etmq->etm->queues.queue_array[etmq->queue_nr];
 	tidq->trace_chan_id = trace_chan_id;
+	tidq->el = tidq->prev_packet_el = ocsd_EL_unknown;
 	tidq->thread = machine__findnew_thread(&etm->session->machines.host, -1,
 					       queue->tid);
 	tidq->prev_packet_thread = machine__idle_thread(&etm->session->machines.host);
@@ -629,6 +631,7 @@ static void cs_etm__packet_swap(struct cs_etm_auxtrace *etm,
 		tmp = tidq->packet;
 		tidq->packet = tidq->prev_packet;
 		tidq->prev_packet = tmp;
+		tidq->prev_packet_el = tidq->el;
 		thread__put(tidq->prev_packet_thread);
 		tidq->prev_packet_thread = thread__get(tidq->thread);
 	}
@@ -890,11 +893,43 @@ static bool cs_etm__evsel_is_auxtrace(struct perf_session *session,
 	return evsel->core.attr.type == aux->pmu_type;
 }
 
-static u8 cs_etm__cpu_mode(struct cs_etm_queue *etmq, u64 address)
+static struct machine *cs_etm__get_machine(struct cs_etm_queue *etmq,
+					   ocsd_ex_level el)
 {
-	struct machine *machine;
+	enum cs_etm_pid_fmt pid_fmt = cs_etm__get_pid_fmt(etmq);
 
-	machine = &etmq->etm->session->machines.host;
+	/*
+	 * For any virtualisation based on nVHE (e.g. pKVM), or host kernels
+	 * running at EL1 assume everything is the host.
+	 */
+	if (pid_fmt == CS_ETM_PIDFMT_CTXTID)
+		return &etmq->etm->session->machines.host;
+
+	/*
+	 * Not perfect, but otherwise assume anything in EL1 is the default
+	 * guest, and everything else is the host. Distinguishing between guest
+	 * and host userspaces isn't currently supported either. Neither is
+	 * multiple guest support. All this does is reduce the likeliness of
+	 * decode errors where we look into the host kernel maps when it should
+	 * have been the guest maps.
+	 */
+	switch (el) {
+	case ocsd_EL1:
+		return machines__find_guest(&etmq->etm->session->machines,
+					    DEFAULT_GUEST_KERNEL_ID);
+	case ocsd_EL3:
+	case ocsd_EL2:
+	case ocsd_EL0:
+	case ocsd_EL_unknown:
+	default:
+		return &etmq->etm->session->machines.host;
+	}
+}
+
+static u8 cs_etm__cpu_mode(struct cs_etm_queue *etmq, u64 address,
+			   ocsd_ex_level el)
+{
+	struct machine *machine = cs_etm__get_machine(etmq, el);
 
 	if (address >= machine__kernel_start(machine)) {
 		if (machine__is_host(machine))
@@ -904,10 +939,14 @@ static u8 cs_etm__cpu_mode(struct cs_etm_queue *etmq, u64 address)
 	} else {
 		if (machine__is_host(machine))
 			return PERF_RECORD_MISC_USER;
-		else if (perf_guest)
+		else {
+			/*
+			 * Can't really happen at the moment because
+			 * cs_etm__get_machine() will always return
+			 * machines.host for any non EL1 trace.
+			 */
 			return PERF_RECORD_MISC_GUEST_USER;
-		else
-			return PERF_RECORD_MISC_HYPERVISOR;
+		}
 	}
 }
 
@@ -924,11 +963,12 @@ static u32 cs_etm__mem_access(struct cs_etm_queue *etmq, u8 trace_chan_id,
 	if (!etmq)
 		return 0;
 
-	cpumode = cs_etm__cpu_mode(etmq, address);
 	tidq = cs_etm__etmq_get_traceid_queue(etmq, trace_chan_id);
 	if (!tidq)
 		return 0;
 
+	cpumode = cs_etm__cpu_mode(etmq, address, tidq->el);
+
 	if (!thread__find_map(tidq->thread, cpumode, address, &al))
 		return 0;
 
@@ -1306,10 +1346,11 @@ cs_etm__get_trace(struct cs_etm_queue *etmq)
 	return etmq->buf_len;
 }
 
-static void cs_etm__set_thread(struct cs_etm_auxtrace *etm,
-			       struct cs_etm_traceid_queue *tidq, pid_t tid)
+static void cs_etm__set_thread(struct cs_etm_queue *etmq,
+			       struct cs_etm_traceid_queue *tidq, pid_t tid,
+			       ocsd_ex_level el)
 {
-	struct machine *machine = &etm->session->machines.host;
+	struct machine *machine = cs_etm__get_machine(etmq, el);
 
 	if (tid != -1) {
 		thread__zput(tidq->thread);
@@ -1319,10 +1360,12 @@ static void cs_etm__set_thread(struct cs_etm_auxtrace *etm,
 	/* Couldn't find a known thread */
 	if (!tidq->thread)
 		tidq->thread = machine__idle_thread(machine);
+
+	tidq->el = el;
 }
 
-int cs_etm__etmq_set_tid(struct cs_etm_queue *etmq,
-			 pid_t tid, u8 trace_chan_id)
+int cs_etm__etmq_set_tid_el(struct cs_etm_queue *etmq, pid_t tid,
+			    u8 trace_chan_id, ocsd_ex_level el)
 {
 	struct cs_etm_traceid_queue *tidq;
 
@@ -1330,7 +1373,7 @@ int cs_etm__etmq_set_tid(struct cs_etm_queue *etmq,
 	if (!tidq)
 		return -EINVAL;
 
-	cs_etm__set_thread(etmq->etm, tidq, tid);
+	cs_etm__set_thread(etmq, tidq, tid, el);
 	return 0;
 }
 
@@ -1400,7 +1443,7 @@ static int cs_etm__synth_instruction_sample(struct cs_etm_queue *etmq,
 	struct perf_sample sample = {.ip = 0,};
 
 	event->sample.header.type = PERF_RECORD_SAMPLE;
-	event->sample.header.misc = cs_etm__cpu_mode(etmq, addr);
+	event->sample.header.misc = cs_etm__cpu_mode(etmq, addr, tidq->el);
 	event->sample.header.size = sizeof(struct perf_event_header);
 
 	/* Set time field based on etm auxtrace config. */
@@ -1459,7 +1502,8 @@ static int cs_etm__synth_branch_sample(struct cs_etm_queue *etmq,
 	ip = cs_etm__last_executed_instr(tidq->prev_packet);
 
 	event->sample.header.type = PERF_RECORD_SAMPLE;
-	event->sample.header.misc = cs_etm__cpu_mode(etmq, ip);
+	event->sample.header.misc = cs_etm__cpu_mode(etmq, ip,
+						     tidq->prev_packet_el);
 	event->sample.header.size = sizeof(struct perf_event_header);
 
 	/* Set time field based on etm auxtrace config. */
diff --git a/tools/perf/util/cs-etm.h b/tools/perf/util/cs-etm.h
index 2f47f4ec5b27..7cca37887917 100644
--- a/tools/perf/util/cs-etm.h
+++ b/tools/perf/util/cs-etm.h
@@ -251,10 +251,11 @@ enum cs_etm_pid_fmt {
 };
 
 #ifdef HAVE_CSTRACE_SUPPORT
+#include <opencsd/ocsd_if_types.h>
 int cs_etm__get_cpu(u8 trace_chan_id, int *cpu);
-enum pid_fmt cs_etm__get_pid_fmt(struct cs_etm_queue *etmq);
-int cs_etm__etmq_set_tid(struct cs_etm_queue *etmq,
-			 pid_t tid, u8 trace_chan_id);
+enum cs_etm_pid_fmt cs_etm__get_pid_fmt(struct cs_etm_queue *etmq);
+int cs_etm__etmq_set_tid_el(struct cs_etm_queue *etmq, pid_t tid,
+			    u8 trace_chan_id, ocsd_ex_level el);
 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.34.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 5/5] perf cs-etm: Add exception level consistency check
  2023-06-12 11:13 [PATCH v3 0/5] perf cs-etm: Track exception level James Clark
                   ` (3 preceding siblings ...)
  2023-06-12 11:14 ` [PATCH v3 4/5] perf cs-etm: Track exception level James Clark
@ 2023-06-12 11:14 ` James Clark
  2023-06-12 18:32   ` Arnaldo Carvalho de Melo
  5 siblings, 0 replies; 12+ messages in thread
From: James Clark @ 2023-06-12 11:14 UTC (permalink / raw)
  To: coresight
  Cc: James Clark, Suzuki K Poulose, Mike Leach, Leo Yan,
	Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Mark Rutland, Alexander Shishkin, Jiri Olsa, Namhyung Kim,
	Ian Rogers, Adrian Hunter, John Garry, Will Deacon,
	linux-arm-kernel, linux-perf-users, linux-kernel

Assert that our own tracking of the exception level matches what
OpenCSD provides. OpenCSD doesn't distinguish between EL0 and EL1 in the
memory access callback so the extra tracking was required. But a rough
assert can still be done.

Signed-off-by: James Clark <james.clark@arm.com>
---
 .../perf/util/cs-etm-decoder/cs-etm-decoder.c |  6 +--
 .../perf/util/cs-etm-decoder/cs-etm-decoder.h |  4 +-
 tools/perf/util/cs-etm.c                      | 41 ++++++++++++++-----
 3 files changed, 36 insertions(+), 15 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 44c49acd6bff..e917985bbbe6 100644
--- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
+++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
@@ -52,15 +52,15 @@ struct cs_etm_decoder {
 static u32
 cs_etm_decoder__mem_access(const void *context,
 			   const ocsd_vaddr_t address,
-			   const ocsd_mem_space_acc_t mem_space __maybe_unused,
+			   const ocsd_mem_space_acc_t mem_space,
 			   const u8 trace_chan_id,
 			   const u32 req_size,
 			   u8 *buffer)
 {
 	struct cs_etm_decoder *decoder = (struct cs_etm_decoder *) context;
 
-	return decoder->mem_access(decoder->data, trace_chan_id,
-				   address, req_size, buffer);
+	return decoder->mem_access(decoder->data, trace_chan_id, address,
+				   req_size, buffer, mem_space);
 }
 
 int cs_etm_decoder__add_mem_access_cb(struct cs_etm_decoder *decoder,
diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h
index 21d403f55d96..272c2efe78ee 100644
--- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h
+++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h
@@ -11,6 +11,7 @@
 #define INCLUDE__CS_ETM_DECODER_H__
 
 #include <linux/types.h>
+#include <opencsd/ocsd_if_types.h>
 #include <stdio.h>
 
 struct cs_etm_decoder;
@@ -19,7 +20,8 @@ struct cs_etm_packet_queue;
 
 struct cs_etm_queue;
 
-typedef u32 (*cs_etm_mem_cb_type)(struct cs_etm_queue *, u8, u64, size_t, u8 *);
+typedef u32 (*cs_etm_mem_cb_type)(struct cs_etm_queue *, u8, u64, size_t, u8 *,
+				  const ocsd_mem_space_acc_t);
 
 struct cs_etmv3_trace_params {
 	u32 reg_ctrl;
diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
index bd724f3b7e35..22acc4e1f7ce 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
@@ -951,7 +951,8 @@ static u8 cs_etm__cpu_mode(struct cs_etm_queue *etmq, u64 address,
 }
 
 static u32 cs_etm__mem_access(struct cs_etm_queue *etmq, u8 trace_chan_id,
-			      u64 address, size_t size, u8 *buffer)
+			      u64 address, size_t size, u8 *buffer,
+			      const ocsd_mem_space_acc_t mem_space)
 {
 	u8  cpumode;
 	u64 offset;
@@ -967,6 +968,24 @@ static u32 cs_etm__mem_access(struct cs_etm_queue *etmq, u8 trace_chan_id,
 	if (!tidq)
 		return 0;
 
+	/*
+	 * We've already tracked EL along side the PID in cs_etm__set_thread()
+	 * so double check that it matches what OpenCSD thinks as well. It
+	 * doesn't distinguish between EL0 and EL1 for this mem access callback
+	 * so we had to do the extra tracking. Skip validation if it's any of
+	 * the 'any' values.
+	 */
+	if (!(mem_space == OCSD_MEM_SPACE_ANY ||
+	      mem_space == OCSD_MEM_SPACE_N || mem_space == OCSD_MEM_SPACE_S)) {
+		if (mem_space & OCSD_MEM_SPACE_EL1N) {
+			/* Includes both non secure EL1 and EL0 */
+			assert(tidq->el == ocsd_EL1 || tidq->el == ocsd_EL0);
+		} else if (mem_space & OCSD_MEM_SPACE_EL2)
+			assert(tidq->el == ocsd_EL2);
+		else if (mem_space & OCSD_MEM_SPACE_EL3)
+			assert(tidq->el == ocsd_EL3);
+	}
+
 	cpumode = cs_etm__cpu_mode(etmq, address, tidq->el);
 
 	if (!thread__find_map(tidq->thread, cpumode, address, &al))
@@ -1215,8 +1234,8 @@ static inline int cs_etm__t32_instr_size(struct cs_etm_queue *etmq,
 {
 	u8 instrBytes[2];
 
-	cs_etm__mem_access(etmq, trace_chan_id, addr,
-			   ARRAY_SIZE(instrBytes), instrBytes);
+	cs_etm__mem_access(etmq, trace_chan_id, addr, ARRAY_SIZE(instrBytes),
+			   instrBytes, 0);
 	/*
 	 * T32 instruction size is indicated by bits[15:11] of the first
 	 * 16-bit word of the instruction: 0b11101, 0b11110 and 0b11111
@@ -1407,8 +1426,8 @@ static void cs_etm__copy_insn(struct cs_etm_queue *etmq,
 	else
 		sample->insn_len = 4;
 
-	cs_etm__mem_access(etmq, trace_chan_id, sample->ip,
-			   sample->insn_len, (void *)sample->insn);
+	cs_etm__mem_access(etmq, trace_chan_id, sample->ip, sample->insn_len,
+			   (void *)sample->insn, 0);
 }
 
 u64 cs_etm__convert_sample_time(struct cs_etm_queue *etmq, u64 cs_timestamp)
@@ -1961,8 +1980,8 @@ static bool cs_etm__is_svc_instr(struct cs_etm_queue *etmq, u8 trace_chan_id,
 		 * so below only read 2 bytes as instruction size for T32.
 		 */
 		addr = end_addr - 2;
-		cs_etm__mem_access(etmq, trace_chan_id, addr,
-				   sizeof(instr16), (u8 *)&instr16);
+		cs_etm__mem_access(etmq, trace_chan_id, addr, sizeof(instr16),
+				   (u8 *)&instr16, 0);
 		if ((instr16 & 0xFF00) == 0xDF00)
 			return true;
 
@@ -1977,8 +1996,8 @@ static bool cs_etm__is_svc_instr(struct cs_etm_queue *etmq, u8 trace_chan_id,
 		 * +---------+---------+-------------------------+
 		 */
 		addr = end_addr - 4;
-		cs_etm__mem_access(etmq, trace_chan_id, addr,
-				   sizeof(instr32), (u8 *)&instr32);
+		cs_etm__mem_access(etmq, trace_chan_id, addr, sizeof(instr32),
+				   (u8 *)&instr32, 0);
 		if ((instr32 & 0x0F000000) == 0x0F000000 &&
 		    (instr32 & 0xF0000000) != 0xF0000000)
 			return true;
@@ -1994,8 +2013,8 @@ static bool cs_etm__is_svc_instr(struct cs_etm_queue *etmq, u8 trace_chan_id,
 		 * +-----------------------+---------+-----------+
 		 */
 		addr = end_addr - 4;
-		cs_etm__mem_access(etmq, trace_chan_id, addr,
-				   sizeof(instr32), (u8 *)&instr32);
+		cs_etm__mem_access(etmq, trace_chan_id, addr, sizeof(instr32),
+				   (u8 *)&instr32, 0);
 		if ((instr32 & 0xFFE0001F) == 0xd4000001)
 			return true;
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 0/5] perf cs-etm: Track exception level
  2023-06-12 11:13 [PATCH v3 0/5] perf cs-etm: Track exception level James Clark
@ 2023-06-12 18:32   ` Arnaldo Carvalho de Melo
  2023-06-12 11:13 ` [PATCH v3 2/5] perf cs-etm: Use previous thread for branch sample source IP James Clark
                     ` (4 subsequent siblings)
  5 siblings, 0 replies; 12+ messages in thread
From: Arnaldo Carvalho de Melo @ 2023-06-12 18:32 UTC (permalink / raw)
  To: James Clark
  Cc: coresight, Suzuki K Poulose, Mike Leach, Leo Yan, Peter Zijlstra,
	Ingo Molnar, Mark Rutland, Alexander Shishkin, Jiri Olsa,
	Namhyung Kim, Ian Rogers, Adrian Hunter, John Garry, Will Deacon,
	linux-arm-kernel, linux-perf-users, linux-kernel

Em Mon, Jun 12, 2023 at 12:13:57PM +0100, James Clark escreveu:
> Changes since v2:
> 
>   * Rename prev_thread -> prev_packet_thread and prev_el ->
>     prev_packet_el
>   * Add a comment about tracking the previous packet's thread
> 
> Changes since v1:
> 
>   * Always assume host kernel when the trace was captured at EL1 (nVHE)
>   * Fix EL validation to work with ETMv3
>   * Add a commit to make PID format accessible from struct
>     cs_etm_auxtrace

Please take a look in my tmp.perf-tools-next branch, there were some
conflicts I had to fix as those files were touched by refactorings for
addr_location and thread reference counting.

⬢[acme@toolbox perf-tools-next]$ git log --oneline -10
aa53fb2c482e70c2 (HEAD -> perf-tools-next) perf cs-etm: Add exception level consistency check
2918e9895224541f perf cs-etm: Track exception level
f492a33909829a75 perf cs-etm: Make PID format accessible from struct cs_etm_auxtrace
e29ec19b0751c6b2 perf cs-etm: Use previous thread for branch sample source IP
e9e03e9c3ca7088c perf cs-etm: Only track threads instead of PID and TIDs
6fd34445b8c94aa7 perf map: Fix double 'struct map' reference free found with -DREFCNT_CHECKING=1
e9c0a7f63e45e76f perf srcline: Optimize comparision against SRCLINE_UNKNOWN
fd87a79c7ed62804 perf hist: Fix srcline memory leak
933f9651d47cdda2 perf srcline: Change free_srcline to zfree_srcline
d22cfb063bcc674e perf callchain: Use pthread keys for tls callchain_cursor
⬢[acme@toolbox perf-tools-next]$


- Arnaldo
 
> ======
> 
> Some fixes to support an issue reported by Denis Nikitin where decoding
> trace that contains different EL1 and EL2 kernels can crash or go into
> an infinite loop because the wrong kernel maps are used for the decode.
> 
> This still doesn't support distinguishing guest and host userspace,
> we'd still have to fix the timestamps and do a bit more work to
> correlate that. And I've removed PERF_RECORD_MISC_HYPERVISOR as a
> possible outcome of cs_etm__cpu_mode(). As far as I know this could
> never have been returned anyway because machine__is_host(machine) was
> always true due to session.machines.host being hard coded. And I'm not
> sure of the relevance of the difference between PERF_RECORD_MISC_KERNEL
> and PERF_RECORD_MISC_HYPERVISOR in this scenario.
> 
> The first commit is a tidy up, second fixes a bug that I found when
> comparing the exception level and thread of branch records, the third
> is the main fix, and the last commit is some extra error checking. 
> 
> Applies to acme/perf-tools-next (42713dafc)
> 
> James Clark (5):
>   perf cs-etm: Only track threads instead of PID and TIDs
>   perf cs-etm: Use previous thread for branch sample source IP
>   perf cs-etm: Make PID format accessible from struct cs_etm_auxtrace
>   perf cs-etm: Track exception level
>   perf cs-etm: Add exception level consistency check
> 
>  .../perf/util/cs-etm-decoder/cs-etm-decoder.c |  33 +-
>  .../perf/util/cs-etm-decoder/cs-etm-decoder.h |   4 +-
>  tools/perf/util/cs-etm.c                      | 282 ++++++++++--------
>  tools/perf/util/cs-etm.h                      |  13 +-
>  4 files changed, 184 insertions(+), 148 deletions(-)
> 
> -- 
> 2.34.1
> 

-- 

- Arnaldo

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 0/5] perf cs-etm: Track exception level
@ 2023-06-12 18:32   ` Arnaldo Carvalho de Melo
  0 siblings, 0 replies; 12+ messages in thread
From: Arnaldo Carvalho de Melo @ 2023-06-12 18:32 UTC (permalink / raw)
  To: James Clark
  Cc: coresight, Suzuki K Poulose, Mike Leach, Leo Yan, Peter Zijlstra,
	Ingo Molnar, Mark Rutland, Alexander Shishkin, Jiri Olsa,
	Namhyung Kim, Ian Rogers, Adrian Hunter, John Garry, Will Deacon,
	linux-arm-kernel, linux-perf-users, linux-kernel

Em Mon, Jun 12, 2023 at 12:13:57PM +0100, James Clark escreveu:
> Changes since v2:
> 
>   * Rename prev_thread -> prev_packet_thread and prev_el ->
>     prev_packet_el
>   * Add a comment about tracking the previous packet's thread
> 
> Changes since v1:
> 
>   * Always assume host kernel when the trace was captured at EL1 (nVHE)
>   * Fix EL validation to work with ETMv3
>   * Add a commit to make PID format accessible from struct
>     cs_etm_auxtrace

Please take a look in my tmp.perf-tools-next branch, there were some
conflicts I had to fix as those files were touched by refactorings for
addr_location and thread reference counting.

⬢[acme@toolbox perf-tools-next]$ git log --oneline -10
aa53fb2c482e70c2 (HEAD -> perf-tools-next) perf cs-etm: Add exception level consistency check
2918e9895224541f perf cs-etm: Track exception level
f492a33909829a75 perf cs-etm: Make PID format accessible from struct cs_etm_auxtrace
e29ec19b0751c6b2 perf cs-etm: Use previous thread for branch sample source IP
e9e03e9c3ca7088c perf cs-etm: Only track threads instead of PID and TIDs
6fd34445b8c94aa7 perf map: Fix double 'struct map' reference free found with -DREFCNT_CHECKING=1
e9c0a7f63e45e76f perf srcline: Optimize comparision against SRCLINE_UNKNOWN
fd87a79c7ed62804 perf hist: Fix srcline memory leak
933f9651d47cdda2 perf srcline: Change free_srcline to zfree_srcline
d22cfb063bcc674e perf callchain: Use pthread keys for tls callchain_cursor
⬢[acme@toolbox perf-tools-next]$


- Arnaldo
 
> ======
> 
> Some fixes to support an issue reported by Denis Nikitin where decoding
> trace that contains different EL1 and EL2 kernels can crash or go into
> an infinite loop because the wrong kernel maps are used for the decode.
> 
> This still doesn't support distinguishing guest and host userspace,
> we'd still have to fix the timestamps and do a bit more work to
> correlate that. And I've removed PERF_RECORD_MISC_HYPERVISOR as a
> possible outcome of cs_etm__cpu_mode(). As far as I know this could
> never have been returned anyway because machine__is_host(machine) was
> always true due to session.machines.host being hard coded. And I'm not
> sure of the relevance of the difference between PERF_RECORD_MISC_KERNEL
> and PERF_RECORD_MISC_HYPERVISOR in this scenario.
> 
> The first commit is a tidy up, second fixes a bug that I found when
> comparing the exception level and thread of branch records, the third
> is the main fix, and the last commit is some extra error checking. 
> 
> Applies to acme/perf-tools-next (42713dafc)
> 
> James Clark (5):
>   perf cs-etm: Only track threads instead of PID and TIDs
>   perf cs-etm: Use previous thread for branch sample source IP
>   perf cs-etm: Make PID format accessible from struct cs_etm_auxtrace
>   perf cs-etm: Track exception level
>   perf cs-etm: Add exception level consistency check
> 
>  .../perf/util/cs-etm-decoder/cs-etm-decoder.c |  33 +-
>  .../perf/util/cs-etm-decoder/cs-etm-decoder.h |   4 +-
>  tools/perf/util/cs-etm.c                      | 282 ++++++++++--------
>  tools/perf/util/cs-etm.h                      |  13 +-
>  4 files changed, 184 insertions(+), 148 deletions(-)
> 
> -- 
> 2.34.1
> 

-- 

- Arnaldo

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 0/5] perf cs-etm: Track exception level
  2023-06-12 18:32   ` Arnaldo Carvalho de Melo
@ 2023-06-13  8:56     ` James Clark
  -1 siblings, 0 replies; 12+ messages in thread
From: James Clark @ 2023-06-13  8:56 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: coresight, Suzuki K Poulose, Mike Leach, Leo Yan, Peter Zijlstra,
	Ingo Molnar, Mark Rutland, Alexander Shishkin, Jiri Olsa,
	Namhyung Kim, Ian Rogers, Adrian Hunter, John Garry, Will Deacon,
	linux-arm-kernel, linux-perf-users, linux-kernel



On 12/06/2023 19:32, Arnaldo Carvalho de Melo wrote:
> Em Mon, Jun 12, 2023 at 12:13:57PM +0100, James Clark escreveu:
>> Changes since v2:
>>
>>   * Rename prev_thread -> prev_packet_thread and prev_el ->
>>     prev_packet_el
>>   * Add a comment about tracking the previous packet's thread
>>
>> Changes since v1:
>>
>>   * Always assume host kernel when the trace was captured at EL1 (nVHE)
>>   * Fix EL validation to work with ETMv3
>>   * Add a commit to make PID format accessible from struct
>>     cs_etm_auxtrace
> 
> Please take a look in my tmp.perf-tools-next branch, there were some
> conflicts I had to fix as those files were touched by refactorings for
> addr_location and thread reference counting.
> 

Yeah I got the same result and the tests are still passing. Thanks for
fixing those.

> ⬢[acme@toolbox perf-tools-next]$ git log --oneline -10
> aa53fb2c482e70c2 (HEAD -> perf-tools-next) perf cs-etm: Add exception level consistency check
> 2918e9895224541f perf cs-etm: Track exception level
> f492a33909829a75 perf cs-etm: Make PID format accessible from struct cs_etm_auxtrace
> e29ec19b0751c6b2 perf cs-etm: Use previous thread for branch sample source IP
> e9e03e9c3ca7088c perf cs-etm: Only track threads instead of PID and TIDs
> 6fd34445b8c94aa7 perf map: Fix double 'struct map' reference free found with -DREFCNT_CHECKING=1
> e9c0a7f63e45e76f perf srcline: Optimize comparision against SRCLINE_UNKNOWN
> fd87a79c7ed62804 perf hist: Fix srcline memory leak
> 933f9651d47cdda2 perf srcline: Change free_srcline to zfree_srcline
> d22cfb063bcc674e perf callchain: Use pthread keys for tls callchain_cursor
> ⬢[acme@toolbox perf-tools-next]$
> 
> 
> - Arnaldo
>  
>> ======
>>
>> Some fixes to support an issue reported by Denis Nikitin where decoding
>> trace that contains different EL1 and EL2 kernels can crash or go into
>> an infinite loop because the wrong kernel maps are used for the decode.
>>
>> This still doesn't support distinguishing guest and host userspace,
>> we'd still have to fix the timestamps and do a bit more work to
>> correlate that. And I've removed PERF_RECORD_MISC_HYPERVISOR as a
>> possible outcome of cs_etm__cpu_mode(). As far as I know this could
>> never have been returned anyway because machine__is_host(machine) was
>> always true due to session.machines.host being hard coded. And I'm not
>> sure of the relevance of the difference between PERF_RECORD_MISC_KERNEL
>> and PERF_RECORD_MISC_HYPERVISOR in this scenario.
>>
>> The first commit is a tidy up, second fixes a bug that I found when
>> comparing the exception level and thread of branch records, the third
>> is the main fix, and the last commit is some extra error checking. 
>>
>> Applies to acme/perf-tools-next (42713dafc)
>>
>> James Clark (5):
>>   perf cs-etm: Only track threads instead of PID and TIDs
>>   perf cs-etm: Use previous thread for branch sample source IP
>>   perf cs-etm: Make PID format accessible from struct cs_etm_auxtrace
>>   perf cs-etm: Track exception level
>>   perf cs-etm: Add exception level consistency check
>>
>>  .../perf/util/cs-etm-decoder/cs-etm-decoder.c |  33 +-
>>  .../perf/util/cs-etm-decoder/cs-etm-decoder.h |   4 +-
>>  tools/perf/util/cs-etm.c                      | 282 ++++++++++--------
>>  tools/perf/util/cs-etm.h                      |  13 +-
>>  4 files changed, 184 insertions(+), 148 deletions(-)
>>
>> -- 
>> 2.34.1
>>
> 

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 0/5] perf cs-etm: Track exception level
@ 2023-06-13  8:56     ` James Clark
  0 siblings, 0 replies; 12+ messages in thread
From: James Clark @ 2023-06-13  8:56 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: coresight, Suzuki K Poulose, Mike Leach, Leo Yan, Peter Zijlstra,
	Ingo Molnar, Mark Rutland, Alexander Shishkin, Jiri Olsa,
	Namhyung Kim, Ian Rogers, Adrian Hunter, John Garry, Will Deacon,
	linux-arm-kernel, linux-perf-users, linux-kernel



On 12/06/2023 19:32, Arnaldo Carvalho de Melo wrote:
> Em Mon, Jun 12, 2023 at 12:13:57PM +0100, James Clark escreveu:
>> Changes since v2:
>>
>>   * Rename prev_thread -> prev_packet_thread and prev_el ->
>>     prev_packet_el
>>   * Add a comment about tracking the previous packet's thread
>>
>> Changes since v1:
>>
>>   * Always assume host kernel when the trace was captured at EL1 (nVHE)
>>   * Fix EL validation to work with ETMv3
>>   * Add a commit to make PID format accessible from struct
>>     cs_etm_auxtrace
> 
> Please take a look in my tmp.perf-tools-next branch, there were some
> conflicts I had to fix as those files were touched by refactorings for
> addr_location and thread reference counting.
> 

Yeah I got the same result and the tests are still passing. Thanks for
fixing those.

> ⬢[acme@toolbox perf-tools-next]$ git log --oneline -10
> aa53fb2c482e70c2 (HEAD -> perf-tools-next) perf cs-etm: Add exception level consistency check
> 2918e9895224541f perf cs-etm: Track exception level
> f492a33909829a75 perf cs-etm: Make PID format accessible from struct cs_etm_auxtrace
> e29ec19b0751c6b2 perf cs-etm: Use previous thread for branch sample source IP
> e9e03e9c3ca7088c perf cs-etm: Only track threads instead of PID and TIDs
> 6fd34445b8c94aa7 perf map: Fix double 'struct map' reference free found with -DREFCNT_CHECKING=1
> e9c0a7f63e45e76f perf srcline: Optimize comparision against SRCLINE_UNKNOWN
> fd87a79c7ed62804 perf hist: Fix srcline memory leak
> 933f9651d47cdda2 perf srcline: Change free_srcline to zfree_srcline
> d22cfb063bcc674e perf callchain: Use pthread keys for tls callchain_cursor
> ⬢[acme@toolbox perf-tools-next]$
> 
> 
> - Arnaldo
>  
>> ======
>>
>> Some fixes to support an issue reported by Denis Nikitin where decoding
>> trace that contains different EL1 and EL2 kernels can crash or go into
>> an infinite loop because the wrong kernel maps are used for the decode.
>>
>> This still doesn't support distinguishing guest and host userspace,
>> we'd still have to fix the timestamps and do a bit more work to
>> correlate that. And I've removed PERF_RECORD_MISC_HYPERVISOR as a
>> possible outcome of cs_etm__cpu_mode(). As far as I know this could
>> never have been returned anyway because machine__is_host(machine) was
>> always true due to session.machines.host being hard coded. And I'm not
>> sure of the relevance of the difference between PERF_RECORD_MISC_KERNEL
>> and PERF_RECORD_MISC_HYPERVISOR in this scenario.
>>
>> The first commit is a tidy up, second fixes a bug that I found when
>> comparing the exception level and thread of branch records, the third
>> is the main fix, and the last commit is some extra error checking. 
>>
>> Applies to acme/perf-tools-next (42713dafc)
>>
>> James Clark (5):
>>   perf cs-etm: Only track threads instead of PID and TIDs
>>   perf cs-etm: Use previous thread for branch sample source IP
>>   perf cs-etm: Make PID format accessible from struct cs_etm_auxtrace
>>   perf cs-etm: Track exception level
>>   perf cs-etm: Add exception level consistency check
>>
>>  .../perf/util/cs-etm-decoder/cs-etm-decoder.c |  33 +-
>>  .../perf/util/cs-etm-decoder/cs-etm-decoder.h |   4 +-
>>  tools/perf/util/cs-etm.c                      | 282 ++++++++++--------
>>  tools/perf/util/cs-etm.h                      |  13 +-
>>  4 files changed, 184 insertions(+), 148 deletions(-)
>>
>> -- 
>> 2.34.1
>>
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 0/5] perf cs-etm: Track exception level
  2023-06-13  8:56     ` James Clark
@ 2023-06-13 19:42       ` Arnaldo Carvalho de Melo
  -1 siblings, 0 replies; 12+ messages in thread
From: Arnaldo Carvalho de Melo @ 2023-06-13 19:42 UTC (permalink / raw)
  To: James Clark
  Cc: coresight, Suzuki K Poulose, Mike Leach, Leo Yan, Peter Zijlstra,
	Ingo Molnar, Mark Rutland, Alexander Shishkin, Jiri Olsa,
	Namhyung Kim, Ian Rogers, Adrian Hunter, John Garry, Will Deacon,
	linux-arm-kernel, linux-perf-users, linux-kernel

Em Tue, Jun 13, 2023 at 09:56:29AM +0100, James Clark escreveu:
> 
> 
> On 12/06/2023 19:32, Arnaldo Carvalho de Melo wrote:
> > Em Mon, Jun 12, 2023 at 12:13:57PM +0100, James Clark escreveu:
> >> Changes since v2:
> >>
> >>   * Rename prev_thread -> prev_packet_thread and prev_el ->
> >>     prev_packet_el
> >>   * Add a comment about tracking the previous packet's thread
> >>
> >> Changes since v1:
> >>
> >>   * Always assume host kernel when the trace was captured at EL1 (nVHE)
> >>   * Fix EL validation to work with ETMv3
> >>   * Add a commit to make PID format accessible from struct
> >>     cs_etm_auxtrace
> > 
> > Please take a look in my tmp.perf-tools-next branch, there were some
> > conflicts I had to fix as those files were touched by refactorings for
> > addr_location and thread reference counting.
> > 
> 
> Yeah I got the same result and the tests are still passing. Thanks for
> fixing those.

Thanks for double checking that!

- Arnaldo
 
> > ⬢[acme@toolbox perf-tools-next]$ git log --oneline -10
> > aa53fb2c482e70c2 (HEAD -> perf-tools-next) perf cs-etm: Add exception level consistency check
> > 2918e9895224541f perf cs-etm: Track exception level
> > f492a33909829a75 perf cs-etm: Make PID format accessible from struct cs_etm_auxtrace
> > e29ec19b0751c6b2 perf cs-etm: Use previous thread for branch sample source IP
> > e9e03e9c3ca7088c perf cs-etm: Only track threads instead of PID and TIDs
> > 6fd34445b8c94aa7 perf map: Fix double 'struct map' reference free found with -DREFCNT_CHECKING=1
> > e9c0a7f63e45e76f perf srcline: Optimize comparision against SRCLINE_UNKNOWN
> > fd87a79c7ed62804 perf hist: Fix srcline memory leak
> > 933f9651d47cdda2 perf srcline: Change free_srcline to zfree_srcline
> > d22cfb063bcc674e perf callchain: Use pthread keys for tls callchain_cursor
> > ⬢[acme@toolbox perf-tools-next]$
> > 
> > 
> > - Arnaldo
> >  
> >> ======
> >>
> >> Some fixes to support an issue reported by Denis Nikitin where decoding
> >> trace that contains different EL1 and EL2 kernels can crash or go into
> >> an infinite loop because the wrong kernel maps are used for the decode.
> >>
> >> This still doesn't support distinguishing guest and host userspace,
> >> we'd still have to fix the timestamps and do a bit more work to
> >> correlate that. And I've removed PERF_RECORD_MISC_HYPERVISOR as a
> >> possible outcome of cs_etm__cpu_mode(). As far as I know this could
> >> never have been returned anyway because machine__is_host(machine) was
> >> always true due to session.machines.host being hard coded. And I'm not
> >> sure of the relevance of the difference between PERF_RECORD_MISC_KERNEL
> >> and PERF_RECORD_MISC_HYPERVISOR in this scenario.
> >>
> >> The first commit is a tidy up, second fixes a bug that I found when
> >> comparing the exception level and thread of branch records, the third
> >> is the main fix, and the last commit is some extra error checking. 
> >>
> >> Applies to acme/perf-tools-next (42713dafc)
> >>
> >> James Clark (5):
> >>   perf cs-etm: Only track threads instead of PID and TIDs
> >>   perf cs-etm: Use previous thread for branch sample source IP
> >>   perf cs-etm: Make PID format accessible from struct cs_etm_auxtrace
> >>   perf cs-etm: Track exception level
> >>   perf cs-etm: Add exception level consistency check
> >>
> >>  .../perf/util/cs-etm-decoder/cs-etm-decoder.c |  33 +-
> >>  .../perf/util/cs-etm-decoder/cs-etm-decoder.h |   4 +-
> >>  tools/perf/util/cs-etm.c                      | 282 ++++++++++--------
> >>  tools/perf/util/cs-etm.h                      |  13 +-
> >>  4 files changed, 184 insertions(+), 148 deletions(-)
> >>
> >> -- 
> >> 2.34.1
> >>
> > 

-- 

- Arnaldo

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 0/5] perf cs-etm: Track exception level
@ 2023-06-13 19:42       ` Arnaldo Carvalho de Melo
  0 siblings, 0 replies; 12+ messages in thread
From: Arnaldo Carvalho de Melo @ 2023-06-13 19:42 UTC (permalink / raw)
  To: James Clark
  Cc: coresight, Suzuki K Poulose, Mike Leach, Leo Yan, Peter Zijlstra,
	Ingo Molnar, Mark Rutland, Alexander Shishkin, Jiri Olsa,
	Namhyung Kim, Ian Rogers, Adrian Hunter, John Garry, Will Deacon,
	linux-arm-kernel, linux-perf-users, linux-kernel

Em Tue, Jun 13, 2023 at 09:56:29AM +0100, James Clark escreveu:
> 
> 
> On 12/06/2023 19:32, Arnaldo Carvalho de Melo wrote:
> > Em Mon, Jun 12, 2023 at 12:13:57PM +0100, James Clark escreveu:
> >> Changes since v2:
> >>
> >>   * Rename prev_thread -> prev_packet_thread and prev_el ->
> >>     prev_packet_el
> >>   * Add a comment about tracking the previous packet's thread
> >>
> >> Changes since v1:
> >>
> >>   * Always assume host kernel when the trace was captured at EL1 (nVHE)
> >>   * Fix EL validation to work with ETMv3
> >>   * Add a commit to make PID format accessible from struct
> >>     cs_etm_auxtrace
> > 
> > Please take a look in my tmp.perf-tools-next branch, there were some
> > conflicts I had to fix as those files were touched by refactorings for
> > addr_location and thread reference counting.
> > 
> 
> Yeah I got the same result and the tests are still passing. Thanks for
> fixing those.

Thanks for double checking that!

- Arnaldo
 
> > ⬢[acme@toolbox perf-tools-next]$ git log --oneline -10
> > aa53fb2c482e70c2 (HEAD -> perf-tools-next) perf cs-etm: Add exception level consistency check
> > 2918e9895224541f perf cs-etm: Track exception level
> > f492a33909829a75 perf cs-etm: Make PID format accessible from struct cs_etm_auxtrace
> > e29ec19b0751c6b2 perf cs-etm: Use previous thread for branch sample source IP
> > e9e03e9c3ca7088c perf cs-etm: Only track threads instead of PID and TIDs
> > 6fd34445b8c94aa7 perf map: Fix double 'struct map' reference free found with -DREFCNT_CHECKING=1
> > e9c0a7f63e45e76f perf srcline: Optimize comparision against SRCLINE_UNKNOWN
> > fd87a79c7ed62804 perf hist: Fix srcline memory leak
> > 933f9651d47cdda2 perf srcline: Change free_srcline to zfree_srcline
> > d22cfb063bcc674e perf callchain: Use pthread keys for tls callchain_cursor
> > ⬢[acme@toolbox perf-tools-next]$
> > 
> > 
> > - Arnaldo
> >  
> >> ======
> >>
> >> Some fixes to support an issue reported by Denis Nikitin where decoding
> >> trace that contains different EL1 and EL2 kernels can crash or go into
> >> an infinite loop because the wrong kernel maps are used for the decode.
> >>
> >> This still doesn't support distinguishing guest and host userspace,
> >> we'd still have to fix the timestamps and do a bit more work to
> >> correlate that. And I've removed PERF_RECORD_MISC_HYPERVISOR as a
> >> possible outcome of cs_etm__cpu_mode(). As far as I know this could
> >> never have been returned anyway because machine__is_host(machine) was
> >> always true due to session.machines.host being hard coded. And I'm not
> >> sure of the relevance of the difference between PERF_RECORD_MISC_KERNEL
> >> and PERF_RECORD_MISC_HYPERVISOR in this scenario.
> >>
> >> The first commit is a tidy up, second fixes a bug that I found when
> >> comparing the exception level and thread of branch records, the third
> >> is the main fix, and the last commit is some extra error checking. 
> >>
> >> Applies to acme/perf-tools-next (42713dafc)
> >>
> >> James Clark (5):
> >>   perf cs-etm: Only track threads instead of PID and TIDs
> >>   perf cs-etm: Use previous thread for branch sample source IP
> >>   perf cs-etm: Make PID format accessible from struct cs_etm_auxtrace
> >>   perf cs-etm: Track exception level
> >>   perf cs-etm: Add exception level consistency check
> >>
> >>  .../perf/util/cs-etm-decoder/cs-etm-decoder.c |  33 +-
> >>  .../perf/util/cs-etm-decoder/cs-etm-decoder.h |   4 +-
> >>  tools/perf/util/cs-etm.c                      | 282 ++++++++++--------
> >>  tools/perf/util/cs-etm.h                      |  13 +-
> >>  4 files changed, 184 insertions(+), 148 deletions(-)
> >>
> >> -- 
> >> 2.34.1
> >>
> > 

-- 

- Arnaldo

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2023-06-13 19:43 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-12 11:13 [PATCH v3 0/5] perf cs-etm: Track exception level James Clark
2023-06-12 11:13 ` [PATCH v3 1/5] perf cs-etm: Only track threads instead of PID and TIDs James Clark
2023-06-12 11:13 ` [PATCH v3 2/5] perf cs-etm: Use previous thread for branch sample source IP James Clark
2023-06-12 11:14 ` [PATCH v3 3/5] perf cs-etm: Make PID format accessible from struct cs_etm_auxtrace James Clark
2023-06-12 11:14 ` [PATCH v3 4/5] perf cs-etm: Track exception level James Clark
2023-06-12 11:14 ` [PATCH v3 5/5] perf cs-etm: Add exception level consistency check James Clark
2023-06-12 18:32 ` [PATCH v3 0/5] perf cs-etm: Track exception level Arnaldo Carvalho de Melo
2023-06-12 18:32   ` Arnaldo Carvalho de Melo
2023-06-13  8:56   ` James Clark
2023-06-13  8:56     ` James Clark
2023-06-13 19:42     ` Arnaldo Carvalho de Melo
2023-06-13 19:42       ` Arnaldo Carvalho de Melo

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.