perf cs-etm: Detect pid in VMID for kernel running at EL2

The PID of the task could be traced as VMID when the kernel is running
at EL2.  Teach the decoder to look for VMID when the CONTEXTIDR (Arm32)
or CONTEXTIDR_EL1 (Arm64) is invalid but we have a valid VMID.

Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Co-developed-by: Leo Yan <leo.yan@linaro.org>
Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: Al Grant <al.grant@arm.com>
Cc: Mike Leach <mike.leach@linaro.org>
Link: https://lore.kernel.org/r/20210213113220.292229-6-leo.yan@linaro.org
Link: https://lore.kernel.org/r/20210224164835.3497311-7-mathieu.poirier@linaro.org
Signed-off-by: Leo Yan <leo.yan@linaro.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Suzuki K Poulose 2021-02-24 09:48:35 -07:00 committed by Arnaldo Carvalho de Melo
parent 47f0d94c20
commit 8e1488a46d

View File

@ -6,6 +6,7 @@
* Author: Mathieu Poirier <mathieu.poirier@linaro.org>
*/
#include <linux/coresight-pmu.h>
#include <linux/err.h>
#include <linux/list.h>
#include <linux/zalloc.h>
@ -491,13 +492,42 @@ cs_etm_decoder__set_tid(struct cs_etm_queue *etmq,
const ocsd_generic_trace_elem *elem,
const uint8_t trace_chan_id)
{
pid_t tid;
pid_t tid = -1;
static u64 pid_fmt;
int ret;
/* Ignore PE_CONTEXT packets that don't have a valid contextID */
if (!elem->context.ctxt_id_valid)
/*
* 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):
if (elem->context.ctxt_id_valid)
tid = elem->context.context_id;
break;
case BIT(ETM_OPT_CTXTID2):
if (elem->context.vmid_valid)
tid = elem->context.vmid;
break;
default:
break;
}
if (tid == -1)
return OCSD_RESP_CONT;
tid = elem->context.context_id;
if (cs_etm__etmq_set_tid(etmq, tid, trace_chan_id))
return OCSD_RESP_FATAL_SYS_ERR;