mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v2 0/2] firmware: qcom: scm: add tracepoints for the SMC call interface
@ 2026-05-22  6:38 Yuvaraj Ranganathan
  2026-05-22  6:38 ` [PATCH v2 1/2] firmware: qcom: scm: add trace events " Yuvaraj Ranganathan
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Yuvaraj Ranganathan @ 2026-05-22  6:38 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio
  Cc: kernel, linux-kernel, linux-arm-msm, Yuvaraj Ranganathan, Konrad Dybcio

The Qualcomm SCM driver is the sole gateway between the kernel and
TrustZone firmware. When firmware issues manifest — unexpected error
codes, calls that never return, or WAITQ sleep/resume cycles that stall
— there is currently no low-overhead way to observe what the driver is
doing without inserting temporary printk statements and rebuilding the
kernel.

This series adds tracepoint coverage for the full SMC call lifecycle.
Once enabled, ftrace or perf can reconstruct the complete sequence of
firmware interactions, correlate service and command identifiers with
firmware return codes, measure per-call latency, and pinpoint the exact
call site responsible for a waitqueue stall — all without modifying
driver source or rebooting.

To capture a trace on a running system:

  echo 1 > /sys/kernel/debug/tracing/events/qcom_scm/enable
  cat /sys/kernel/debug/tracing/trace

Example output:

  kworker/0:1-42  [000] ....  120.614235: scm_smc_request: smc_id:0x42000601 svc_id:0x06 cmd_id:0x01 args_cnt:1 args:{0x2000c1c}
  kworker/0:1-42  [000] ....  120.614289: scm_smc_done: smc_id:0x42000601 ret:0 res_to_callee:0 res0:1 res1:0 res2:0
  kworker/2:1-87  [002] ....  120.821011: scm_smc_request: smc_id:0x42000603 svc_id:0x01 cmd_id:0x05 args_cnt:1 args:{0xa}
  kworker/2:1-87  [002] ....  120.821379: scm_waitq_sleep: wq_ctx:0, smc_call_ctx:1
  kworker/2:1-87  [002] ....  120.823104: scm_waitq_resume: smc_call_ctx:1
  kworker/2:1-87  [002] ....  120.823551: scm_smc_done: smc_id:0x42000603 ret:0 res_to_callee:0 res0:0 res1:0 res2:0

Tested on sa8797 with CONFIG_QCOM_SCM=y and CONFIG_FTRACE=y.
Compilation verified on arm32 and arm64.

Signed-off-by: Yuvaraj Ranganathan <yuvaraj.ranganathan@oss.qualcomm.com>
---
Changes in v2:
- Remove tabs before assignments as suggested in review.
- Link to v1: https://patch.msgid.link/20260506-scm-tracepoints-v1-0-4bc983264014@oss.qualcomm.com

---
Yuvaraj Ranganathan (2):
      firmware: qcom: scm: add trace events for the SMC call interface
      firmware: qcom: scm: instrument SMC call path with tracepoints

 drivers/firmware/qcom/Makefile         |   1 +
 drivers/firmware/qcom/qcom_scm-smc.c   |  10 +++
 drivers/firmware/qcom/qcom_scm_trace.h | 143 +++++++++++++++++++++++++++++++++
 3 files changed, 154 insertions(+)
---
base-commit: 90c7629ccf1277799b025501e5491429ebf7b6cf
change-id: 20260506-scm-tracepoints-cb645232acbe

Best regards,
--  
Yuvaraj Ranganathan <yuvaraj.ranganathan@oss.qualcomm.com>


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

* [PATCH v2 1/2] firmware: qcom: scm: add trace events for the SMC call interface
  2026-05-22  6:38 [PATCH v2 0/2] firmware: qcom: scm: add tracepoints for the SMC call interface Yuvaraj Ranganathan
@ 2026-05-22  6:38 ` Yuvaraj Ranganathan
  2026-05-22  6:39 ` [PATCH v2 2/2] firmware: qcom: scm: instrument SMC call path with tracepoints Yuvaraj Ranganathan
  2026-07-11 16:40 ` [PATCH v2 0/2] firmware: qcom: scm: add tracepoints for the SMC call interface Bjorn Andersson
  2 siblings, 0 replies; 4+ messages in thread
From: Yuvaraj Ranganathan @ 2026-05-22  6:38 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio
  Cc: kernel, linux-kernel, linux-arm-msm, Yuvaraj Ranganathan, Konrad Dybcio

The SCM SMC call path is opaque at runtime. Stalls caused by firmware
congestion, QCOM_SCM_WAITQ_SLEEP/RESUME cycles, and EBUSY retry loops
are invisible without recompiling the kernel with temporary printk
statements or attaching a hardware debugger.

