| From 47f0d94c203751ddcfdb296fcf15df20fffcef0c Mon Sep 17 00:00:00 2001 |
| From: Leo Yan <leo.yan@linaro.org> |
| Date: Wed, 24 Feb 2021 09:48:34 -0700 |
| Subject: [PATCH 4/5] perf cs-etm: Add helper cs_etm__get_pid_fmt() |
| |
| This patch adds helper function cs_etm__get_pid_fmt(), by passing |
| parameter "traceID", it returns the PID format. |
| |
| Signed-off-by: Leo Yan <leo.yan@linaro.org> |
| Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org> |
| Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com> |
| Cc: Mike Leach <mike.leach@linaro.org> |
| Link: https://lore.kernel.org/r/20210213113220.292229-5-leo.yan@linaro.org |
| Link: https://lore.kernel.org/r/20210224164835.3497311-6-mathieu.poirier@linaro.org |
| Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> |
| --- |
| tools/perf/util/cs-etm.c | 42 ++++++++++++++++++++++++++++++++++++++++ |
| tools/perf/util/cs-etm.h | 1 + |
| 2 files changed, 43 insertions(+) |
| |
| diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c |
| index ee32d023e9bd..9ac80fc23c58 100644 |
| --- a/tools/perf/util/cs-etm.c |
| +++ b/tools/perf/util/cs-etm.c |
| @@ -7,6 +7,7 @@ |
| */ |
| |
| #include <linux/bitops.h> |
| +#include <linux/coresight-pmu.h> |
| #include <linux/err.h> |
| #include <linux/kernel.h> |
| #include <linux/log2.h> |
| @@ -156,6 +157,47 @@ int cs_etm__get_cpu(u8 trace_chan_id, int *cpu) |
| return 0; |
| } |
| |
| +/* |
| + * The returned PID format is presented by two bits: |
| + * |
| + * Bit ETM_OPT_CTXTID: CONTEXTIDR or CONTEXTIDR_EL1 is traced; |
| + * Bit ETM_OPT_CTXTID2: CONTEXTIDR_EL2 is traced. |
| + * |
| + * 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. |
| + */ |
| +int cs_etm__get_pid_fmt(u8 trace_chan_id, u64 *pid_fmt) |
| +{ |
| + struct int_node *inode; |
| + u64 *metadata, val; |
| + |
| + inode = intlist__find(traceid_list, trace_chan_id); |
| + if (!inode) |
| + return -EINVAL; |
| + |
| + metadata = inode->priv; |
| + |
| + 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); |
| + } 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); |
| + /* CONTEXTIDR_EL1 is traced */ |
| + else if (val & BIT(ETM4_CFG_BIT_CTXTID)) |
| + *pid_fmt = BIT(ETM_OPT_CTXTID); |
| + } |
| + |
| + return 0; |
| +} |
| + |
| void cs_etm__etmq_set_traceid_queue_timestamp(struct cs_etm_queue *etmq, |
| u8 trace_chan_id) |
| { |
| diff --git a/tools/perf/util/cs-etm.h b/tools/perf/util/cs-etm.h |
| index e153d02df0de..85ed11e9d2a7 100644 |
| --- a/tools/perf/util/cs-etm.h |
| +++ b/tools/perf/util/cs-etm.h |
| @@ -193,6 +193,7 @@ struct cs_etm_packet_queue { |
| int cs_etm__process_auxtrace_info(union perf_event *event, |
| struct perf_session *session); |
| int cs_etm__get_cpu(u8 trace_chan_id, int *cpu); |
| +int cs_etm__get_pid_fmt(u8 trace_chan_id, u64 *pid_fmt); |
| 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.32.0.rc1.229.g3e70b5a671-goog |
| |