lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Wed, 25 Oct 2023 12:27:00 +0530
From:   jeshwank <JESHWANTHKUMAR.NK@....com>
To:     <thomas.lendacky@....com>, <john.allen@....com>,
        <herbert@...dor.apana.org.au>, <davem@...emloft.net>,
        <jens.wiklander@...aro.org>, <sumit.garg@...aro.org>,
        <jarkko.nikula@...ux.intel.com>, <mario.limonciello@....com>,
        <linux-crypto@...r.kernel.org>, <linux-kernel@...r.kernel.org>,
        <op-tee@...ts.trustedfirmware.org>
CC:     <Mythri.Pandeshwarakrishna@....com>, <Devaraj.Rangasamy@....com>,
        <Rijo-john.Thomas@....com>, <nimesh.easow@....com>,
        <JESHWANTHKUMAR.NK@....com>
Subject: [PATCH 3/3] tee: amdtee: Use psp_tee_alloc_buffer() and psp_tee_free_buffer()

From: Rijo Thomas <Rijo-john.Thomas@....com>

Allocate shared memory using psp_tee_alloc_buffer(), and free shared
memory using psp_tee_free_buffer().

As part of cleanup, memory allocation using get_free_pages() is replaced
with DMA APIs.

Signed-off-by: Rijo Thomas <Rijo-john.Thomas@....com>
Signed-off-by: Jeshwanth Kumar <JESHWANTHKUMAR.NK@....com>
---
 drivers/tee/amdtee/amdtee_private.h | 18 +++----
 drivers/tee/amdtee/call.c           | 74 +++++++++++++----------------
 drivers/tee/amdtee/core.c           | 72 +++++++++++++++++-----------
 drivers/tee/amdtee/shm_pool.c       | 21 ++------
 4 files changed, 89 insertions(+), 96 deletions(-)

diff --git a/drivers/tee/amdtee/amdtee_private.h b/drivers/tee/amdtee/amdtee_private.h
index 6d0f7062bb87..e2bb0a21942c 100644
--- a/drivers/tee/amdtee/amdtee_private.h
+++ b/drivers/tee/amdtee/amdtee_private.h
@@ -13,6 +13,7 @@
 #include <linux/kref.h>
 #include <linux/types.h>
 #include "amdtee_if.h"
+#include <linux/psp-tee.h>
 
 #define DRIVER_NAME	"amdtee"
 #define DRIVER_AUTHOR   "AMD-TEE Linux driver team"
@@ -78,19 +79,14 @@ struct amdtee_driver_data {
 	struct amdtee *amdtee;
 };
 
-struct shmem_desc {
-	void *kaddr;
-	u64 size;
-};
-
 /**
  * struct amdtee_shm_data - Shared memory data
- * @kaddr:	Kernel virtual address of shared memory
+ * @shm_buf:	Pointer to shared memory buffer
  * @buf_id:	Buffer id of memory mapped by TEE_CMD_ID_MAP_SHARED_MEM
  */
 struct amdtee_shm_data {
 	struct  list_head shm_node;
-	void    *kaddr;
+	struct	psp_tee_buffer *shm_buf;
 	u32     buf_id;
 };
 