Add five TRACE_EVENTs covering the complete lifecycle of an SCM call:

  scm_smc_request
    Emit before each arm_smccc_smc_quirk() invocation. Records the
    SMC function ID, decoded service and command identifiers, argument
    count, and up to six register arguments in hex and decimal. Because
    the caller loops on QCOM_SCM_INTERRUPTED, this event fires once per
    physical SMC instruction including inte

  scm_smc_done
    Emit after the outer __scm_smc_do() returns, pairing each
    request with its final outcome. Records the SMC function ID, the
    kernel error code returned to the caller, and the four firmware
    result registers a0-a3.

  scm_waitq_sleep
    Emit when the firmware returns QCOM_SCM_WAITQ_SLEEP. Records
    the wait-queue context and the SMC call context handles required
    to issue the matching WAITQ_RESUME.

  scm_waitq_resume
    Emit just before constructing and sending the WAITQ_RESUME
    follow-up call. Records the SMC call context handle being resumed.

  scm_waitq_get_wq_ctx
    Emit after a successful WAITQ_GET_WQ_CTX fast-call. Records
    the returned wait-queue context, flags, and more_pending indicator.

These events let ftrace and perf reconstruct the full sequence of
firmware interactions, measure per-call and end-to-end latency, and
attribute waitqueue stalls to specific service/command pairs without
modifying driver source.

Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Yuvaraj Ranganathan <yuvaraj.ranganathan@oss.qualcomm.com>
---
 drivers/firmware/qcom/qcom_scm_trace.h | 143 +++++++++++++++++++++++++++++++++
 1 file changed, 143 insertions(+)

diff --git a/drivers/firmware/qcom/qcom_scm_trace.h b/drivers/firmware/qcom/qcom_scm_trace.h
new file mode 100644
index 000000000000..6c911124fc56
--- /dev/null
+++ b/drivers/firmware/qcom/qcom_scm_trace.h
@@ -0,0 +1,143 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM qcom_scm
+
+#if !defined(_TRACE_SCM_SMC_INTERFACE_H) || defined(TRACE_HEADER_MULTI_READ)
+
+#define _TRACE_SCM_SMC_INTERFACE_H
+
+#include <linux/tracepoint.h>
+
+TRACE_EVENT(scm_smc_request,
+
+	TP_PROTO(unsigned long a0, const struct arm_smccc_args *smc),
+
+	TP_ARGS(a0, smc),
+
+	TP_STRUCT__entry(
+		__field(u64, smc_id)
+		__field(u8, svc_id)
+		__field(u8, cmd_id)
+		__field(u8, args_cnt)
+		__dynamic_array(unsigned long, args,
+				min_t(u8, (smc->args[1] & 0xF), (u8)6))
+	),
+
+	TP_fast_assign(
+		__entry->smc_id = a0;
+		__entry->svc_id = (smc->args[0] >> 8) & 0xFF;
+		__entry->cmd_id = smc->args[0] & 0xFF;
+		u8 n = min_t(u8, (smc->args[1] & 0xF), (u8)6);
+
+		__entry->args_cnt = n;
+
+		unsigned long *dst = __get_dynamic_array(args);
+
+		for (int i = 0; i < n; i++)
+			dst[i] = smc->args[2 + i];
+	),
+
+	TP_printk("smc_id:0x%08llx svc_id:0x%02x cmd_id:0x%02x args_cnt:%u args:%s",
+		  __entry->smc_id, __entry->svc_id, __entry->cmd_id, __entry->args_cnt,
+		  __print_dynamic_array(args, sizeof(unsigned long)))
+);
+
+TRACE_EVENT(scm_waitq_sleep,
+
+	TP_PROTO(u32 wq_ctx, u32 smc_ctx),
+
+	TP_ARGS(wq_ctx, smc_ctx),
+
+	TP_STRUCT__entry(
+		__field(u32, wq_ctx)
+		__field(u32, smc_call_ctx)
+	),
+
+	TP_fast_assign(
+		__entry->wq_ctx = wq_ctx;
+		__entry->smc_call_ctx = smc_ctx;
+	),
+
+	TP_printk("wq_ctx:%u, smc_call_ctx:%u", __entry->wq_ctx, __entry->smc_call_ctx)
+);
+
+TRACE_EVENT(scm_waitq_resume,
+
+	TP_PROTO(u32 smc_ctx),
+
+	TP_ARGS(smc_ctx),
+
+	TP_STRUCT__entry(
+		__field(u32, smc_call_ctx)
+	),
+
+	TP_fast_assign(
+		__entry->smc_call_ctx = smc_ctx;
+	),
+
+	TP_printk("smc_call_ctx:%u", __entry->smc_call_ctx)
+);
+
+TRACE_EVENT(scm_waitq_get_wq_ctx,
+
+	TP_PROTO(u32 wq_ctx, u32 flags, u32 pending),
+
+	TP_ARGS(wq_ctx, flags, pending),
+
+	TP_STRUCT__entry(
+		__field(u32, wq_ctx)
+		__field(u32, flags)
+		__field(u32, more_pending)
+	),
+
+	TP_fast_assign(
+		__entry->wq_ctx = wq_ctx;
+		__entry->flags = flags;
+		__entry->more_pending = pending;
+	),
+
+	TP_printk("wq_ctx:%u, flags:%u, more_pending:%u",
+		  __entry->wq_ctx, __entry->flags, __entry->more_pending)
+);
+
+TRACE_EVENT(scm_smc_done,
+
+	TP_PROTO(int ret, u64 smc_id, struct arm_smccc_res *smc_res),
+
+	TP_ARGS(ret, smc_id, smc_res),
+
+	TP_STRUCT__entry(
+		__field(int, ret)
+		__field(u64, smc_id)
+		__field(unsigned long, res)
+		__field(unsigned long, res0)
+		__field(unsigned long, res1)
+		__field(unsigned long, res2)
+	),
+
+	TP_fast_assign(
+		__entry->ret = ret;
+		__entry->smc_id = smc_id;
+		__entry->res = smc_res->a0;
+		__entry->res0 = smc_res->a1;
+		__entry->res1 = smc_res->a2;
+		__entry->res2 = smc_res->a3;
+	),
+
+	TP_printk("smc_id:0x%08llx, ret:%d res_to_callee:0x%lx res0:0x%lx res1:0x%lx res2:0x%lx",
+		  __entry->smc_id, __entry->ret, __entry->res,
+		  __entry->res0, __entry->res1, __entry->res2)
+);
+
+#endif /* _TRACE_SCM_SMC_INTERFACE_H */
+
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH .
+#define TRACE_INCLUDE_FILE qcom_scm_trace
+
+#include <trace/define_trace.h>
+

