summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/tee/optee/call.c69
-rw-r--r--drivers/tee/optee/core.c2
-rw-r--r--drivers/tee/optee/optee_private.h4
3 files changed, 75 insertions, 0 deletions
diff --git a/drivers/tee/optee/call.c b/drivers/tee/optee/call.c
index e85860f6e057..a05e9e61105f 100644
--- a/drivers/tee/optee/call.c
+++ b/drivers/tee/optee/call.c
@@ -533,3 +533,72 @@ void optee_free_pages_list(void *list, size_t num_entries)
533 free_pages_exact(list, get_pages_list_size(num_entries)); 533 free_pages_exact(list, get_pages_list_size(num_entries));
534} 534}
535 535
536int optee_shm_register(struct tee_context *ctx, struct tee_shm *shm,
537 struct page **pages, size_t num_pages)
538{
539 struct tee_shm *shm_arg = NULL;
540 struct optee_msg_arg *msg_arg;
541 u64 *pages_list;
542 phys_addr_t msg_parg;
543 int rc = 0;
544
545 if (!num_pages)
546 return -EINVAL;
547
548 pages_list = optee_allocate_pages_list(num_pages);
549 if (!pages_list)
550 return -ENOMEM;
551
552 shm_arg = get_msg_arg(ctx, 1, &msg_arg, &msg_parg);
553 if (IS_ERR(shm_arg)) {
554 rc = PTR_ERR(shm_arg);
555 goto out;
556 }
557
558 optee_fill_pages_list(pages_list, pages, num_pages,
559 tee_shm_get_page_offset(shm));
560
561 msg_arg->cmd = OPTEE_MSG_CMD_REGISTER_SHM;
562 msg_arg->params->attr = OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT |
563 OPTEE_MSG_ATTR_NONCONTIG;
564 msg_arg->params->u.tmem.shm_ref = (unsigned long)shm;
565 msg_arg->params->u.tmem.size = tee_shm_get_size(shm);
566 /*
567 * In the least bits of msg_arg->params->u.tmem.buf_ptr we
568 * store buffer offset from 4k page, as described in OP-TEE ABI.
569 */
570 msg_arg->params->u.tmem.buf_ptr = virt_to_phys(pages_list) |
571 (tee_shm_get_page_offset(shm) & (OPTEE_MSG_NONCONTIG_PAGE_SIZE - 1));
572
573 if (optee_do_call_with_arg(ctx, msg_parg) ||
574 msg_arg->ret != TEEC_SUCCESS)
575 rc = -EINVAL;
576
577 tee_shm_free(shm_arg);
578out:
579 optee_free_pages_list(pages_list, num_pages);
580 return rc;
581}
582
583int optee_shm_unregister(struct tee_context *ctx, struct tee_shm *shm)
584{
585 struct tee_shm *shm_arg;
586 struct optee_msg_arg *msg_arg;
587 phys_addr_t msg_parg;
588 int rc = 0;
589
590 shm_arg = get_msg_arg(ctx, 1, &msg_arg, &msg_parg);
591 if (IS_ERR(shm_arg))
592 return PTR_ERR(shm_arg);
593
594 msg_arg->cmd = OPTEE_MSG_CMD_UNREGISTER_SHM;
595
596 msg_arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_RMEM_INPUT;
597 msg_arg->params[0].u.rmem.shm_ref = (unsigned long)shm;
598
599 if (optee_do_call_with_arg(ctx, msg_parg) ||
600 msg_arg->ret != TEEC_SUCCESS)
601 rc = -EINVAL;
602 tee_shm_free(shm_arg);
603 return rc;
604}
diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c
index edb6e4e9ef3a..eb407daaba03 100644
--- a/drivers/tee/optee/core.c
+++ b/drivers/tee/optee/core.c
@@ -267,6 +267,8 @@ static const struct tee_driver_ops optee_ops = {
267 .close_session = optee_close_session, 267 .close_session = optee_close_session,
268 .invoke_func = optee_invoke_func, 268 .invoke_func = optee_invoke_func,
269 .cancel_req = optee_cancel_req, 269 .cancel_req = optee_cancel_req,
270 .shm_register = optee_shm_register,
271 .shm_unregister = optee_shm_unregister,
270}; 272};
271 273
272static const struct tee_desc optee_desc = { 274static const struct tee_desc optee_desc = {
diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h
index b63213d09d68..d7bc77d95022 100644
--- a/drivers/tee/optee/optee_private.h
+++ b/drivers/tee/optee/optee_private.h
@@ -160,6 +160,10 @@ int optee_cancel_req(struct tee_context *ctx, u32 cancel_id, u32 session);
160void optee_enable_shm_cache(struct optee *optee); 160void optee_enable_shm_cache(struct optee *optee);
161void optee_disable_shm_cache(struct optee *optee); 161void optee_disable_shm_cache(struct optee *optee);
162 162
163int optee_shm_register(struct tee_context *ctx, struct tee_shm *shm,
164 struct page **pages, size_t num_pages);
165int optee_shm_unregister(struct tee_context *ctx, struct tee_shm *shm);
166
163int optee_from_msg_param(struct tee_param *params, size_t num_params, 167int optee_from_msg_param(struct tee_param *params, size_t num_params,
164 const struct optee_msg_param *msg_params); 168 const struct optee_msg_param *msg_params);
165int optee_to_msg_param(struct optee_msg_param *msg_params, size_t num_params, 169int optee_to_msg_param(struct optee_msg_param *msg_params, size_t num_params,