From 873f25f55f18c471189b7439c09cbd2a311184e3 Mon Sep 17 00:00:00 2001 From: Elliot Berman Date: Thu, 7 Nov 2019 13:54:38 -0800 Subject: [PATCH] firmware: qcom_scm: Add trace points to scm driver Adding traces to find the arguments passed to secure world and the values returned. Change-Id: I6a90f968a05873f0ecbd4a0cc8c85d704e1d64cf Signed-off-by: Elliot Berman Signed-off-by: Siddharth Gupta --- drivers/firmware/qcom_scm-smc.c | 29 +++++++++++++++-- include/trace/events/scm.h | 57 +++++++++++++-------------------- 2 files changed, 49 insertions(+), 37 deletions(-) diff --git a/drivers/firmware/qcom_scm-smc.c b/drivers/firmware/qcom_scm-smc.c index 77f4cb28a97f..aceeeb41aad0 100644 --- a/drivers/firmware/qcom_scm-smc.c +++ b/drivers/firmware/qcom_scm-smc.c @@ -19,6 +19,9 @@ #include "qcom_scm.h" +#define CREATE_TRACE_POINTS +#include + #define MAX_QCOM_SCM_ARGS 10 #define MAX_QCOM_SCM_RETS 3 @@ -169,10 +172,15 @@ static void __qcom_scm_call_do_quirk(const struct arm_smccc_args *smc, struct arm_smccc_res *res) { unsigned long a0 = smc->a[0]; + ktime_t time; + const bool trace = trace_scm_call_enabled(); struct arm_smccc_quirk quirk = { .id = ARM_SMCCC_QUIRK_QCOM_A6 }; quirk.state.a6 = 0; + if (trace) + time = ktime_get(); + do { arm_smccc_smc_quirk(a0, smc->a[1], smc->a[2], smc->a[3], smc->a[4], smc->a[5], quirk.state.a6, @@ -182,6 +190,9 @@ static void __qcom_scm_call_do_quirk(const struct arm_smccc_args *smc, a0 = res->a0; } while (res->a0 == QCOM_SCM_INTERRUPTED); + + if (trace) + trace_scm_call(smc->a, res, ktime_us_delta(ktime_get(), time)); } static int qcom_scm_call_smccc(struct device *dev, @@ -261,9 +272,7 @@ static int qcom_scm_call_smccc(struct device *dev, do { mutex_lock(&qcom_scm_lock); - __qcom_scm_call_do_quirk(&smc, &res); - mutex_unlock(&qcom_scm_lock); if (res.a0 == QCOM_SCM_V2_EBUSY) { @@ -329,10 +338,19 @@ static inline void *legacy_get_response_buffer( static void __qcom_scm_call_do(const struct arm_smccc_args *smc, struct arm_smccc_res *res) { + ktime_t time; + const bool trace = trace_scm_call_enabled(); + + if (trace) + time = ktime_get(); + do { arm_smccc_smc(smc->a[0], smc->a[1], smc->a[2], smc->a[3], smc->a[4], smc->a[5], smc->a[6], smc->a[7], res); } while (res->a0 == QCOM_SCM_INTERRUPTED); + + if (trace) + trace_scm_call(smc->a, res, ktime_us_delta(ktime_get(), time)); } /** @@ -438,6 +456,8 @@ static int qcom_scm_call_atomic_legacy(struct device *dev, struct arm_smccc_args smc = {{0}}; struct arm_smccc_res res; size_t i, arglen = desc->arginfo & 0xf; + const bool trace = trace_scm_call_enabled(); + ktime_t time; BUG_ON(arglen > LEGACY_ATOMIC_N_REG_ARGS); @@ -447,9 +467,14 @@ static int qcom_scm_call_atomic_legacy(struct device *dev, for (i = 0; i < arglen; i++) smc.a[i + LEGACY_ATOMIC_FIRST_REG_IDX] = desc->args[i]; + if (trace) + time = ktime_get(); arm_smccc_smc(smc.a[0], smc.a[1], smc.a[2], smc.a[3], smc.a[4], smc.a[5], smc.a[6], smc.a[7], &res); + if (trace) + trace_scm_call(smc.a, &res, ktime_us_delta(ktime_get(), time)); + desc->res[0] = res.a1; desc->res[1] = res.a2; desc->res[2] = res.a3; diff --git a/include/trace/events/scm.h b/include/trace/events/scm.h index 860cb070cde3..ebca8f0ccf2b 100644 --- a/include/trace/events/scm.h +++ b/include/trace/events/scm.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2016, 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2016, 2018-2019 The Linux Foundation. All rights reserved. */ #undef TRACE_SYSTEM @@ -10,50 +10,37 @@ #define _TRACE_SCM_H #include #include -#include +#include -TRACE_EVENT(scm_call_start, +TRACE_EVENT(scm_call, - TP_PROTO(u64 x0, struct scm_desc *p), + TP_PROTO(const unsigned long *a, const struct arm_smccc_res *r, + const s64 delta), - TP_ARGS(x0, p), + TP_ARGS(a, r, delta), TP_STRUCT__entry( - __field(u64, x0) - __field(u32, arginfo) - __array(u64, args, MAX_SCM_ARGS) - __field(u64, x5) + __array(u64, args, 8) + __array(unsigned long, ret, 4) + __field(s64, delta) ), TP_fast_assign( - __entry->x0 = x0; - __entry->arginfo = p->arginfo; - memcpy(__entry->args, p->args, sizeof(__entry->args)); - __entry->x5 = p->x5; + memcpy(__entry->args, a, sizeof(__entry->args)); + __entry->ret[0] = r->a0; + __entry->ret[1] = r->a1; + __entry->ret[2] = r->a2; + __entry->ret[3] = r->a3; + __entry->delta = delta; ), - TP_printk("func id=%#llx (args: %#x, %#llx, %#llx, %#llx, %#llx)", - __entry->x0, __entry->arginfo, __entry->args[0], - __entry->args[1], __entry->args[2], __entry->x5) -); - - -TRACE_EVENT(scm_call_end, - - TP_PROTO(struct scm_desc *p), - - TP_ARGS(p), - - TP_STRUCT__entry( - __array(u64, ret, MAX_SCM_RETS) - ), - - TP_fast_assign( - memcpy(__entry->ret, p->ret, sizeof(__entry->ret)); - ), - - TP_printk("ret: %#llx, %#llx, %#llx", - __entry->ret[0], __entry->ret[1], __entry->ret[2]) + TP_printk("%3ld [%#lx %#lx %#lx %#lx %#lx %#lx %#lx %#lx] (%#lx %#lx %#lx %#lx)", + __entry->delta, + __entry->args[0], __entry->args[1], __entry->args[2], + __entry->args[3], __entry->args[4], __entry->args[5], + __entry->args[6], __entry->args[7], + __entry->ret[0], __entry->ret[1], + __entry->ret[2], __entry->ret[3]) ); #endif /* _TRACE_SCM_H */