diff options
author | Ji Soo Shin <jisshin@google.com> | 2023-03-14 13:02:46 +0100 |
---|---|---|
committer | Ji Soo Shin <jisshin@google.com> | 2023-03-15 22:07:30 +0000 |
commit | 5a3911b600dc5de99f19e56ebedb9b8a4efb3c3e (patch) | |
tree | 44c43848642e067f5496e6eeb2a7ebc3e5f4d9ec | |
parent | 51113a0fb53cb8c3d2137c8ff09dec253f507fd5 (diff) | |
download | trusty-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/Kbuild | 5 | ||||
-rw-r--r-- | drivers/trusty/trusty-ipc-trace.h | 244 | ||||
-rw-r--r-- | drivers/trusty/trusty-ipc.c | 45 | ||||
-rw-r--r-- | drivers/trusty/trusty-irq-trace.h | 32 | ||||
-rw-r--r-- | drivers/trusty/trusty-irq.c | 6 | ||||
-rw-r--r-- | drivers/trusty/trusty-trace.h | 205 | ||||
-rw-r--r-- | drivers/trusty/trusty.c | 32 | ||||
-rw-r--r-- | include/linux/trusty/trusty_ipc.h | 1 |
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; |