-- 
2.34.1


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

* [PATCH v2 2/2] firmware: qcom: scm: instrument SMC call path with tracepoints
  2026-05-22  6:38 [PATCH v2 0/2] firmware: qcom: scm: add tracepoints for the SMC call interface Yuvaraj Ranganathan
  2026-05-22  6:38 ` [PATCH v2 1/2] firmware: qcom: scm: add trace events " Yuvaraj Ranganathan
@ 2026-05-22  6:39 ` Yuvaraj Ranganathan
  2026-07-11 16:40 ` [PATCH v2 0/2] firmware: qcom: scm: add tracepoints for the SMC call interface Bjorn Andersson
  2 siblings, 0 replies; 4+ messages in thread
From: Yuvaraj Ranganathan @ 2026-05-22  6:39 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio
  Cc: kernel, linux-kernel, linux-arm-msm, Yuvaraj Ranganathan, Konrad Dybcio

Wire the five tracepoints defined in qcom_scm_trace.h into the SMC
execution path by including the header with CREATE_TRACE_POINTS.

Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Yuvaraj Ranganathan <yuvaraj.ranganathan@oss.qualcomm.com>
---
 drivers/firmware/qcom/Makefile       |  1 +
 drivers/firmware/qcom/qcom_scm-smc.c | 10 ++++++++++
 2 files changed, 11 insertions(+)

diff --git a/drivers/firmware/qcom/Makefile b/drivers/firmware/qcom/Makefile
index 0be40a1abc13..b679d3fc2c26 100644
--- a/drivers/firmware/qcom/Makefile
+++ b/drivers/firmware/qcom/Makefile
@@ -5,6 +5,7 @@
 
 obj-$(CONFIG_QCOM_SCM)		+= qcom-scm.o
 qcom-scm-objs += qcom_scm.o qcom_scm-smc.o qcom_scm-legacy.o
+CFLAGS_qcom_scm-smc.o := -I$(src)
 obj-$(CONFIG_QCOM_TZMEM)	+= qcom_tzmem.o
 obj-$(CONFIG_QCOM_QSEECOM)	+= qcom_qseecom.o
 obj-$(CONFIG_QCOM_QSEECOM_UEFISECAPP) += qcom_qseecom_uefisecapp.o
diff --git a/drivers/firmware/qcom/qcom_scm-smc.c b/drivers/firmware/qcom/qcom_scm-smc.c
index 574930729ddd..01999c22659c 100644
--- a/drivers/firmware/qcom/qcom_scm-smc.c
+++ b/drivers/firmware/qcom/qcom_scm-smc.c
@@ -24,6 +24,9 @@ struct arm_smccc_args {
 	unsigned long args[8];
 };
 
+#define CREATE_TRACE_POINTS
+#include "qcom_scm_trace.h"
+
 static DEFINE_MUTEX(qcom_scm_lock);
 
 #define QCOM_SCM_EBUSY_WAIT_MS 30
@@ -44,6 +47,7 @@ static void __scm_smc_do_quirk(const struct arm_smccc_args *smc,
 	quirk.state.a6 = 0;
 
 	do {
+		trace_scm_smc_request(a0, smc);
 		arm_smccc_smc_quirk(a0, smc->args[1], smc->args[2],
 				    smc->args[3], smc->args[4], smc->args[5],
 				    quirk.state.a6, smc->args[7], res, &quirk);
@@ -83,6 +87,7 @@ int scm_get_wq_ctx(u32 *wq_ctx, u32 *flags, u32 *more_pending)
 	if (ret)
 		return ret;
 
+	trace_scm_waitq_get_wq_ctx(get_wq_res.a1, get_wq_res.a2, get_wq_res.a3);
 	*wq_ctx = get_wq_res.a1;
 	*flags  = get_wq_res.a2;
 	*more_pending = get_wq_res.a3;
@@ -105,10 +110,12 @@ static int __scm_smc_do_quirk_handle_waitq(struct device *dev, struct arm_smccc_
 			wq_ctx = res->a1;
 			smc_call_ctx = res->a2;
 
+			trace_scm_waitq_sleep(wq_ctx, smc_call_ctx);
 			ret = qcom_scm_wait_for_wq_completion(wq_ctx);
 			if (ret)
 				return ret;
 
+			trace_scm_waitq_resume(smc_call_ctx);
 			fill_wq_resume_args(&resume, smc_call_ctx);
 			smc = &resume;
 		}
@@ -201,6 +208,9 @@ int __scm_smc_call(struct device *dev, const struct qcom_scm_desc *desc,
 	}
 
 	ret = __scm_smc_do(dev, &smc, &smc_res, atomic);
+
+	trace_scm_smc_done(ret, smc.args[0], &smc_res);
+
 	if (ret)
 		return ret;
 

-- 
2.34.1


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

* Re: [PATCH v2 0/2] firmware: qcom: scm: add tracepoints for the SMC call interface
  2026-05-22  6:38 [PATCH v2 0/2] firmware: qcom: scm: add tracepoints for the SMC call interface Yuvaraj Ranganathan
  2026-05-22  6:38 ` [PATCH v2 1/2] firmware: qcom: scm: add trace events " Yuvaraj Ranganathan
  2026-05-22  6:39 ` [PATCH v2 2/2] firmware: qcom: scm: instrument SMC call path with tracepoints Yuvaraj Ranganathan
@ 2026-07-11 16:40 ` Bjorn Andersson
  2 siblings, 0 replies; 4+ messages in thread
