summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTri Vo <trong@google.com>2022-01-18 16:15:06 -0800
committerWill McVicker <willmcvicker@google.com>2022-04-22 10:47:57 -0700
commit7078cceeba4af32c97408c4e1b90d209ba615486 (patch)
tree94f24eeda7bcaac6b0460f62c22a8e79b53205d2
parent187e1b804ddf226b0d587adba2f22ecbfb0a7587 (diff)
downloadtrusty-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/Kconfig13
-rw-r--r--drivers/trusty/trusty-ipc.c58
-rw-r--r--include/linux/trusty/trusty.h27
-rw-r--r--include/uapi/linux/trusty/ipc.h23
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,
};
/**