From: Rijo Thomas Rijo-john.Thomas@amd.com
Allocate TEE ring buffer and command buffer using psp_tee_alloc_buffer(), and free TEE ring buffer and command buffer 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@amd.com Co-developed-by: Jeshwanth Kumar JESHWANTHKUMAR.NK@amd.com Signed-off-by: Jeshwanth Kumar JESHWANTHKUMAR.NK@amd.com --- drivers/crypto/ccp/tee-dev.c | 68 ++++++++++++++---------------------- drivers/crypto/ccp/tee-dev.h | 11 +++--- 2 files changed, 31 insertions(+), 48 deletions(-)
diff --git a/drivers/crypto/ccp/tee-dev.c b/drivers/crypto/ccp/tee-dev.c index fa6f89572613..f0a94191662d 100644 --- a/drivers/crypto/ccp/tee-dev.c +++ b/drivers/crypto/ccp/tee-dev.c @@ -76,22 +76,16 @@ EXPORT_SYMBOL(psp_tee_free_buffer); static int tee_alloc_ring(struct psp_tee_device *tee, int ring_size) { struct ring_buf_manager *rb_mgr = &tee->rb_mgr; - void *start_addr;
if (!ring_size) return -EINVAL;
- /* We need actual physical address instead of DMA address, since - * Trusted OS running on AMD Secure Processor will map this region - */ - start_addr = (void *)__get_free_pages(GFP_KERNEL, get_order(ring_size)); - if (!start_addr) + rb_mgr->ring_buf = psp_tee_alloc_buffer(ring_size, + GFP_KERNEL | __GFP_ZERO); + if (!rb_mgr->ring_buf) { + dev_err(tee->dev, "ring allocation failed\n"); return -ENOMEM; - - memset(start_addr, 0x0, ring_size); - rb_mgr->ring_start = start_addr; - rb_mgr->ring_size = ring_size; - rb_mgr->ring_pa = __psp_pa(start_addr); + } mutex_init(&rb_mgr->mutex);
return 0; @@ -101,15 +95,8 @@ static void tee_free_ring(struct psp_tee_device *tee) { struct ring_buf_manager *rb_mgr = &tee->rb_mgr;
- if (!rb_mgr->ring_start) - return; + psp_tee_free_buffer(rb_mgr->ring_buf);
- free_pages((unsigned long)rb_mgr->ring_start, - get_order(rb_mgr->ring_size)); - - rb_mgr->ring_start = NULL; - rb_mgr->ring_size = 0; - rb_mgr->ring_pa = 0; mutex_destroy(&rb_mgr->mutex); }
@@ -133,35 +120,36 @@ static int tee_wait_cmd_poll(struct psp_tee_device *tee, unsigned int timeout, return -ETIMEDOUT; }
-static -struct tee_init_ring_cmd *tee_alloc_cmd_buffer(struct psp_tee_device *tee) +struct psp_tee_buffer *tee_alloc_cmd_buffer(struct psp_tee_device *tee) { struct tee_init_ring_cmd *cmd; + struct psp_tee_buffer *cmd_buffer;
- cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); - if (!cmd) + cmd_buffer = psp_tee_alloc_buffer(sizeof(*cmd), + GFP_KERNEL | __GFP_ZERO); + if (!cmd_buffer) return NULL;
- cmd->hi_addr = upper_32_bits(tee->rb_mgr.ring_pa); - cmd->low_addr = lower_32_bits(tee->rb_mgr.ring_pa); - cmd->size = tee->rb_mgr.ring_size; + cmd = (struct tee_init_ring_cmd *)cmd_buffer->vaddr; + cmd->hi_addr = upper_32_bits(tee->rb_mgr.ring_buf->paddr); + cmd->low_addr = lower_32_bits(tee->rb_mgr.ring_buf->paddr); + cmd->size = tee->rb_mgr.ring_buf->size;
dev_dbg(tee->dev, "tee: ring address: high = 0x%x low = 0x%x size = %u\n", cmd->hi_addr, cmd->low_addr, cmd->size);
- return cmd; + return cmd_buffer; }
-static inline void tee_free_cmd_buffer(struct tee_init_ring_cmd *cmd) +static inline void tee_free_cmd_buffer(struct psp_tee_buffer *cmd_buffer) { - kfree(cmd); + psp_tee_free_buffer(cmd_buffer); }
static int tee_init_ring(struct psp_tee_device *tee) { int ring_size = MAX_RING_BUFFER_ENTRIES * sizeof(struct tee_ring_cmd); - struct tee_init_ring_cmd *cmd; - phys_addr_t cmd_buffer; + struct psp_tee_buffer *cmd_buffer; unsigned int reg; int ret;
@@ -175,21 +163,19 @@ static int tee_init_ring(struct psp_tee_device *tee)
tee->rb_mgr.wptr = 0;
- cmd = tee_alloc_cmd_buffer(tee); - if (!cmd) { + cmd_buffer = tee_alloc_cmd_buffer(tee); + if (!cmd_buffer) { tee_free_ring(tee); return -ENOMEM; }
- cmd_buffer = __psp_pa((void *)cmd); - /* Send command buffer details to Trusted OS by writing to * CPU-PSP message registers */
- iowrite32(lower_32_bits(cmd_buffer), + iowrite32(lower_32_bits(cmd_buffer->paddr), tee->io_regs + tee->vdata->cmdbuff_addr_lo_reg); - iowrite32(upper_32_bits(cmd_buffer), + iowrite32(upper_32_bits(cmd_buffer->paddr), tee->io_regs + tee->vdata->cmdbuff_addr_hi_reg); iowrite32(TEE_RING_INIT_CMD, tee->io_regs + tee->vdata->cmdresp_reg); @@ -209,7 +195,7 @@ static int tee_init_ring(struct psp_tee_device *tee) }
free_buf: - tee_free_cmd_buffer(cmd); + tee_free_cmd_buffer(cmd_buffer);
return ret; } @@ -219,7 +205,7 @@ static void tee_destroy_ring(struct psp_tee_device *tee) unsigned int reg; int ret;
- if (!tee->rb_mgr.ring_start) + if (!tee->rb_mgr.ring_buf->vaddr) return;
if (psp_dead) @@ -308,7 +294,7 @@ static int tee_submit_cmd(struct psp_tee_device *tee, enum tee_cmd_id cmd_id, do { /* Get pointer to ring buffer command entry */ cmd = (struct tee_ring_cmd *) - (tee->rb_mgr.ring_start + tee->rb_mgr.wptr); + (tee->rb_mgr.ring_buf->vaddr + tee->rb_mgr.wptr);
rptr = ioread32(tee->io_regs + tee->vdata->ring_rptr_reg);
@@ -357,7 +343,7 @@ static int tee_submit_cmd(struct psp_tee_device *tee, enum tee_cmd_id cmd_id,
/* Update local copy of write pointer */ tee->rb_mgr.wptr += sizeof(struct tee_ring_cmd); - if (tee->rb_mgr.wptr >= tee->rb_mgr.ring_size) + if (tee->rb_mgr.wptr >= tee->rb_mgr.ring_buf->size) tee->rb_mgr.wptr = 0;
/* Trigger interrupt to Trusted OS */ diff --git a/drivers/crypto/ccp/tee-dev.h b/drivers/crypto/ccp/tee-dev.h index 49d26158b71e..0e4398d15f93 100644 --- a/drivers/crypto/ccp/tee-dev.h +++ b/drivers/crypto/ccp/tee-dev.h @@ -16,6 +16,7 @@
#include <linux/device.h> #include <linux/mutex.h> +#include <linux/psp-tee.h>
#define TEE_DEFAULT_TIMEOUT 10 #define MAX_BUFFER_SIZE 988 @@ -48,17 +49,13 @@ struct tee_init_ring_cmd {
/** * struct ring_buf_manager - Helper structure to manage ring buffer. - * @ring_start: starting address of ring buffer - * @ring_size: size of ring buffer in bytes - * @ring_pa: physical address of ring buffer * @wptr: index to the last written entry in ring buffer + * @ring_buf: ring buffer allocated using DMA api */ struct ring_buf_manager { - struct mutex mutex; /* synchronizes access to ring buffer */ - void *ring_start; - u32 ring_size; - phys_addr_t ring_pa; + struct mutex mutex; /* synchronizes access to ring buffer */ u32 wptr; + struct psp_tee_buffer *ring_buf; };
struct psp_tee_device {