From: Bjorn Andersson @ 2026-07-11 16:40 UTC (permalink / raw)
  To: Konrad Dybcio, Yuvaraj Ranganathan
  Cc: kernel, linux-kernel, linux-arm-msm, Konrad Dybcio


On Fri, 22 May 2026 12:08:58 +0530, Yuvaraj Ranganathan wrote:
> The Qualcomm SCM driver is the sole gateway between the kernel and
> TrustZone firmware. When firmware issues manifest — unexpected error
> codes, calls that never return, or WAITQ sleep/resume cycles that stall
> — there is currently no low-overhead way to observe what the driver is
> doing without inserting temporary printk statements and rebuilding the
> kernel.
> 
> [...]

Applied, thanks!

[1/2] firmware: qcom: scm: add trace events for the SMC call interface
      commit: f6bb2daa4584229af155c2488b83151999315293
[2/2] firmware: qcom: scm: instrument SMC call path with tracepoints
      commit: 41329e72363c02facfeae063ef304aa7ced68c3b

Best regards,
-- 
Bjorn Andersson <andersson@kernel.org>

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

end of thread, other threads:[~2026-07-11 16:40 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-05-22  6:38 [PATCH v2 0/2] firmware: qcom: scm: add tracepoints for the SMC call interface Yuvaraj Ranganathan
2026-05-22  6:38 ` [PATCH v2 1/2] firmware: qcom: scm: add trace events " Yuvaraj Ranganathan
2026-05-22  6:39 ` [PATCH v2 2/2] firmware: qcom: scm: instrument SMC call path with tracepoints Yuvaraj Ranganathan
2026-07-11 16:40 ` [PATCH v2 0/2] firmware: qcom: scm: add tracepoints for the SMC call interface Bjorn Andersson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®