On Sat, Feb 06, 2021 at 11:08:31PM +0800, Leo Yan wrote: > 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@xxxxxxxxxx> Reviewed-by: Mathieu Poirier <mathieu.poirier@xxxxxxxxxx> > --- > 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 a2a369e2fbb6..b9c1d329a7f1 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 4ad925d6d799..7cc3bba0017d 100644 > --- a/tools/perf/util/cs-etm.h > +++ b/tools/perf/util/cs-etm.h > @@ -173,6 +173,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.25.1 >