diff options
author | Tri Vo <trong@google.com> | 2022-01-18 16:15:06 -0800 |
---|---|---|
committer | Will McVicker <willmcvicker@google.com> | 2022-04-22 10:47:57 -0700 |
commit | 7078cceeba4af32c97408c4e1b90d209ba615486 (patch) | |
tree | 94f24eeda7bcaac6b0460f62c22a8e79b53205d2 | |
parent | 187e1b804ddf226b0d587adba2f22ecbfb0a7587 (diff) | |
download | trusty-7078cceeba4af32c97408c4e1b90d209ba615486.tar.gz |
ANDROID: trusty: Support setting trusty_shared_mem_id_t
This patch allows DMA heaps to allocate/release shared memory IDs and
associate them with DMA buffers. If an trusty_shared_mem_id_t is
specified, Trusty driver will not manage life cycle of the transaction
associated with that ID.
DMA buffers with trusty_shared_mem_id_t pre-allocated must be in secure
memory, and newly added TRUSTY_SEND_SECURE should be used to transfer
them to Trusty.
For backwards compatibility, we only issue a warning if either
TRUSTY_SHARE or TRUSTY_LEND is used to transfer a DMA buffer with an
allocated trusty_shared_mem_id_t.
Bug: 206813152
Change-Id: Ic651967fe66bd3f46bf36d34d3fda60a6399a6ac
Signed-off-by: Tri Vo <trong@google.com>
(cherry picked from commit 629a4d3318cc1234675f62b69fba8791592e8a83)
Signed-off-by: Will McVicker <willmcvicker@google.com>
-rw-r--r-- | drivers/trusty/Kconfig | 13 | ||||
-rw-r--r-- | drivers/trusty/trusty-ipc.c | 58 | ||||
-rw-r--r-- | include/linux/trusty/trusty.h | 27 | ||||
-rw-r--r-- | include/uapi/linux/trusty/ipc.h | 23 |
4 files changed, 97 insertions, 24 deletions
diff --git a/drivers/trusty/Kconfig b/drivers/trusty/Kconfig index 2f0e30c..fcde7f0 100644 --- a/drivers/trusty/Kconfig +++ b/drivers/trusty/Kconfig @@ -88,6 +88,19 @@ config TRUSTY_DMA_BUF_FFA_TAG If set to N, a default implementation which returns 0 will be used. +config TRUSTY_DMA_BUF_SHARED_MEM_ID + bool "Availability of trusty_dma_buf_get_shared_mem_id" + default n + help + Whether trusty_dma_buf_get_shared_mem_id is provided on this platform. + Providing this function allows the platform to manage memory + transaction life cycle of DMA bufs independently of Trusty IPC driver. + The latter can query trusty_shared_mem_id_t value allocated for a + given DMA buf using trusty_dma_buf_get_shared_mem_id interface. + + If set to N, a default implementation which does not allocate any IDs + will be used. + config TRUSTY_CRASH_IS_PANIC bool "When trusty panics, then panic the kernel" help diff --git a/drivers/trusty/trusty-ipc.c b/drivers/trusty/trusty-ipc.c index d83e8a0..babb91c 100644 --- a/drivers/trusty/trusty-ipc.c +++ b/drivers/trusty/trusty-ipc.c @@ -165,10 +165,14 @@ struct tipc_shared_handle { struct rb_node node; struct tipc_shm tipc; struct tipc_virtio_dev *vds; - struct sg_table *sgt; - struct dma_buf_attachment *attach; struct dma_buf *dma_buf; bool shared; + /* + * Following fields are only used if dma_buf does not own a + * trusty_shared_mem_id_t. + */ + struct dma_buf_attachment *attach; + struct sg_table *sgt; }; static struct class *tipc_class; @@ -1106,7 +1110,7 @@ static int dn_connect_ioctl(struct tipc_dn_chan *dn, char __user *usr_name) } static int dn_share_fd(struct tipc_dn_chan *dn, int fd, - bool lend, + enum transfer_kind transfer_kind, struct tipc_shared_handle **out) { int ret = 0; @@ -1116,6 +1120,8 @@ static int dn_share_fd(struct tipc_dn_chan *dn, int fd, bool writable = false; pgprot_t prot; u64 tag = 0; + trusty_shared_mem_id_t mem_id; + bool lend; if (dn->state != TIPC_CONNECTED) { dev_dbg(dev, "Tried to share fd while not connected\n"); @@ -1151,6 +1157,32 @@ static int dn_share_fd(struct tipc_dn_chan *dn, int fd, goto cleanup_handle; } + tag = trusty_dma_buf_get_ffa_tag(shared_handle->dma_buf); + ret = trusty_dma_buf_get_shared_mem_id(shared_handle->dma_buf, &mem_id); + /* + * Buffers with a preallocated mem_id should only be sent to Trusty + * using TRUSTY_SEND_SECURE. And conversely, TRUSTY_SEND_SECURE should + * only be used to send buffers with preallcoated mem_id. + */ + if (!ret) { + /* Use shared memory ID owned by dma_buf */ + /* TODO: Enforce transfer_kind == TRUSTY_SEND_SECURE */ + WARN_ONCE(transfer_kind != TRUSTY_SEND_SECURE, + "Use TRUSTY_SEND_SECURE instead"); + goto mem_id_allocated; + } + + if (ret != -ENODATA) { + dev_err(dev, "dma_buf can't be transferred (%d)\n", ret); + goto cleanup_handle; + } + + if (transfer_kind == TRUSTY_SEND_SECURE) { + dev_err(dev, "No mem ID for TRUSTY_SEND_SECURE\n"); + goto cleanup_handle; + } + lend = (transfer_kind == TRUSTY_LEND); + shared_handle->attach = dma_buf_attach(shared_handle->dma_buf, dev); if (IS_ERR(shared_handle->attach)) { ret = PTR_ERR(shared_handle->attach); @@ -1168,13 +1200,10 @@ static int dn_share_fd(struct tipc_dn_chan *dn, int fd, goto cleanup_handle; } - tag = trusty_dma_buf_get_ffa_tag(shared_handle->dma_buf); - ret = trusty_transfer_memory(tipc_shared_handle_dev(shared_handle), - &shared_handle->tipc.obj_id, - shared_handle->sgt->sgl, - shared_handle->sgt->orig_nents, prot, - tag, lend); + &mem_id, shared_handle->sgt->sgl, + shared_handle->sgt->orig_nents, prot, tag, + lend); if (ret < 0) { dev_dbg(dev, "Transferring memory failed: %d\n", ret); @@ -1185,6 +1214,9 @@ static int dn_share_fd(struct tipc_dn_chan *dn, int fd, goto cleanup_handle; } shared_handle->shared = true; + +mem_id_allocated: + shared_handle->tipc.obj_id = mem_id; shared_handle->tipc.size = shared_handle->dma_buf->size; shared_handle->tipc.tag = tag; *out = shared_handle; @@ -1257,7 +1289,6 @@ static long filp_send_ioctl(struct file *filp, long ret = 0; ssize_t data_len = 0; ssize_t shm_len = 0; - bool lend = false; if (copy_from_user(&req, arg, sizeof(req))) return -EFAULT; @@ -1292,18 +1323,15 @@ static long filp_send_ioctl(struct file *filp, for (shm_idx = 0; shm_idx < req.shm_cnt; shm_idx++) { switch (shm[shm_idx].transfer) { case TRUSTY_SHARE: - lend = false; - break; case TRUSTY_LEND: - lend = true; + case TRUSTY_SEND_SECURE: break; default: dev_err(dev, "Unknown transfer type: 0x%x\n", shm[shm_idx].transfer); goto shm_share_failed; } - ret = dn_share_fd(dn, shm[shm_idx].fd, - lend, + ret = dn_share_fd(dn, shm[shm_idx].fd, shm[shm_idx].transfer, &shm_handles[shm_idx]); if (ret) { dev_dbg(dev, "Forwarding memory failed\n" diff --git a/include/linux/trusty/trusty.h b/include/linux/trusty/trusty.h index ec53eb2..efbb369 100644 --- a/include/linux/trusty/trusty.h +++ b/include/linux/trusty/trusty.h @@ -85,6 +85,33 @@ static inline u64 trusty_dma_buf_get_ffa_tag(struct dma_buf *dma_buf) } #endif +/* Invalid handle value is defined by FF-A spec */ +#ifdef CONFIG_TRUSTY_DMA_BUF_SHARED_MEM_ID +/** + * trusty_dma_buf_get_shared_mem_id() - Get memory ID corresponding to a dma_buf + * @dma_buf: DMA buffer + * @id: Pointer to output trusty_shared_mem_id_t + * + * Sets @id to trusty_shared_mem_id_t corresponding to the given @dma_buf. + * @dma_buf "owns" the ID, i.e. is responsible for allocating/releasing it. + * @dma_buf with an allocated @id must be in secure memory and should only be + * sent to Trusty using TRUSTY_SEND_SECURE. + * + * Return: + * * 0 - success + * * -ENODATA - @dma_buf does not own a trusty_shared_mem_id_t + * * ... - @dma_buf should not be lent or shared + */ +int trusty_dma_buf_get_shared_mem_id(struct dma_buf *dma_buf, + trusty_shared_mem_id_t *id); +#else +static inline int trusty_dma_buf_get_shared_mem_id(struct dma_buf *dma_buf, + trusty_shared_mem_id_t *id) +{ + return -ENODATA; +} +#endif + struct trusty_nop { struct list_head node; u32 args[3]; diff --git a/include/uapi/linux/trusty/ipc.h b/include/uapi/linux/trusty/ipc.h index 20cdd90..af91035 100644 --- a/include/uapi/linux/trusty/ipc.h +++ b/include/uapi/linux/trusty/ipc.h @@ -9,15 +9,19 @@ /** * enum transfer_kind - How to send an fd to Trusty - * @TRUSTY_SHARE: Memory will be accessible by Linux and Trusty. On ARM it will - * be mapped as nonsecure. Suitable for shared memory. The paired - * fd must be a "memfd". - * @TRUSTY_LEND: Memory will be accessible only to Trusty. On ARM it will be - * transitioned to "Secure" memory if Trusty is in TrustZone. - * This transfer kind is suitable for donating video buffers or - * other similar resources. The paired fd may need to come from a - * platform-specific allocator for memory that may be - * transitioned to "Secure". + * @TRUSTY_SHARE: Memory will be accessible by Linux and Trusty. On ARM it + * will be mapped as nonsecure. Suitable for shared memory. + * The paired fd must be a "dma_buf". + * @TRUSTY_LEND: Memory will be accessible only to Trusty. On ARM it will + * be transitioned to "Secure" memory if Trusty is in + * TrustZone. This transfer kind is suitable for donating + * video buffers or other similar resources. The paired fd + * may need to come from a platform-specific allocator for + * memory that may be transitioned to "Secure". + * @TRUSTY_SEND_SECURE: Send memory that is already "Secure". Memory will be + * accessible only to Trusty. The paired fd may need to + * come from a platform-specific allocator that returns + * "Secure" buffers. * * Describes how the user would like the resource in question to be sent to * Trusty. Options may be valid only for certain kinds of fds. @@ -25,6 +29,7 @@ enum transfer_kind { TRUSTY_SHARE = 0, TRUSTY_LEND = 1, + TRUSTY_SEND_SECURE = 2, }; /** |