@@ -145,11 +141,11 @@ int amdtee_invoke_func(struct tee_context *ctx,
 
 int amdtee_cancel_req(struct tee_context *ctx, u32 cancel_id, u32 session);
 
-int amdtee_map_shmem(struct tee_shm *shm);
+int amdtee_alloc_shmem(struct tee_shm *shm);
 
-void amdtee_unmap_shmem(struct tee_shm *shm);
+void amdtee_free_shmem(struct tee_shm *shm);
 
-int handle_load_ta(void *data, u32 size,
+int handle_load_ta(struct psp_tee_buffer *buf,
 		   struct tee_ioctl_open_session_arg *arg);
 
 int handle_unload_ta(u32 ta_handle);
@@ -159,7 +155,7 @@ int handle_open_session(struct tee_ioctl_open_session_arg *arg, u32 *info,
 
 int handle_close_session(u32 ta_handle, u32 info);
 
-int handle_map_shmem(u32 count, struct shmem_desc *start, u32 *buf_id);
+int handle_map_shmem(struct psp_tee_buffer *shm_buf, u32 *buf_id);
 
 void handle_unmap_shmem(u32 buf_id);
 
diff --git a/drivers/tee/amdtee/call.c b/drivers/tee/amdtee/call.c
index e9b63dcb3194..031d37cc975c 100644
--- a/drivers/tee/amdtee/call.c
+++ b/drivers/tee/amdtee/call.c
@@ -283,53 +283,44 @@ int handle_invoke_cmd(struct tee_ioctl_invoke_arg *arg, u32 sinfo,
 	return ret;
 }
 
-int handle_map_shmem(u32 count, struct shmem_desc *start, u32 *buf_id)
+int handle_map_shmem(struct psp_tee_buffer *shm_buf, u32 *buf_id)
 {
 	struct tee_cmd_map_shared_mem *cmd;
-	phys_addr_t paddr;
-	int ret, i;
 	u32 status;
+	int ret;
 
-	if (!count || !start || !buf_id)
+	if (!shm_buf || !shm_buf->vaddr || !buf_id)
 		return -EINVAL;
 
 	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
 	if (!cmd)
 		return -ENOMEM;
 
-	/* Size must be page aligned */
-	for (i = 0; i < count ; i++) {
-		if (!start[i].kaddr || (start[i].size & (PAGE_SIZE - 1))) {
-			ret = -EINVAL;
-			goto free_cmd;
-		}
-
-		if ((u64)start[i].kaddr & (PAGE_SIZE - 1)) {
-			pr_err("map shared memory: page unaligned. addr 0x%llx",
-			       (u64)start[i].kaddr);
-			ret = -EINVAL;
-			goto free_cmd;
-		}
+	/* Size and address must be page aligned */
+	if (shm_buf->size & (PAGE_SIZE - 1)) {
+		ret = -EINVAL;
+		goto free_cmd;
 	}
 
-	cmd->sg_list.count = count;
-
-	/* Create buffer list */
-	for (i = 0; i < count ; i++) {
-		paddr = __psp_pa(start[i].kaddr);
-		cmd->sg_list.buf[i].hi_addr = upper_32_bits(paddr);
-		cmd->sg_list.buf[i].low_addr = lower_32_bits(paddr);
-		cmd->sg_list.buf[i].size = start[i].size;
-		cmd->sg_list.size += cmd->sg_list.buf[i].size;
-
-		pr_debug("buf[%d]:hi addr = 0x%x\n", i,
-			 cmd->sg_list.buf[i].hi_addr);
-		pr_debug("buf[%d]:low addr = 0x%x\n", i,
-			 cmd->sg_list.buf[i].low_addr);
-		pr_debug("buf[%d]:size = 0x%x\n", i, cmd->sg_list.buf[i].size);
-		pr_debug("list size = 0x%x\n", cmd->sg_list.size);
+	if ((u64)shm_buf->vaddr & (PAGE_SIZE - 1)) {
+		pr_err("map shared memory: page unaligned. addr 0x%llx",
+		       (u64)shm_buf->vaddr);
+		ret = -EINVAL;
+		goto free_cmd;
 	}
 
+	/* Update sg list */
+	cmd->sg_list.count = 1;
+	cmd->sg_list.buf[0].hi_addr = upper_32_bits(shm_buf->paddr);
+	cmd->sg_list.buf[0].low_addr = lower_32_bits(shm_buf->paddr);
+	cmd->sg_list.buf[0].size = shm_buf->size;
+	cmd->sg_list.size = cmd->sg_list.buf[0].size;
+
+	pr_debug("buf: hi addr = 0x%x\n", cmd->sg_list.buf[0].hi_addr);
+	pr_debug("buf: low addr = 0x%x\n", cmd->sg_list.buf[0].low_addr);
+	pr_debug("buf: size = 0x%x\n", cmd->sg_list.buf[0].size);
+	pr_debug("list size = 0x%x\n", cmd->sg_list.size);
+
 	*buf_id = 0;
 
 	ret = psp_tee_process_cmd(TEE_CMD_ID_MAP_SHARED_MEM, (void *)cmd,
@@ -396,25 +387,24 @@ int handle_open_session(struct tee_ioctl_open_session_arg *arg, u32 *info,
 	return ret;
 }
 
-int handle_load_ta(void *data, u32 size, struct tee_ioctl_open_session_arg *arg)
+int handle_load_ta(struct psp_tee_buffer *buf,
+		   struct tee_ioctl_open_session_arg *arg)
 {
 	struct tee_cmd_unload_ta unload_cmd = {};
 	struct tee_cmd_load_ta load_cmd = {};
-	phys_addr_t blob;
 	int ret;
 
-	if (size == 0 || !data || !arg)
+	if (buf->size == 0 || !buf->paddr || !arg)
 		return -EINVAL;
 
-	blob = __psp_pa(data);
-	if (blob & (PAGE_SIZE - 1)) {
-		pr_err("load TA: page unaligned. blob 0x%llx", blob);
+	if (buf->dma & (PAGE_SIZE - 1)) {
+		pr_err("load TA: page unaligned. addr 0x%llx", buf->dma);
 		return -EINVAL;
 	}
 
-	load_cmd.hi_addr = upper_32_bits(blob);
-	load_cmd.low_addr = lower_32_bits(blob);
-	load_cmd.size = size;
+	load_cmd.hi_addr = upper_32_bits(buf->paddr);
+	load_cmd.low_addr = lower_32_bits(buf->paddr);
+	load_cmd.size = buf->size;
 
 	mutex_lock(&ta_refcount_mutex);
 
diff --git a/drivers/tee/amdtee/core.c b/drivers/tee/amdtee/core.c
index 3c15f6a9e91c..37784360fc10 100644
--- a/drivers/tee/amdtee/core.c
+++ b/drivers/tee/amdtee/core.c
@@ -17,6 +17,7 @@
 #include "amdtee_private.h"
 #include "../tee_private.h"
 #include <linux/psp-tee.h>
+#include <linux/psp.h>
 
 static struct amdtee_driver_data *drv_data;
 static DEFINE_MUTEX(session_list_mutex);
@@ -158,7 +159,8 @@ u32 get_buffer_id(struct tee_shm *shm)
 
 	mutex_lock(&ctxdata->shm_mutex);
 	list_for_each_entry(shmdata, &ctxdata->shm_list, shm_node)
-		if (shmdata->kaddr == shm->kaddr) {
+		if (shmdata->shm_buf &&
+		    shmdata->shm_buf->vaddr == shm->kaddr) {
 			buf_id = shmdata->buf_id;
 			break;
 		}
@@ -168,11 +170,13 @@ u32 get_buffer_id(struct tee_shm *shm)
 }
 
 static DEFINE_MUTEX(drv_mutex);
-static int copy_ta_binary(struct tee_context *ctx, void *ptr, void **ta,
-			  size_t *ta_size)
+static int copy_ta_binary(struct tee_context *ctx, void *ptr,
+			  struct psp_tee_buffer **bufp)
 {
 	const struct firmware *fw;
 	char fw_name[TA_PATH_MAX];
+	struct psp_tee_buffer *buf;
+	unsigned long size;
 	struct {
 		u32 lo;
 		u16 mid;
@@ -201,15 +205,16 @@ static int copy_ta_binary(struct tee_context *ctx, void *ptr, void **ta,
 		goto unlock;
 	}
 
-	*ta_size = roundup(fw->size, PAGE_SIZE);
-	*ta = (void *)__get_free_pages(GFP_KERNEL, get_order(*ta_size));
-	if (!*ta) {
-		pr_err("%s: get_free_pages failed\n", __func__);
+	size = roundup(fw->size, PAGE_SIZE);
+	buf = psp_tee_alloc_buffer(size, GFP_KERNEL);
+	if (!buf) {
+		pr_err("TA binary memory allocation failed\n");
 		rc = -ENOMEM;
 		goto rel_fw;
 	}
+	memcpy(buf->vaddr, fw->data, fw->size);
+	*bufp = buf;
 
-	memcpy(*ta, fw->data, fw->size);
 rel_fw:
 	release_firmware(fw);
 unlock:
@@ -234,24 +239,23 @@ int amdtee_open_session(struct tee_context *ctx,
 {
 	struct amdtee_context_data *ctxdata = ctx->data;
 	struct amdtee_session *sess = NULL;
+	struct psp_tee_buffer *buf;
 	u32 session_info, ta_handle;
-	size_t ta_size;
 	int rc, i;
-	void *ta;
 
 	if (arg->clnt_login != TEE_IOCTL_LOGIN_PUBLIC) {
 		pr_err("unsupported client login method\n");
 		return -EINVAL;
 	}
 
-	rc = copy_ta_binary(ctx, &arg->uuid[0], &ta, &ta_size);
+	rc = copy_ta_binary(ctx, &arg->uuid[0], &buf);
 	if (rc) {
 		pr_err("failed to copy TA binary\n");
 		return rc;
 	}
 
 	/* Load the TA binary into TEE environment */
-	handle_load_ta(ta, ta_size, arg);
+	handle_load_ta(buf, arg);
 	if (arg->ret != TEEC_SUCCESS)
 		goto out;
 
@@ -298,7 +302,7 @@ int amdtee_open_session(struct tee_context *ctx,
 	}
 
 out:
-	free_pages((u64)ta, get_order(ta_size));
+	psp_tee_free_buffer(buf);
 	return rc;
 }
 
@@ -338,51 +342,62 @@ int amdtee_close_session(struct tee_context *ctx, u32 session)
 	return 0;
 }
 
-int amdtee_map_shmem(struct tee_shm *shm)
+int amdtee_alloc_shmem(struct tee_shm *shm)
 {
 	struct amdtee_context_data *ctxdata;
 	struct amdtee_shm_data *shmnode;
-	struct shmem_desc shmem;
-	int rc, count;
+	struct psp_tee_buffer *shm_buf;
 	u32 buf_id;
+	int rc;
 
 	if (!shm)
 		return -EINVAL;
 
-	shmnode = kmalloc(sizeof(*shmnode), GFP_KERNEL);
-	if (!shmnode)
+	shm_buf = psp_tee_alloc_buffer(shm->size, GFP_KERNEL | __GFP_ZERO);
+	if (!shm_buf)
 		return -ENOMEM;
 
-	count = 1;
-	shmem.kaddr = shm->kaddr;
-	shmem.size = shm->size;
+	shm->kaddr = shm_buf->vaddr;
+	shm->paddr = __psp_pa(shm_buf->vaddr);
+
+	shmnode = kmalloc(sizeof(*shmnode), GFP_KERNEL);
+	if (!shmnode) {
+		rc = -ENOMEM;
+		goto free_dmabuf;
+	}
 
 	/*
 	 * Send a MAP command to TEE and get the corresponding
 	 * buffer Id
 	 */
-	rc = handle_map_shmem(count, &shmem, &buf_id);
+	rc = handle_map_shmem(shm_buf, &buf_id);
 	if (rc) {
 		pr_err("map_shmem failed: ret = %d\n", rc);
-		kfree(shmnode);
-		return rc;
+		goto free_shmnode;
 	}
 
-	shmnode->kaddr = shm->kaddr;
+	shmnode->shm_buf = shm_buf;
 	shmnode->buf_id = buf_id;
 	ctxdata = shm->ctx->data;
 	mutex_lock(&ctxdata->shm_mutex);
 	list_add(&shmnode->shm_node, &ctxdata->shm_list);
 	mutex_unlock(&ctxdata->shm_mutex);
 
-	pr_debug("buf_id :[%x] kaddr[%p]\n", shmnode->buf_id, shmnode->kaddr);
+	pr_debug("buf_id :[%x] kaddr[%p]\n", shmnode->buf_id, shm->kaddr);
 
 	return 0;
+
+free_shmnode:
+	kfree(shmnode);
+free_dmabuf:
+	psp_tee_free_buffer(shm_buf);
+	return rc;
 }
 
-void amdtee_unmap_shmem(struct tee_shm *shm)
+void amdtee_free_shmem(struct tee_shm *shm)
 {
 	struct amdtee_context_data *ctxdata;
+	struct psp_tee_buffer *shm_buf = NULL;
 	struct amdtee_shm_data *shmnode;
 	u32 buf_id;
 
@@ -390,6 +405,7 @@ void amdtee_unmap_shmem(struct tee_shm *shm)
 		return;
 
 	buf_id = get_buffer_id(shm);
+
 	/* Unmap the shared memory from TEE */
 	handle_unmap_shmem(buf_id);
 
@@ -398,10 +414,12 @@ void amdtee_unmap_shmem(struct tee_shm *shm)
 	list_for_each_entry(shmnode, &ctxdata->shm_list, shm_node)
 		if (buf_id == shmnode->buf_id) {
 			list_del(&shmnode->shm_node);
+			shm_buf = shmnode->shm_buf;
 			kfree(shmnode);
 			break;
 		}
 	mutex_unlock(&ctxdata->shm_mutex);
+	psp_tee_free_buffer(shm_buf);
 }
 
 int amdtee_invoke_func(struct tee_context *ctx,
diff --git a/drivers/tee/amdtee/shm_pool.c b/drivers/tee/amdtee/shm_pool.c
index f0303126f199..443874c82611 100644
--- a/drivers/tee/amdtee/shm_pool.c
+++ b/drivers/tee/amdtee/shm_pool.c
@@ -12,25 +12,13 @@ static int pool_op_alloc(struct tee_shm_pool *pool, struct tee_shm *shm,
 			 size_t size, size_t align)
 {
 	unsigned int order = get_order(size);
-	unsigned long va;
 	int rc;
 
-	/*
-	 * Ignore alignment since this is already going to be page aligned
-	 * and there's no need for any larger alignment.
-	 */
-	va = __get_free_pages(GFP_KERNEL | __GFP_ZERO, order);
-	if (!va)
-		return -ENOMEM;
-
-	shm->kaddr = (void *)va;
-	shm->paddr = __psp_pa((void *)va);
 	shm->size = PAGE_SIZE << order;
 
-	/* Map the allocated memory in to TEE */
-	rc = amdtee_map_shmem(shm);
+	/* Allocate and map memory in to TEE */
+	rc = amdtee_alloc_shmem(shm);
 	if (rc) {
-		free_pages(va, order);
 		shm->kaddr = NULL;
 		return rc;
 	}
@@ -41,8 +29,9 @@ static int pool_op_alloc(struct tee_shm_pool *pool, struct tee_shm *shm,
 static void pool_op_free(struct tee_shm_pool *pool, struct tee_shm *shm)
 {
 	/* Unmap the shared memory from TEE */
-	amdtee_unmap_shmem(shm);
-	free_pages((unsigned long)shm->kaddr, get_order(shm->size));
+	amdtee_free_shmem(shm);
+
+	shm->size = 0;
 	shm->kaddr = NULL;
 }
 
-- 
2.25.1

Powered by blists - more mailing lists