* [PATCH v2 0/2] OP-TEE kernel private shared memory optimizations @ 2023-11-08 10:27 Jens Wiklander 2023-11-08 10:27 ` [PATCH v2 1/2] optee: add page list to kernel private shared memory Jens Wiklander 2023-11-08 10:27 ` [PATCH v2 2/2] optee: allocate shared memory with alloc_pages_exact() Jens Wiklander 0 siblings, 2 replies; 5+ messages in thread From: Jens Wiklander @ 2023-11-08 10:27 UTC (permalink / raw) To: linux-kernel, op-tee Cc: Sumit Garg, Jerome Forissier, Shyam Saini, Jens Wiklander Hi, This patch set optimizes OP-TEE driver private shared memory allocated as dynamic shared memory (not from the static shared memory pool). The first patch handles kernel private RPC allocatations larger than one page and the second changes from alloc_pages_exact() instead of alloc_pages() for more efficient memory usage. v1->v2: * Split into two patches as requested Jens Wiklander (2): optee: add page list to kernel private shared memory optee: allocate shared memory with alloc_pages_exact() drivers/tee/optee/core.c | 59 +++++++++++++++++++++++++------------ drivers/tee/optee/smc_abi.c | 45 +++++++++++++--------------- 2 files changed, 61 insertions(+), 43 deletions(-) base-commit: 05d3ef8bba77c1b5f98d941d8b2d4aeab8118ef1 -- 2.34.1 ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2 1/2] optee: add page list to kernel private shared memory 2023-11-08 10:27 [PATCH v2 0/2] OP-TEE kernel private shared memory optimizations Jens Wiklander @ 2023-11-08 10:27 ` Jens Wiklander 2023-11-10 14:36 ` Sumit Garg 2023-11-08 10:27 ` [PATCH v2 2/2] optee: allocate shared memory with alloc_pages_exact() Jens Wiklander 1 sibling, 1 reply; 5+ messages in thread From: Jens Wiklander @ 2023-11-08 10:27 UTC (permalink / raw) To: linux-kernel, op-tee Cc: Sumit Garg, Jerome Forissier, Shyam Saini, Jens Wiklander Until now has kernel private shared memory allocated as dynamic shared memory (not from the static shared memory pool) been returned without a list of physical pages on allocations via RPC. To support allocations larger than one page add a list of physical pages for all allocations larger than one page. Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org> --- drivers/tee/optee/core.c | 40 +++++++++++++++++++++++++-------- drivers/tee/optee/smc_abi.c | 45 +++++++++++++++++-------------------- 2 files changed, 52 insertions(+), 33 deletions(-) diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c index 2a258bd3b6b5..a425eca0173d 100644 --- a/drivers/tee/optee/core.c +++ b/drivers/tee/optee/core.c @@ -27,6 +27,7 @@ int optee_pool_op_alloc_helper(struct tee_shm_pool *pool, struct tee_shm *shm, unsigned long start)) { unsigned int order = get_order(size); + unsigned int nr_pages = 1 << order; struct page *page; int rc = 0; @@ -39,12 +40,24 @@ int optee_pool_op_alloc_helper(struct tee_shm_pool *pool, struct tee_shm *shm, return -ENOMEM; shm->kaddr = page_address(page); - shm->paddr = page_to_phys(page); shm->size = PAGE_SIZE << order; - if (shm_register) { - unsigned int nr_pages = 1 << order, i; + /* + * If memory is registered immediately use a temporary page list + * and free it directly after the registration is completed. + * + * Else, if we have allocated more than one page store a page + * list in the struct tee_shm. + * + * Else, store the physical address of the single page that was + * allocated. + * + * optee_pool_op_free_helper() is responsible for freeing the + * resourses allocated in this function. + */ + if (shm_register || nr_pages > 1) { struct page **pages; + unsigned int i; pages = kcalloc(nr_pages, sizeof(*pages), GFP_KERNEL); if (!pages) { @@ -55,17 +68,24 @@ int optee_pool_op_alloc_helper(struct tee_shm_pool *pool, struct tee_shm *shm, for (i = 0; i < nr_pages; i++) pages[i] = page + i; - rc = shm_register(shm->ctx, shm, pages, nr_pages, - (unsigned long)shm->kaddr); - kfree(pages); - if (rc) - goto err; + if (shm_register) { + rc = shm_register(shm->ctx, shm, pages, nr_pages, + (unsigned long)shm->kaddr); + kfree(pages); + if (rc) + goto err; + } else { + shm->pages = pages; + shm->num_pages = nr_pages; + } + } else { + shm->paddr = page_to_phys(page); } return 0; - err: free_pages((unsigned long)shm->kaddr, order); + shm->kaddr = NULL; return rc; } @@ -77,6 +97,8 @@ void optee_pool_op_free_helper(struct tee_shm_pool *pool, struct tee_shm *shm, shm_unregister(shm->ctx, shm); free_pages((unsigned long)shm->kaddr, get_order(shm->size)); shm->kaddr = NULL; + kfree(shm->pages); + shm->pages = NULL; } static void optee_bus_scan(struct work_struct *work) diff --git a/drivers/tee/optee/smc_abi.c b/drivers/tee/optee/smc_abi.c index d5b28fd35d66..b69410c7cc0a 100644 --- a/drivers/tee/optee/smc_abi.c +++ b/drivers/tee/optee/smc_abi.c @@ -678,10 +678,11 @@ static void handle_rpc_func_cmd_shm_alloc(struct tee_context *ctx, struct optee_msg_arg *arg, struct optee_call_ctx *call_ctx) { - phys_addr_t pa; struct tee_shm *shm; size_t sz; size_t n; + struct page **pages; + size_t page_count; arg->ret_origin = TEEC_ORIGIN_COMMS; @@ -716,32 +717,23 @@ static void handle_rpc_func_cmd_shm_alloc(struct tee_context *ctx, return; } - if (tee_shm_get_pa(shm, 0, &pa)) { - arg->ret = TEEC_ERROR_BAD_PARAMETERS; - goto bad; - } - - sz = tee_shm_get_size(shm); - - if (tee_shm_is_dynamic(shm)) { - struct page **pages; + /* + * If there are pages it's dynamically allocated shared memory (not + * from the reserved shared memory pool) and needs to be + * registered. + */ + pages = tee_shm_get_pages(shm, &page_count); + if (pages) { u64 *pages_list; - size_t page_num; - - pages = tee_shm_get_pages(shm, &page_num); - if (!pages || !page_num) { - arg->ret = TEEC_ERROR_OUT_OF_MEMORY; - goto bad; - } - pages_list = optee_allocate_pages_list(page_num); + pages_list = optee_allocate_pages_list(page_count); if (!pages_list) { arg->ret = TEEC_ERROR_OUT_OF_MEMORY; goto bad; } call_ctx->pages_list = pages_list; - call_ctx->num_entries = page_num; + call_ctx->num_entries = page_count; arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT | OPTEE_MSG_ATTR_NONCONTIG; @@ -752,17 +744,22 @@ static void handle_rpc_func_cmd_shm_alloc(struct tee_context *ctx, arg->params[0].u.tmem.buf_ptr = virt_to_phys(pages_list) | (tee_shm_get_page_offset(shm) & (OPTEE_MSG_NONCONTIG_PAGE_SIZE - 1)); - arg->params[0].u.tmem.size = tee_shm_get_size(shm); - arg->params[0].u.tmem.shm_ref = (unsigned long)shm; - optee_fill_pages_list(pages_list, pages, page_num, + optee_fill_pages_list(pages_list, pages, page_count, tee_shm_get_page_offset(shm)); } else { + phys_addr_t pa; + + if (tee_shm_get_pa(shm, 0, &pa)) { + arg->ret = TEEC_ERROR_BAD_PARAMETERS; + goto bad; + } + arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT; arg->params[0].u.tmem.buf_ptr = pa; - arg->params[0].u.tmem.size = sz; - arg->params[0].u.tmem.shm_ref = (unsigned long)shm; } + arg->params[0].u.tmem.size = tee_shm_get_size(shm); + arg->params[0].u.tmem.shm_ref = (unsigned long)shm; arg->ret = TEEC_SUCCESS; return; -- 2.34.1 ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v2 1/2] optee: add page list to kernel private shared memory 2023-11-08 10:27 ` [PATCH v2 1/2] optee: add page list to kernel private shared memory Jens Wiklander @ 2023-11-10 14:36 ` Sumit Garg 2023-11-13 17:13 ` Jens Wiklander 0 siblings, 1 reply; 5+ messages in thread From: Sumit Garg @ 2023-11-10 14:36 UTC (permalink / raw) To: Jens Wiklander; +Cc: linux-kernel, op-tee, Jerome Forissier, Shyam Saini Hi Jens, On Wed, 8 Nov 2023 at 15:57, Jens Wiklander <jens.wiklander@linaro.org> wrote: > > Until now has kernel private shared memory allocated as dynamic shared > memory (not from the static shared memory pool) been returned without a > list of physical pages on allocations via RPC. To support allocations > larger than one page add a list of physical pages for all allocations > larger than one page. > > Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org> > --- > drivers/tee/optee/core.c | 40 +++++++++++++++++++++++++-------- > drivers/tee/optee/smc_abi.c | 45 +++++++++++++++++-------------------- > 2 files changed, 52 insertions(+), 33 deletions(-) > > diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c > index 2a258bd3b6b5..a425eca0173d 100644 > --- a/drivers/tee/optee/core.c > +++ b/drivers/tee/optee/core.c > @@ -27,6 +27,7 @@ int optee_pool_op_alloc_helper(struct tee_shm_pool *pool, struct tee_shm *shm, > unsigned long start)) > { > unsigned int order = get_order(size); > + unsigned int nr_pages = 1 << order; > struct page *page; > int rc = 0; > > @@ -39,12 +40,24 @@ int optee_pool_op_alloc_helper(struct tee_shm_pool *pool, struct tee_shm *shm, > return -ENOMEM; > > shm->kaddr = page_address(page); > - shm->paddr = page_to_phys(page); > shm->size = PAGE_SIZE << order; > > - if (shm_register) { > - unsigned int nr_pages = 1 << order, i; > + /* > + * If memory is registered immediately use a temporary page list > + * and free it directly after the registration is completed. > + * > + * Else, if we have allocated more than one page store a page > + * list in the struct tee_shm. > + * > + * Else, store the physical address of the single page that was > + * allocated. > + * > + * optee_pool_op_free_helper() is responsible for freeing the > + * resourses allocated in this function. > + */ It looks a bit complex to me. Do we really need it to be conditional? I was thinking if we can simplify this API as follows: int optee_pool_op_alloc_helper(struct tee_shm_pool *pool, struct tee_shm *shm, size_t size, size_t align, int (*shm_register)(struct tee_shm *shm)) { unsigned int order = get_order(size); unsigned int nr_pages = 1 << order, i; struct page **pages; struct page *page; int rc = 0; /* * Ignore alignment since this is already going to be page aligned * and there's no need for any larger alignment. */ page = alloc_pages(GFP_KERNEL | __GFP_ZERO, order); if (!page) return -ENOMEM; shm->kaddr = page_address(page); shm->paddr = page_to_phys(page); shm->size = PAGE_SIZE << order; pages = kcalloc(nr_pages, sizeof(*pages), GFP_KERNEL); if (!pages) { rc = -ENOMEM; goto err; } for (i = 0; i < nr_pages; i++) pages[i] = page + i; shm->pages = pages; shm->num_pages = nr_pages; if (shm_register) { rc = shm_register(shm); if (rc) goto err; } return 0; err: kfree(pages); free_pages((unsigned long)shm->kaddr, order); return rc; } -Sumit > + if (shm_register || nr_pages > 1) { > struct page **pages; > + unsigned int i; > > pages = kcalloc(nr_pages, sizeof(*pages), GFP_KERNEL); > if (!pages) { > @@ -55,17 +68,24 @@ int optee_pool_op_alloc_helper(struct tee_shm_pool *pool, struct tee_shm *shm, > for (i = 0; i < nr_pages; i++) > pages[i] = page + i; > > - rc = shm_register(shm->ctx, shm, pages, nr_pages, > - (unsigned long)shm->kaddr); > - kfree(pages); > - if (rc) > - goto err; > + if (shm_register) { > + rc = shm_register(shm->ctx, shm, pages, nr_pages, > + (unsigned long)shm->kaddr); > + kfree(pages); > + if (rc) > + goto err; > + } else { > + shm->pages = pages; > + shm->num_pages = nr_pages; > + } > + } else { > + shm->paddr = page_to_phys(page); > } > > return 0; > - > err: > free_pages((unsigned long)shm->kaddr, order); > + shm->kaddr = NULL; > return rc; > } > > @@ -77,6 +97,8 @@ void optee_pool_op_free_helper(struct tee_shm_pool *pool, struct tee_shm *shm, > shm_unregister(shm->ctx, shm); > free_pages((unsigned long)shm->kaddr, get_order(shm->size)); > shm->kaddr = NULL; > + kfree(shm->pages); > + shm->pages = NULL; > } > > static void optee_bus_scan(struct work_struct *work) > diff --git a/drivers/tee/optee/smc_abi.c b/drivers/tee/optee/smc_abi.c > index d5b28fd35d66..b69410c7cc0a 100644 > --- a/drivers/tee/optee/smc_abi.c > +++ b/drivers/tee/optee/smc_abi.c > @@ -678,10 +678,11 @@ static void handle_rpc_func_cmd_shm_alloc(struct tee_context *ctx, > struct optee_msg_arg *arg, > struct optee_call_ctx *call_ctx) > { > - phys_addr_t pa; > struct tee_shm *shm; > size_t sz; > size_t n; > + struct page **pages; > + size_t page_count; > > arg->ret_origin = TEEC_ORIGIN_COMMS; > > @@ -716,32 +717,23 @@ static void handle_rpc_func_cmd_shm_alloc(struct tee_context *ctx, > return; > } > > - if (tee_shm_get_pa(shm, 0, &pa)) { > - arg->ret = TEEC_ERROR_BAD_PARAMETERS; > - goto bad; > - } > - > - sz = tee_shm_get_size(shm); > - > - if (tee_shm_is_dynamic(shm)) { > - struct page **pages; > + /* > + * If there are pages it's dynamically allocated shared memory (not > + * from the reserved shared memory pool) and needs to be > + * registered. > + */ > + pages = tee_shm_get_pages(shm, &page_count); > + if (pages) { > u64 *pages_list; > - size_t page_num; > - > - pages = tee_shm_get_pages(shm, &page_num); > - if (!pages || !page_num) { > - arg->ret = TEEC_ERROR_OUT_OF_MEMORY; > - goto bad; > - } > > - pages_list = optee_allocate_pages_list(page_num); > + pages_list = optee_allocate_pages_list(page_count); > if (!pages_list) { > arg->ret = TEEC_ERROR_OUT_OF_MEMORY; > goto bad; > } > > call_ctx->pages_list = pages_list; > - call_ctx->num_entries = page_num; > + call_ctx->num_entries = page_count; > > arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT | > OPTEE_MSG_ATTR_NONCONTIG; > @@ -752,17 +744,22 @@ static void handle_rpc_func_cmd_shm_alloc(struct tee_context *ctx, > arg->params[0].u.tmem.buf_ptr = virt_to_phys(pages_list) | > (tee_shm_get_page_offset(shm) & > (OPTEE_MSG_NONCONTIG_PAGE_SIZE - 1)); > - arg->params[0].u.tmem.size = tee_shm_get_size(shm); > - arg->params[0].u.tmem.shm_ref = (unsigned long)shm; > > - optee_fill_pages_list(pages_list, pages, page_num, > + optee_fill_pages_list(pages_list, pages, page_count, > tee_shm_get_page_offset(shm)); > } else { > + phys_addr_t pa; > + > + if (tee_shm_get_pa(shm, 0, &pa)) { > + arg->ret = TEEC_ERROR_BAD_PARAMETERS; > + goto bad; > + } > + > arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT; > arg->params[0].u.tmem.buf_ptr = pa; > - arg->params[0].u.tmem.size = sz; > - arg->params[0].u.tmem.shm_ref = (unsigned long)shm; > } > + arg->params[0].u.tmem.size = tee_shm_get_size(shm); > + arg->params[0].u.tmem.shm_ref = (unsigned long)shm; > > arg->ret = TEEC_SUCCESS; > return; > -- > 2.34.1 > ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v2 1/2] optee: add page list to kernel private shared memory 2023-11-10 14:36 ` Sumit Garg @ 2023-11-13 17:13 ` Jens Wiklander 0 siblings, 0 replies; 5+ messages in thread From: Jens Wiklander @ 2023-11-13 17:13 UTC (permalink / raw) To: Sumit Garg; +Cc: linux-kernel, op-tee, Jerome Forissier, Shyam Saini Hi Sumit, On Fri, Nov 10, 2023 at 3:36 PM Sumit Garg <sumit.garg@linaro.org> wrote: > > Hi Jens, > > On Wed, 8 Nov 2023 at 15:57, Jens Wiklander <jens.wiklander@linaro.org> wrote: > > > > Until now has kernel private shared memory allocated as dynamic shared > > memory (not from the static shared memory pool) been returned without a > > list of physical pages on allocations via RPC. To support allocations > > larger than one page add a list of physical pages for all allocations > > larger than one page. > > > > Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org> > > --- > > drivers/tee/optee/core.c | 40 +++++++++++++++++++++++++-------- > > drivers/tee/optee/smc_abi.c | 45 +++++++++++++++++-------------------- > > 2 files changed, 52 insertions(+), 33 deletions(-) > > > > diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c > > index 2a258bd3b6b5..a425eca0173d 100644 > > --- a/drivers/tee/optee/core.c > > +++ b/drivers/tee/optee/core.c > > @@ -27,6 +27,7 @@ int optee_pool_op_alloc_helper(struct tee_shm_pool *pool, struct tee_shm *shm, > > unsigned long start)) > > { > > unsigned int order = get_order(size); > > + unsigned int nr_pages = 1 << order; > > struct page *page; > > int rc = 0; > > > > @@ -39,12 +40,24 @@ int optee_pool_op_alloc_helper(struct tee_shm_pool *pool, struct tee_shm *shm, > > return -ENOMEM; > > > > shm->kaddr = page_address(page); > > - shm->paddr = page_to_phys(page); > > shm->size = PAGE_SIZE << order; > > > > - if (shm_register) { > > - unsigned int nr_pages = 1 << order, i; > > + /* > > + * If memory is registered immediately use a temporary page list > > + * and free it directly after the registration is completed. > > + * > > + * Else, if we have allocated more than one page store a page > > + * list in the struct tee_shm. > > + * > > + * Else, store the physical address of the single page that was > > + * allocated. > > + * > > + * optee_pool_op_free_helper() is responsible for freeing the > > + * resourses allocated in this function. > > + */ > > It looks a bit complex to me. Do we really need it to be conditional? > I was thinking if we can simplify this API as follows: > > int optee_pool_op_alloc_helper(struct tee_shm_pool *pool, struct tee_shm *shm, > size_t size, size_t align, > int (*shm_register)(struct tee_shm *shm)) > { > unsigned int order = get_order(size); > unsigned int nr_pages = 1 << order, i; > struct page **pages; > struct page *page; > int rc = 0; > > /* > * Ignore alignment since this is already going to be page aligned > * and there's no need for any larger alignment. > */ > page = alloc_pages(GFP_KERNEL | __GFP_ZERO, order); > if (!page) > return -ENOMEM; > > shm->kaddr = page_address(page); > shm->paddr = page_to_phys(page); > shm->size = PAGE_SIZE << order; > > pages = kcalloc(nr_pages, sizeof(*pages), GFP_KERNEL); > if (!pages) { > rc = -ENOMEM; > goto err; > } > > for (i = 0; i < nr_pages; i++) > pages[i] = page + i; > > shm->pages = pages; > shm->num_pages = nr_pages; > > if (shm_register) { > rc = shm_register(shm); > if (rc) > goto err; > } > > return 0; > > err: > kfree(pages); > free_pages((unsigned long)shm->kaddr, order); > return rc; > } Good idea, I'll try it in the v3. Thanks, Jens > > -Sumit > > > + if (shm_register || nr_pages > 1) { > > struct page **pages; > > + unsigned int i; > > > > pages = kcalloc(nr_pages, sizeof(*pages), GFP_KERNEL); > > if (!pages) { > > @@ -55,17 +68,24 @@ int optee_pool_op_alloc_helper(struct tee_shm_pool *pool, struct tee_shm *shm, > > for (i = 0; i < nr_pages; i++) > > pages[i] = page + i; > > > > - rc = shm_register(shm->ctx, shm, pages, nr_pages, > > - (unsigned long)shm->kaddr); > > - kfree(pages); > > - if (rc) > > - goto err; > > + if (shm_register) { > > + rc = shm_register(shm->ctx, shm, pages, nr_pages, > > + (unsigned long)shm->kaddr); > > + kfree(pages); > > + if (rc) > > + goto err; > > + } else { > > + shm->pages = pages; > > + shm->num_pages = nr_pages; > > + } > > + } else { > > + shm->paddr = page_to_phys(page); > > } > > > > return 0; > > - > > err: > > free_pages((unsigned long)shm->kaddr, order); > > + shm->kaddr = NULL; > > return rc; > > } > > > > @@ -77,6 +97,8 @@ void optee_pool_op_free_helper(struct tee_shm_pool *pool, struct tee_shm *shm, > > shm_unregister(shm->ctx, shm); > > free_pages((unsigned long)shm->kaddr, get_order(shm->size)); > > shm->kaddr = NULL; > > + kfree(shm->pages); > > + shm->pages = NULL; > > } > > > > static void optee_bus_scan(struct work_struct *work) > > diff --git a/drivers/tee/optee/smc_abi.c b/drivers/tee/optee/smc_abi.c > > index d5b28fd35d66..b69410c7cc0a 100644 > > --- a/drivers/tee/optee/smc_abi.c > > +++ b/drivers/tee/optee/smc_abi.c > > @@ -678,10 +678,11 @@ static void handle_rpc_func_cmd_shm_alloc(struct tee_context *ctx, > > struct optee_msg_arg *arg, > > struct optee_call_ctx *call_ctx) > > { > > - phys_addr_t pa; > > struct tee_shm *shm; > > size_t sz; > > size_t n; > > + struct page **pages; > > + size_t page_count; > > > > arg->ret_origin = TEEC_ORIGIN_COMMS; > > > > @@ -716,32 +717,23 @@ static void handle_rpc_func_cmd_shm_alloc(struct tee_context *ctx, > > return; > > } > > > > - if (tee_shm_get_pa(shm, 0, &pa)) { > > - arg->ret = TEEC_ERROR_BAD_PARAMETERS; > > - goto bad; > > - } > > - > > - sz = tee_shm_get_size(shm); > > - > > - if (tee_shm_is_dynamic(shm)) { > > - struct page **pages; > > + /* > > + * If there are pages it's dynamically allocated shared memory (not > > + * from the reserved shared memory pool) and needs to be > > + * registered. > > + */ > > + pages = tee_shm_get_pages(shm, &page_count); > > + if (pages) { > > u64 *pages_list; > > - size_t page_num; > > - > > - pages = tee_shm_get_pages(shm, &page_num); > > - if (!pages || !page_num) { > > - arg->ret = TEEC_ERROR_OUT_OF_MEMORY; > > - goto bad; > > - } > > > > - pages_list = optee_allocate_pages_list(page_num); > > + pages_list = optee_allocate_pages_list(page_count); > > if (!pages_list) { > > arg->ret = TEEC_ERROR_OUT_OF_MEMORY; > > goto bad; > > } > > > > call_ctx->pages_list = pages_list; > > - call_ctx->num_entries = page_num; > > + call_ctx->num_entries = page_count; > > > > arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT | > > OPTEE_MSG_ATTR_NONCONTIG; > > @@ -752,17 +744,22 @@ static void handle_rpc_func_cmd_shm_alloc(struct tee_context *ctx, > > arg->params[0].u.tmem.buf_ptr = virt_to_phys(pages_list) | > > (tee_shm_get_page_offset(shm) & > > (OPTEE_MSG_NONCONTIG_PAGE_SIZE - 1)); > > - arg->params[0].u.tmem.size = tee_shm_get_size(shm); > > - arg->params[0].u.tmem.shm_ref = (unsigned long)shm; > > > > - optee_fill_pages_list(pages_list, pages, page_num, > > + optee_fill_pages_list(pages_list, pages, page_count, > > tee_shm_get_page_offset(shm)); > > } else { > > + phys_addr_t pa; > > + > > + if (tee_shm_get_pa(shm, 0, &pa)) { > > + arg->ret = TEEC_ERROR_BAD_PARAMETERS; > > + goto bad; > > + } > > + > > arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT; > > arg->params[0].u.tmem.buf_ptr = pa; > > - arg->params[0].u.tmem.size = sz; > > - arg->params[0].u.tmem.shm_ref = (unsigned long)shm; > > } > > + arg->params[0].u.tmem.size = tee_shm_get_size(shm); > > + arg->params[0].u.tmem.shm_ref = (unsigned long)shm; > > > > arg->ret = TEEC_SUCCESS; > > return; > > -- > > 2.34.1 > > ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2 2/2] optee: allocate shared memory with alloc_pages_exact() 2023-11-08 10:27 [PATCH v2 0/2] OP-TEE kernel private shared memory optimizations Jens Wiklander 2023-11-08 10:27 ` [PATCH v2 1/2] optee: add page list to kernel private shared memory Jens Wiklander @ 2023-11-08 10:27 ` Jens Wiklander 1 sibling, 0 replies; 5+ messages in thread From: Jens Wiklander @ 2023-11-08 10:27 UTC (permalink / raw) To: linux-kernel, op-tee Cc: Sumit Garg, Jerome Forissier, Shyam Saini, Jens Wiklander Allocate memory to share with the secure using alloc_pages_exact() instead of alloc_pages() for more efficient memory usage. Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org> --- drivers/tee/optee/core.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c index a425eca0173d..6303085a1b49 100644 --- a/drivers/tee/optee/core.c +++ b/drivers/tee/optee/core.c @@ -26,21 +26,19 @@ int optee_pool_op_alloc_helper(struct tee_shm_pool *pool, struct tee_shm *shm, size_t num_pages, unsigned long start)) { - unsigned int order = get_order(size); - unsigned int nr_pages = 1 << order; - struct page *page; + size_t nr_pages = roundup(size, PAGE_SIZE) / PAGE_SIZE; int rc = 0; /* * Ignore alignment since this is already going to be page aligned * and there's no need for any larger alignment. */ - page = alloc_pages(GFP_KERNEL | __GFP_ZERO, order); - if (!page) + shm->kaddr = alloc_pages_exact(nr_pages * PAGE_SIZE, + GFP_KERNEL | __GFP_ZERO); + if (!shm->kaddr) return -ENOMEM; - shm->kaddr = page_address(page); - shm->size = PAGE_SIZE << order; + shm->size = nr_pages * PAGE_SIZE; /* * If memory is registered immediately use a temporary page list @@ -66,7 +64,8 @@ int optee_pool_op_alloc_helper(struct tee_shm_pool *pool, struct tee_shm *shm, } for (i = 0; i < nr_pages; i++) - pages[i] = page + i; + pages[i] = virt_to_page((u8 *)shm->kaddr + + i * PAGE_SIZE); if (shm_register) { rc = shm_register(shm->ctx, shm, pages, nr_pages, @@ -79,12 +78,12 @@ int optee_pool_op_alloc_helper(struct tee_shm_pool *pool, struct tee_shm *shm, shm->num_pages = nr_pages; } } else { - shm->paddr = page_to_phys(page); + shm->paddr = virt_to_phys(shm->kaddr); } return 0; err: - free_pages((unsigned long)shm->kaddr, order); + free_pages_exact(shm->kaddr, shm->size); shm->kaddr = NULL; return rc; } @@ -95,7 +94,7 @@ void optee_pool_op_free_helper(struct tee_shm_pool *pool, struct tee_shm *shm, { if (shm_unregister) shm_unregister(shm->ctx, shm); - free_pages((unsigned long)shm->kaddr, get_order(shm->size)); + free_pages_exact(shm->kaddr, shm->size); shm->kaddr = NULL; kfree(shm->pages); shm->pages = NULL; -- 2.34.1 ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2023-11-13 17:13 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2023-11-08 10:27 [PATCH v2 0/2] OP-TEE kernel private shared memory optimizations Jens Wiklander 2023-11-08 10:27 ` [PATCH v2 1/2] optee: add page list to kernel private shared memory Jens Wiklander 2023-11-10 14:36 ` Sumit Garg 2023-11-13 17:13 ` Jens Wiklander 2023-11-08 10:27 ` [PATCH v2 2/2] optee: allocate shared memory with alloc_pages_exact() Jens Wiklander
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®