summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJi Soo Shin <jisshin@google.com>2023-03-14 13:02:46 +0100
committerJi Soo Shin <jisshin@google.com>2023-03-15 22:07:30 +0000
commit5a3911b600dc5de99f19e56ebedb9b8a4efb3c3e (patch)
tree44c43848642e067f5496e6eeb2a7ebc3e5f4d9ec
parent51113a0fb53cb8c3d2137c8ff09dec253f507fd5 (diff)
downloadtrusty-5a3911b600dc5de99f19e56ebedb9b8a4efb3c3e.tar.gz
ANDROID: trusty: Add trace points
Bug: 179312495 Change-Id: I93c51b8e675c4b6faa231e51c681f82dd2c9a38f Signed-off-by: Ji Soo Shin <jisshin@google.com>
-rw-r--r--drivers/trusty/Kbuild5
-rw-r--r--drivers/trusty/trusty-ipc-trace.h244
-rw-r--r--drivers/trusty/trusty-ipc.c45
-rw-r--r--drivers/trusty/trusty-irq-trace.h32
-rw-r--r--drivers/trusty/trusty-irq.c6
-rw-r--r--drivers/trusty/trusty-trace.h205
-rw-r--r--drivers/trusty/trusty.c32
-rw-r--r--include/linux/trusty/trusty_ipc.h1
8 files changed, 559 insertions, 11 deletions
diff --git a/drivers/trusty/Kbuild b/drivers/trusty/Kbuild
index 2cf1cfc..76f6932 100644
--- a/drivers/trusty/Kbuild
+++ b/drivers/trusty/Kbuild
@@ -3,6 +3,11 @@
# Makefile for trusty components
#
+# Needed for the trace points
+CFLAGS_trusty.o = -I$(srctree)/$(src)
+CFLAGS_trusty-irq.o = -I$(srctree)/$(src)
+CFLAGS_trusty-ipc.o = -I$(srctree)/$(src)
+
obj-$(CONFIG_TRUSTY) += trusty-core.o
trusty-core-objs += trusty.o trusty-mem.o
trusty-core-$(CONFIG_ARM) += trusty-smc-arm.o
diff --git a/drivers/trusty/trusty-ipc-trace.h b/drivers/trusty/trusty-ipc-trace.h
new file mode 100644
index 0000000..9f193e2
--- /dev/null
+++ b/drivers/trusty/trusty-ipc-trace.h
@@ -0,0 +1,244 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2022 Google, Inc.
+ */
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM trusty
+
+#if !defined(_TRUSTY_IPC_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRUSTY_IPC_TRACE_H
+
+#include <linux/tracepoint.h>
+#include <uapi/linux/trusty/ipc.h>
+#include <linux/trusty/trusty_ipc.h>
+
+/* One of the requirements of checkpatch.pl script is to have "parentheses
+ * to sheild macro arguments from the effects of operator precedence."
+ * Otherwise checkpatch.pl script shall throw below checkpatch error
+ *
+ * "ERROR: Macros with complex values should be enclosed in parentheses"
+ *
+ * Hence extra parenthese are used to avoid the above checkpatch error.
+ * And the extra paentheses are removed using DELETE_PAREN to avoid
+ * compilation errors.
+ */
+#define _DELETE_PAREN(args...) args
+#define DELETE_PAREN(arg) _DELETE_PAREN(_DELETE_PAREN arg)
+
+#define TIPC_CHANNEL_STATE_LIST ( \
+ tipc_state(DISCONNECTED) \
+ tipc_state(CONNECTING) \
+ tipc_state(CONNECTED) \
+ tipc_state_end(STALE) \
+ )
+
+#undef tipc_state
+#undef tipc_state_end
+
+#define tipc_state_define_enum(x) (TRACE_DEFINE_ENUM(TIPC_##x);)
+#define tipc_state(x) DELETE_PAREN(tipc_state_define_enum(x))
+#define tipc_state_end(x) DELETE_PAREN(tipc_state_define_enum(x))
+
+DELETE_PAREN(TIPC_CHANNEL_STATE_LIST)
+
+#undef tipc_state
+#undef tipc_state_end
+
+#define tipc_state(x) { TIPC_##x, #x },
+#define tipc_state_end(x) { TIPC_##x, #x }
+
+#define tipc_channel_state_name(x) \
+ __print_symbolic(x, DELETE_PAREN(TIPC_CHANNEL_STATE_LIST))
+
+TRACE_EVENT(trusty_ipc_connect,
+ TP_PROTO(struct tipc_chan *chan, const char *port),
+ TP_ARGS(chan, port),
+ TP_STRUCT__entry(
+ __field(u32, chan)
+ __string(port, port)
+ __field(int, state)
+ ),
+ TP_fast_assign(
+ __entry->chan = chan ? chan->local : ~0U;
+ __assign_str(port, port);
+ __entry->state = chan ? chan->state : 0;
+ ),
+ TP_printk("chan=%u port=%s state=%s", __entry->chan, __get_str(port),
+ tipc_channel_state_name(__entry->state))
+);
+
+TRACE_EVENT(trusty_ipc_connect_end,
+ TP_PROTO(struct tipc_chan *chan, int err),
+ TP_ARGS(chan, err),
+ TP_STRUCT__entry(
+ __field(u32, chan)
+ __field(int, err)
+ __field(int, state)
+ ),
+ TP_fast_assign(
+ __entry->chan = chan ? chan->local : ~0U;
+ __entry->err = err;
+ __entry->state = chan ? chan->state : 0;
+ ),
+ TP_printk("chan=%u err=%d state=%s", __entry->chan, __entry->err,
+ tipc_channel_state_name(__entry->state))
+);
+
+#define TIPC_CHANNEL_EVENT_LIST ( \
+ tipc_event(CONNECTED) \
+ tipc_event(DISCONNECTED) \
+ tipc_event_end(SHUTDOWN) \
+ )
+
+#undef tipc_event
+#undef tipc_event_end
+
+#define tipc_event_define_enum(x) (TRACE_DEFINE_ENUM(TIPC_CHANNEL_##x);)
+#define tipc_event(x) DELETE_PAREN(tipc_event_define_enum(x))
+#define tipc_event_end(x) DELETE_PAREN(tipc_event_define_enum(x))
+
+DELETE_PAREN(TIPC_CHANNEL_EVENT_LIST)
+
+#undef tipc_event
+#undef tipc_event_end
+
+#define tipc_event(x) { TIPC_CHANNEL_##x, #x },
+#define tipc_event_end(x) { TIPC_CHANNEL_##x, #x }
+
+#define tipc_channel_event_name(x) \
+ __print_symbolic(x, DELETE_PAREN(TIPC_CHANNEL_EVENT_LIST))
+
+TRACE_EVENT(trusty_ipc_handle_event,
+ TP_PROTO(struct tipc_chan *chan, u32 event_id),
+ TP_ARGS(chan, event_id),
+ TP_STRUCT__entry(
+ __field(u32, chan)
+ __array(char, srv_name, MAX_SRV_NAME_LEN)
+ __field(u32, event_id)
+ ),
+ TP_fast_assign(
+ __entry->chan = chan ? chan->local : ~0U;
+ memcpy(__entry->srv_name, chan ? chan->srv_name : "", MAX_SRV_NAME_LEN);
+ __entry->event_id = event_id;
+ ),
+ TP_printk("chan=%u srv_name=%s event=%s", __entry->chan, __entry->srv_name,
+ tipc_channel_event_name(__entry->event_id))
+);
+
+TRACE_EVENT(trusty_ipc_write,
+ TP_PROTO(struct tipc_chan *chan,
+ int len_or_err,
+ struct tipc_msg_buf *txbuf,
+ struct trusty_shm *shm),
+ TP_ARGS(chan, len_or_err, txbuf, shm),
+ TP_STRUCT__entry(
+ __field(int, len_or_err)
+ __field(u32, chan)
+ __array(char, srv_name, MAX_SRV_NAME_LEN)
+ __field(u64, buf_id)
+ __field(size_t, shm_cnt)
+ __dynamic_array(int, kind_shm, txbuf ? txbuf->shm_cnt : 0)
+ ),
+ TP_fast_assign(
+ size_t x;
+
+ __entry->len_or_err = len_or_err;
+ __entry->chan = chan ? chan->local : ~0U;
+ memcpy(__entry->srv_name, chan ? chan->srv_name : "", MAX_SRV_NAME_LEN);
+ __entry->buf_id = txbuf ? txbuf->buf_id : ~0ULL;
+ __entry->shm_cnt = txbuf ? txbuf->shm_cnt : 0;
+ if (shm) {
+ for (x = 0; x < __entry->shm_cnt; x++)
+ *((int *)__get_dynamic_array(kind_shm) + x) = shm[x].transfer;
+ }
+ ),
+ TP_printk("len_or_err=%d chan=%u srv_name=%s buf_id=0x%llx shm_cnt=%zu kind_shm=%s",
+ __entry->len_or_err, __entry->chan, __entry->srv_name, __entry->buf_id,
+ __entry->shm_cnt, __print_array(__get_dynamic_array(kind_shm),
+ __get_dynamic_array_len(kind_shm) / sizeof(int), sizeof(int)))
+);
+
+TRACE_EVENT(trusty_ipc_read,
+ TP_PROTO(struct tipc_chan *chan),
+ TP_ARGS(chan),
+ TP_STRUCT__entry(
+ __field(u32, chan)
+ __array(char, srv_name, MAX_SRV_NAME_LEN)
+ ),
+ TP_fast_assign(
+ __entry->chan = chan ? chan->local : ~0U;
+ memcpy(__entry->srv_name, chan ? chan->srv_name : "", MAX_SRV_NAME_LEN);
+ ),
+ TP_printk("chan=%u srv_name=%s", __entry->chan, __entry->srv_name)
+);
+
+TRACE_EVENT(trusty_ipc_read_end,
+ TP_PROTO(struct tipc_chan *chan,
+ int len_or_err,
+ struct tipc_msg_buf *rxbuf),
+ TP_ARGS(chan, len_or_err, rxbuf),
+ TP_STRUCT__entry(
+ __field(int, len_or_err)
+ __field(u32, chan)
+ __array(char, srv_name, MAX_SRV_NAME_LEN)
+ __field(u64, buf_id)
+ __field(size_t, shm_cnt)
+ ),
+ TP_fast_assign(
+ __entry->len_or_err = len_or_err;
+ __entry->chan = chan ? chan->local : ~0U;
+ memcpy(__entry->srv_name, chan ? chan->srv_name : "", MAX_SRV_NAME_LEN);
+ __entry->buf_id = rxbuf ? rxbuf->buf_id : ~0ULL;
+ __entry->shm_cnt = rxbuf ? rxbuf->shm_cnt : 0;
+ ),
+ TP_printk("len_or_err=%d chan=%u srv_name=%s buf_id=0x%llx shm_cnt=%zu",
+ __entry->len_or_err, __entry->chan, __entry->srv_name,
+ __entry->buf_id, __entry->shm_cnt)
+);
+
+TRACE_EVENT(trusty_ipc_poll,
+ TP_PROTO(struct tipc_chan *chan,
+ unsigned int poll_mask),
+ TP_ARGS(chan, poll_mask),
+ TP_STRUCT__entry(
+ __field(unsigned int, poll_mask)
+ __field(u32, chan)
+ __array(char, srv_name, MAX_SRV_NAME_LEN)
+ ),
+ TP_fast_assign(
+ __entry->poll_mask = poll_mask;
+ __entry->chan = chan ? chan->local : ~0U;
+ memcpy(__entry->srv_name, chan ? chan->srv_name : "", MAX_SRV_NAME_LEN);
+ ),
+ TP_printk("poll_mask=%u chan=%u srv_name=%s",
+ __entry->poll_mask, __entry->chan, __entry->srv_name)
+);
+
+/*
+ * tracepoint when a message buffer is received from trusty
+ * and is awaiting for its HAL consumer to read it
+ */
+TRACE_EVENT(trusty_ipc_rx,
+ TP_PROTO(struct tipc_chan *chan, struct tipc_msg_buf *rxbuf),
+ TP_ARGS(chan, rxbuf),
+ TP_STRUCT__entry(
+ __field(u32, chan)
+ __array(char, srv_name, MAX_SRV_NAME_LEN)
+ __field(u64, buf_id)
+ ),
+ TP_fast_assign(
+ __entry->chan = chan ? chan->local : ~0U;
+ memcpy(__entry->srv_name, chan ? chan->srv_name : "", MAX_SRV_NAME_LEN);
+ __entry->buf_id = rxbuf ? rxbuf->buf_id : ~0ULL;
+ ),
+ TP_printk("chan=%u srv_name=%s buf_id=0x%llx", __entry->chan,
+ __entry->srv_name, __entry->buf_id)
+);
+#endif /* _TRUSTY_IPC_TRACE_H */
+
+#undef TRACE_INCLUDE_PATH
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_PATH .
+#define TRACE_INCLUDE_FILE trusty-ipc-trace
+#include <trace/define_trace.h>
diff --git a/drivers/trusty/trusty-ipc.c b/drivers/trusty/trusty-ipc.c
index a30e02a..af0deda 100644
--- a/drivers/trusty/trusty-ipc.c
+++ b/drivers/trusty/trusty-ipc.c
@@ -28,6 +28,8 @@
#include <uapi/linux/trusty/ipc.h>
+#include "trusty-ipc-trace.h"
+
#define MAX_DEVICES 4
#define REPLY_TIMEOUT 5000
@@ -795,6 +797,8 @@ int tipc_chan_connect(struct tipc_chan *chan, const char *name)
struct tipc_conn_req_body *body;
struct tipc_msg_buf *txbuf;
+ trace_trusty_ipc_connect(chan, name);
+
txbuf = vds_get_txbuf(chan->vds, TXBUF_TIMEOUT);
if (IS_ERR(txbuf))
return PTR_ERR(txbuf);
@@ -961,6 +965,8 @@ static struct tipc_msg_buf *dn_handle_msg(void *data,
mutex_lock(&dn->lock);
if (dn->state == TIPC_CONNECTED) {
+ /* buffer received from trusty */
+ trace_trusty_ipc_rx(dn->chan, rxbuf);
/* get new buffer */
newbuf = tipc_chan_get_rxbuf(dn->chan);
if (newbuf) {
@@ -1026,6 +1032,7 @@ static void dn_shutdown(struct tipc_dn_chan *dn)
static void dn_handle_event(void *data, int event)
{
struct tipc_dn_chan *dn = data;
+ trace_trusty_ipc_handle_event(dn->chan, event);
switch (event) {
case TIPC_CHANNEL_SHUTDOWN:
@@ -1136,10 +1143,14 @@ static int dn_connect_ioctl(struct tipc_dn_chan *dn, char __user *usr_name)
/* send connect request */
ret = tipc_chan_connect(dn->chan, name);
if (ret)
- return ret;
+ goto err_handle;
/* and wait for reply */
- return dn_wait_for_reply(dn, REPLY_TIMEOUT);
+ ret = dn_wait_for_reply(dn, REPLY_TIMEOUT);
+
+err_handle:
+ trace_trusty_ipc_connect_end(dn->chan, ret);
+ return ret;
}
static int dn_share_fd(struct tipc_dn_chan *dn, int fd,
@@ -1407,6 +1418,8 @@ static long filp_send_ioctl(struct file *filp,
for (shm_idx = 0; shm_idx < req.shm_cnt; shm_idx++)
tipc_shared_handle_register(shm_handles[shm_idx]);
+ trace_trusty_ipc_write(dn->chan, ret, NULL, NULL);
+
ret = tipc_chan_queue_msg(dn->chan, txbuf);
if (ret)
@@ -1421,6 +1434,9 @@ load_shm_args_failed:
kfree(shm_handles);
shm_handles_alloc_failed:
kfree(shm);
+
+ if (ret)
+ trace_trusty_ipc_write(dn->chan, ret, txbuf, shm);
return ret;
queue_failed:
@@ -1433,6 +1449,7 @@ get_txbuf_failed:
shm_share_failed:
for (shm_idx--; shm_idx >= 0; shm_idx--)
tipc_shared_handle_drop(shm_handles[shm_idx]);
+
goto common_cleanup;
}
@@ -1488,12 +1505,14 @@ static ssize_t tipc_read_iter(struct kiocb *iocb, struct iov_iter *iter)
{
ssize_t ret;
size_t len;
- struct tipc_msg_buf *mb;
+ struct tipc_msg_buf *mb = NULL;
struct file *filp = iocb->ki_filp;
struct tipc_dn_chan *dn = filp->private_data;
mutex_lock(&dn->lock);
+ trace_trusty_ipc_read(dn->chan);
+
while (list_empty(&dn->rx_msg_queue)) {
if (dn->state != TIPC_CONNECTED) {
if (dn->state == TIPC_CONNECTING)
@@ -1536,6 +1555,7 @@ static ssize_t tipc_read_iter(struct kiocb *iocb, struct iov_iter *iter)
tipc_chan_put_rxbuf(dn->chan, mb);
out:
+ trace_trusty_ipc_read_end(dn->chan, ret, mb);
mutex_unlock(&dn->lock);
return ret;
}
@@ -1554,22 +1574,30 @@ static ssize_t tipc_write_iter(struct kiocb *iocb, struct iov_iter *iter)
txbuf = tipc_chan_get_txbuf_timeout(dn->chan, timeout);
- if (IS_ERR(txbuf))
- return PTR_ERR(txbuf);
+ if (IS_ERR(txbuf)) {
+ ret = PTR_ERR(txbuf);
+ goto exit_out;
+ }
len = txbuf_write_iter(txbuf, iter);
- if (len < 0)
+ if (len < 0) {
+ ret = len;
goto err_out;
+ }
/* queue message */
ret = tipc_chan_queue_msg(dn->chan, txbuf);
if (ret)
goto err_out;
+ trace_trusty_ipc_write(dn->chan, len, txbuf, NULL);
+
return len;
err_out:
tipc_chan_put_txbuf(dn->chan, txbuf);
+exit_out:
+ trace_trusty_ipc_write(dn->chan, ret, NULL, NULL);
return ret;
}
@@ -1592,6 +1620,8 @@ static __poll_t tipc_poll(struct file *filp, poll_table *wait)
mask |= EPOLLERR;
mutex_unlock(&dn->lock);
+
+ trace_trusty_ipc_poll(dn->chan, mask);
return mask;
}
@@ -2256,6 +2286,9 @@ static void __exit tipc_exit(void)
subsys_initcall(tipc_init);
module_exit(tipc_exit);
+#define CREATE_TRACE_POINTS
+#include "trusty-ipc-trace.h"
+
MODULE_DEVICE_TABLE(tipc, tipc_virtio_id_table);
MODULE_DESCRIPTION("Trusty IPC driver");
MODULE_IMPORT_NS(DMA_BUF);
diff --git a/drivers/trusty/trusty-irq-trace.h b/drivers/trusty/trusty-irq-trace.h
new file mode 100644
index 0000000..3df61b8
--- /dev/null
+++ b/drivers/trusty/trusty-irq-trace.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2022 Google, Inc.
+ */
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM trusty
+
+#if !defined(_TRUSTY_IRQ_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRUSTY_IRQ_TRACE_H
+
+#include <linux/tracepoint.h>
+
+TRACE_EVENT(trusty_irq,
+ TP_PROTO(int irq),
+ TP_ARGS(irq),
+ TP_STRUCT__entry(
+ __field(int, irq)
+ ),
+ TP_fast_assign(
+ __entry->irq = irq;
+ ),
+ TP_printk("irq=%d", __entry->irq)
+);
+
+#endif /* _TRUSTY_IRQ_TRACE_H */
+
+#undef TRACE_INCLUDE_PATH
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_PATH .
+#define TRACE_INCLUDE_FILE trusty-irq-trace
+#include <trace/define_trace.h>
diff --git a/drivers/trusty/trusty-irq.c b/drivers/trusty/trusty-irq.c
index 5c60761..0cbbe70 100644
--- a/drivers/trusty/trusty-irq.c
+++ b/drivers/trusty/trusty-irq.c
@@ -17,6 +17,8 @@
#include <linux/trusty/sm_err.h>
#include <linux/trusty/trusty.h>
+#include "trusty-irq-trace.h"
+
struct trusty_irq {
struct trusty_irq_state *is;
struct hlist_node node;
@@ -153,6 +155,7 @@ static irqreturn_t trusty_irq_handler(int irq, void *data)
dev_dbg(is->dev, "%s: irq %d, percpu %d, cpu %d, enable %d\n",
__func__, irq, trusty_irq->irq, smp_processor_id(),
trusty_irq->enable);
+ trace_trusty_irq(irq);
if (!trusty_irq->doorbell) {
if (trusty_irq->percpu) {
@@ -641,5 +644,8 @@ static void __exit trusty_irq_driver_exit(void)
module_init(trusty_irq_driver_init);
module_exit(trusty_irq_driver_exit);
+#define CREATE_TRACE_POINTS
+#include "trusty-irq-trace.h"
+
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Trusty IRQ driver");
diff --git a/drivers/trusty/trusty-trace.h b/drivers/trusty/trusty-trace.h
new file mode 100644
index 0000000..adb3653
--- /dev/null
+++ b/drivers/trusty/trusty-trace.h
@@ -0,0 +1,205 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2022 Google, Inc.
+ */
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM trusty
+
+#if !defined(_TRUSTY_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRUSTY_TRACE_H
+
+#include <linux/tracepoint.h>
+#include <linux/trusty/smcall.h>
+
+/* One of the requirements of checkpatch.pl script is to have "parentheses
+ * to sheild macro arguments from the effects of operator precedence."
+ * Otherwise checkpatch.pl script shall throw below error
+ * "ERROR: Macros with complex values should be enclosed in parentheses"
+ *
+ * Hence extra parenthese are used to avoid the above checkpatch error.
+ * And the extra paentheses are removed using DELETE_PAREN to avoid
+ * compilation errors.
+ */
+#define _DELETE_PAREN(args...) args
+#define DELETE_PAREN(arg) _DELETE_PAREN(_DELETE_PAREN arg)
+
+/*
+ * SMC fast call and std call numbers from linux/trusty/smcall.h
+ */
+#define SMC_NAME_LIST ( \
+ smc_name(SC_RESTART_LAST) \
+ smc_name(SC_LOCKED_NOP) \
+ smc_name(SC_RESTART_FIQ) \
+ smc_name(SC_NOP) \
+ smc_name(FC_RESERVED) \
+ smc_name(FC_FIQ_EXIT) \
+ smc_name(FC_REQUEST_FIQ) \
+ smc_name(FC_GET_NEXT_IRQ) \
+ smc_name(FC_CPU_SUSPEND) \
+ smc_name(FC_CPU_RESUME) \
+ smc_name(FC_AARCH_SWITCH) \
+ smc_name(FC_GET_VERSION_STR) \
+ smc_name(FC_API_VERSION) \
+ smc_name(SC_VIRTIO_GET_DESCR) \
+ smc_name(SC_VIRTIO_START) \
+ smc_name(SC_VIRTIO_STOP) \
+ smc_name(SC_VDEV_RESET) \
+ smc_name(SC_VDEV_KICK_VQ) \
+ smc_name_end(NC_VDEV_KICK_VQ) \
+ )
+
+#undef smc_name
+#undef smc_name_end
+
+#define smc_name_define_enum(x) (TRACE_DEFINE_ENUM(SMC_##x);)
+#define smc_name(x) DELETE_PAREN(smc_name_define_enum(x))
+#define smc_name_end(x) DELETE_PAREN(smc_name_define_enum(x))
+
+DELETE_PAREN(SMC_NAME_LIST)
+
+#undef smc_name
+#undef smc_name_end
+
+#define smc_name(x) { SMC_##x, #x },
+#define smc_name_end(x) { SMC_##x, #x }
+
+#define smc_show_name(x) \
+ __print_symbolic(x, DELETE_PAREN(SMC_NAME_LIST))
+
+DECLARE_EVENT_CLASS(trusty_smc4_class,
+ TP_PROTO(unsigned long r0, unsigned long r1, unsigned long r2,
+ unsigned long r3),
+ TP_ARGS(r0, r1, r2, r3),
+ TP_STRUCT__entry(
+ __field(unsigned long, r0)
+ __field(unsigned long, r1)
+ __field(unsigned long, r2)
+ __field(unsigned long, r3)
+ ),
+ TP_fast_assign(
+ __entry->r0 = r0;
+ __entry->r1 = r1;
+ __entry->r2 = r2;
+ __entry->r3 = r3;
+ ),
+ TP_printk("smcnr=%s r0=0x%lx r1=0x%lx r2=0x%lx r3=0x%lx", smc_show_name(__entry->r0),
+ __entry->r0, __entry->r1, __entry->r2, __entry->r3)
+);
+
+#define DEFINE_TRUSTY_SMC4_EVENT(name) \
+DEFINE_EVENT(trusty_smc4_class, name, \
+ TP_PROTO(unsigned long r0, unsigned long r1, unsigned long r2, \
+ unsigned long r3), \
+ TP_ARGS(r0, r1, r2, r3))
+
+DEFINE_TRUSTY_SMC4_EVENT(trusty_std_call32);
+DEFINE_TRUSTY_SMC4_EVENT(trusty_smc);
+
+DECLARE_EVENT_CLASS(trusty_smc_return_class,
+ TP_PROTO(unsigned long ret),
+ TP_ARGS(ret),
+ TP_STRUCT__entry(
+ __field(unsigned long, ret)
+ ),
+ TP_fast_assign(
+ __entry->ret = ret;
+ ),
+ TP_printk("ret:ulong=%lu (0x%lx) (ret:s32=%d)", __entry->ret,
+ __entry->ret, (s32)__entry->ret)
+);
+
+#define DEFINE_TRUSTY_SMC_RETURN_EVENT(name) \
+DEFINE_EVENT(trusty_smc_return_class, name, \
+ TP_PROTO(unsigned long ret), \
+ TP_ARGS(ret))
+
+DEFINE_TRUSTY_SMC_RETURN_EVENT(trusty_std_call32_done);
+DEFINE_TRUSTY_SMC_RETURN_EVENT(trusty_smc_done);
+
+TRACE_EVENT(trusty_share_memory,
+ TP_PROTO(size_t len, unsigned int nents, bool lend),
+ TP_ARGS(len, nents, lend),
+ TP_STRUCT__entry(
+ __field(size_t, len)
+ __field(unsigned int, nents)
+ __field(bool, lend)
+ ),
+ TP_fast_assign(
+ __entry->len = len;
+ __entry->nents = nents;
+ __entry->lend = lend;
+ ),
+ TP_printk("len=%zu, nents=%u, lend=%u", __entry->len, __entry->nents, __entry->lend)
+);
+
+TRACE_EVENT(trusty_share_memory_done,
+ TP_PROTO(size_t len, unsigned int nents, bool lend, u64 handle, int ret),
+ TP_ARGS(len, nents, lend, handle, ret),
+ TP_STRUCT__entry(
+ __field(size_t, len)
+ __field(unsigned int, nents)
+ __field(bool, lend)
+ __field(u64, handle)
+ __field(int, ret)
+ ),
+ TP_fast_assign(
+ __entry->len = len;
+ __entry->nents = nents;
+ __entry->lend = lend;
+ __entry->handle = handle;
+ __entry->ret = ret;
+ ),
+ TP_printk("len=%zu, nents=%u, lend=%u, ffa_handle=0x%llx, ret=%d", __entry->len,
+ __entry->nents, __entry->lend, __entry->handle, __entry->ret)
+);
+
+TRACE_EVENT(trusty_enqueue_nop,
+ TP_PROTO(struct trusty_nop *nop),
+ TP_ARGS(nop),
+ TP_STRUCT__entry(
+ __field(u32, arg1)
+ __field(u32, arg2)
+ __field(u32, arg3)
+ ),
+ TP_fast_assign(
+ __entry->arg1 = nop ? nop->args[0] : 0U;
+ __entry->arg2 = nop ? nop->args[1] : 0U;
+ __entry->arg3 = nop ? nop->args[2] : 0U;
+ ),
+ TP_printk("arg1=0x%x, arg2=0x%x, arg3=0x%x", __entry->arg1, __entry->arg2, __entry->arg3)
+);
+
+TRACE_EVENT(trusty_reclaim_memory,
+ TP_PROTO(u64 id),
+ TP_ARGS(id),
+ TP_STRUCT__entry(
+ __field(u64, id)
+ ),
+ TP_fast_assign(
+ __entry->id = id;
+ ),
+ TP_printk("id=%llu", __entry->id)
+);
+
+TRACE_EVENT(trusty_reclaim_memory_done,
+ TP_PROTO(u64 id, int ret),
+ TP_ARGS(id, ret),
+ TP_STRUCT__entry(
+ __field(u64, id)
+ __field(int, ret)
+ ),
+ TP_fast_assign(
+ __entry->id = id;
+ __entry->ret = ret;
+ ),
+ TP_printk("id=%llu ret=%d (0x%x)", __entry->id, __entry->ret, __entry->ret)
+);
+
+#endif /* _TRUSTY_TRACE_H */
+
+#undef TRACE_INCLUDE_PATH
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_PATH .
+#define TRACE_INCLUDE_FILE trusty-trace
+#include <trace/define_trace.h>
diff --git a/drivers/trusty/trusty.c b/drivers/trusty/trusty.c
index d1d7054..ac08d51 100644
--- a/drivers/trusty/trusty.c
+++ b/drivers/trusty/trusty.c
@@ -20,6 +20,7 @@
#include <linux/dma-mapping.h>
#include "trusty-smc.h"
+#include "trusty-trace.h"
struct trusty_state;
static struct platform_driver trusty_driver;
@@ -55,7 +56,12 @@ struct trusty_state {
static inline unsigned long smc(unsigned long r0, unsigned long r1,
unsigned long r2, unsigned long r3)
{
- return trusty_smc8(r0, r1, r2, r3, 0, 0, 0, 0).r0;
+ unsigned long ret;
+
+ trace_trusty_smc(r0, r1, r2, r3);
+ ret = trusty_smc8(r0, r1, r2, r3, 0, 0, 0, 0).r0;
+ trace_trusty_smc_done(ret);
+ return ret;
}
s32 trusty_fast_call32(struct device *dev, u32 smcnr, u32 a0, u32 a1, u32 a2)
@@ -203,6 +209,8 @@ s32 trusty_std_call32(struct device *dev, u32 smcnr, u32 a0, u32 a1, u32 a2)
return SM_ERR_PANIC;
}
+ trace_trusty_std_call32(smcnr, a0, a1, a2);
+
if (smcnr != SMC_SC_NOP) {
mutex_lock(&s->smc_lock);
reinit_completion(&s->cpu_idle_completion);
@@ -227,6 +235,8 @@ s32 trusty_std_call32(struct device *dev, u32 smcnr, u32 a0, u32 a1, u32 a2)
else
mutex_unlock(&s->smc_lock);
+ trace_trusty_std_call32_done(ret);
+
return ret;
}
EXPORT_SYMBOL(trusty_std_call32);
@@ -250,7 +260,7 @@ int trusty_transfer_memory(struct device *dev, u64 *id,
struct scatterlist *sg;
size_t count;
size_t i;
- size_t len;
+ size_t len = 0;
u64 ffa_handle = 0;
size_t total_len;
size_t endpoint_count = 1;
@@ -299,6 +309,8 @@ int trusty_transfer_memory(struct device *dev, u64 *id,
for_each_sg(sglist, sg, nents, i)
len += sg_dma_len(sg);
+ trace_trusty_share_memory(len, nents, lend);
+
mutex_lock(&s->share_memory_msg_lock);
mtd->sender_id = s->ffa_local_id;
@@ -399,13 +411,15 @@ int trusty_transfer_memory(struct device *dev, u64 *id,
if (!ret) {
*id = ffa_handle;
dev_dbg(s->dev, "%s: done\n", __func__);
- return 0;
+ goto done;
}
dev_err(s->dev, "%s: failed %d", __func__, ret);
err_encode_page_info:
dma_unmap_sg(dev, sglist, nents, DMA_BIDIRECTIONAL);
+done:
+ trace_trusty_share_memory_done(len, nents, lend, ffa_handle, ret);
return ret;
}
EXPORT_SYMBOL(trusty_transfer_memory);
@@ -457,6 +471,7 @@ int trusty_reclaim_memory(struct device *dev, u64 id,
return 0;
}
+ trace_trusty_reclaim_memory(id);
mutex_lock(&s->share_memory_msg_lock);
smc_ret = trusty_smc8(SMC_FC_FFA_MEM_RECLAIM, (u32)id, id >> 32, 0, 0,
@@ -474,12 +489,15 @@ int trusty_reclaim_memory(struct device *dev, u64 id,
mutex_unlock(&s->share_memory_msg_lock);
if (ret != 0)
- return ret;
+ goto err_ffa_mem_reclaim;
dma_unmap_sg(dev, sglist, nents, DMA_BIDIRECTIONAL);
dev_dbg(s->dev, "%s: done\n", __func__);
- return 0;
+
+err_ffa_mem_reclaim:
+ trace_trusty_reclaim_memory_done(id, ret);
+ return ret;
}
EXPORT_SYMBOL(trusty_reclaim_memory);
@@ -813,6 +831,7 @@ void trusty_enqueue_nop(struct device *dev, struct trusty_nop *nop)
struct trusty_work *tw;
struct trusty_state *s = platform_get_drvdata(to_platform_device(dev));
+ trace_trusty_enqueue_nop(nop);
preempt_disable();
tw = this_cpu_ptr(s->nop_works);
if (nop) {
@@ -1001,5 +1020,8 @@ static void __exit trusty_driver_exit(void)
subsys_initcall(trusty_driver_init);
module_exit(trusty_driver_exit);
+#define CREATE_TRACE_POINTS
+#include "trusty-trace.h"
+
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Trusty core driver");
diff --git a/include/linux/trusty/trusty_ipc.h b/include/linux/trusty/trusty_ipc.h
index 9386392..3b17ddb 100644
--- a/include/linux/trusty/trusty_ipc.h
+++ b/include/linux/trusty/trusty_ipc.h
@@ -9,6 +9,7 @@
#include <linux/scatterlist.h>
#include <linux/trusty/trusty.h>
#include <linux/types.h>
+#include <uapi/linux/trusty/ipc.h>
struct tipc_chan;