diff options
-rw-r--r-- | drivers/tee/optee/call.c | 69 | ||||
-rw-r--r-- | drivers/tee/optee/core.c | 2 | ||||
-rw-r--r-- | drivers/tee/optee/optee_private.h | 4 |
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 | ||
536 | int 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); | ||
578 | out: | ||
579 | optee_free_pages_list(pages_list, num_pages); | ||
580 | return rc; | ||
581 | } | ||
582 | |||
583 | int 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 | ||
272 | static const struct tee_desc optee_desc = { | 274 | static 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); | |||
160 | void optee_enable_shm_cache(struct optee *optee); | 160 | void optee_enable_shm_cache(struct optee *optee); |
161 | void optee_disable_shm_cache(struct optee *optee); | 161 | void optee_disable_shm_cache(struct optee *optee); |
162 | 162 | ||
163 | int optee_shm_register(struct tee_context *ctx, struct tee_shm *shm, | ||
164 | struct page **pages, size_t num_pages); | ||
165 | int optee_shm_unregister(struct tee_context *ctx, struct tee_shm *shm); | ||
166 | |||
163 | int optee_from_msg_param(struct tee_param *params, size_t num_params, | 167 | int 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); |
165 | int optee_to_msg_param(struct optee_msg_param *msg_params, size_t num_params, | 169 | int optee_to_msg_param(struct optee_msg_param *msg_params, size_t num_params, |