| From ded880d3eb33d8fafc3032882fdc6a35ac7ba6ce Mon Sep 17 00:00:00 2001 |
| From: Sumit Garg <sumit.garg@linaro.org> |
| Date: Fri, 8 Nov 2019 16:57:14 +0530 |
| Subject: [PATCH] tee: optee: Fix dynamic shm pool allocations |
| |
| commit a249dd200d03791cab23e47571f3e13d9c72af6c upstream. |
| |
| In case of dynamic shared memory pool, kernel memory allocated using |
| dmabuf_mgr pool needs to be registered with OP-TEE prior to its usage |
| during optee_open_session() or optee_invoke_func(). |
| |
| So fix dmabuf_mgr pool allocations via an additional call to |
| optee_shm_register(). |
| |
| Also, allow kernel pages to be registered as shared memory with OP-TEE. |
| |
| Fixes: 9733b072a12a ("optee: allow to work without static shared memory") |
| Signed-off-by: Sumit Garg <sumit.garg@linaro.org> |
| Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/tee/optee/call.c b/drivers/tee/optee/call.c |
| index aa942703ae65..bce45b16d46c 100644 |
| --- a/drivers/tee/optee/call.c |
| +++ b/drivers/tee/optee/call.c |
| @@ -553,6 +553,13 @@ static int check_mem_type(unsigned long start, size_t num_pages) |
| struct mm_struct *mm = current->mm; |
| int rc; |
| |
| + /* |
| + * Allow kernel address to register with OP-TEE as kernel |
| + * pages are configured as normal memory only. |
| + */ |
| + if (virt_addr_valid(start)) |
| + return 0; |
| + |
| down_read(&mm->mmap_sem); |
| rc = __check_mem_type(find_vma(mm, start), |
| start + num_pages * PAGE_SIZE); |
| diff --git a/drivers/tee/optee/shm_pool.c b/drivers/tee/optee/shm_pool.c |
| index de1d9b8fad90..0332a5301d61 100644 |
| --- a/drivers/tee/optee/shm_pool.c |
| +++ b/drivers/tee/optee/shm_pool.c |
| @@ -17,6 +17,7 @@ static int pool_op_alloc(struct tee_shm_pool_mgr *poolm, |
| { |
| unsigned int order = get_order(size); |
| struct page *page; |
| + int rc = 0; |
| |
| page = alloc_pages(GFP_KERNEL | __GFP_ZERO, order); |
| if (!page) |
| @@ -26,12 +27,21 @@ static int pool_op_alloc(struct tee_shm_pool_mgr *poolm, |
| shm->paddr = page_to_phys(page); |
| shm->size = PAGE_SIZE << order; |
| |
| - return 0; |
| + if (shm->flags & TEE_SHM_DMA_BUF) { |
| + shm->flags |= TEE_SHM_REGISTER; |
| + rc = optee_shm_register(shm->ctx, shm, &page, 1 << order, |
| + (unsigned long)shm->kaddr); |
| + } |
| + |
| + return rc; |
| } |
| |
| static void pool_op_free(struct tee_shm_pool_mgr *poolm, |
| struct tee_shm *shm) |
| { |
| + if (shm->flags & TEE_SHM_DMA_BUF) |
| + optee_shm_unregister(shm->ctx, shm); |
| + |
| free_pages((unsigned long)shm->kaddr, get_order(shm->size)); |
| shm->kaddr = NULL; |
| } |
| -- |
| 2.7.4 |
| |