aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/tee/optee/core.c80
1 files changed, 49 insertions, 31 deletions
diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c
index 0842b6e6af82..48963eab32f5 100644
--- a/drivers/tee/optee/core.c
+++ b/drivers/tee/optee/core.c
@@ -419,9 +419,35 @@ static bool optee_msg_exchange_capabilities(optee_invoke_fn *invoke_fn,
419 return true; 419 return true;
420} 420}
421 421
422static struct tee_shm_pool *optee_config_dyn_shm(void)
423{
424 struct tee_shm_pool_mgr *priv_mgr;
425 struct tee_shm_pool_mgr *dmabuf_mgr;
426 void *rc;
427
428 rc = optee_shm_pool_alloc_pages();
429 if (IS_ERR(rc))
430 return rc;
431 priv_mgr = rc;
432
433 rc = optee_shm_pool_alloc_pages();
434 if (IS_ERR(rc)) {
435 tee_shm_pool_mgr_destroy(priv_mgr);
436 return rc;
437 }
438 dmabuf_mgr = rc;
439
440 rc = tee_shm_pool_alloc(priv_mgr, dmabuf_mgr);
441 if (IS_ERR(rc)) {
442 tee_shm_pool_mgr_destroy(priv_mgr);
443 tee_shm_pool_mgr_destroy(dmabuf_mgr);
444 }
445
446 return rc;
447}
448
422static struct tee_shm_pool * 449static struct tee_shm_pool *
423optee_config_shm_memremap(optee_invoke_fn *invoke_fn, void **memremaped_shm, 450optee_config_shm_memremap(optee_invoke_fn *invoke_fn, void **memremaped_shm)
424 u32 sec_caps)
425{ 451{
426 union { 452 union {
427 struct arm_smccc_res smccc; 453 struct arm_smccc_res smccc;
@@ -436,10 +462,11 @@ optee_config_shm_memremap(optee_invoke_fn *invoke_fn, void **memremaped_shm,
436 struct tee_shm_pool_mgr *priv_mgr; 462 struct tee_shm_pool_mgr *priv_mgr;
437 struct tee_shm_pool_mgr *dmabuf_mgr; 463 struct tee_shm_pool_mgr *dmabuf_mgr;
438 void *rc; 464 void *rc;
465 const int sz = OPTEE_SHM_NUM_PRIV_PAGES * PAGE_SIZE;
439 466
440 invoke_fn(OPTEE_SMC_GET_SHM_CONFIG, 0, 0, 0, 0, 0, 0, 0, &res.smccc); 467 invoke_fn(OPTEE_SMC_GET_SHM_CONFIG, 0, 0, 0, 0, 0, 0, 0, &res.smccc);
441 if (res.result.status != OPTEE_SMC_RETURN_OK) { 468 if (res.result.status != OPTEE_SMC_RETURN_OK) {
442 pr_info("shm service not available\n"); 469 pr_err("static shm service not available\n");
443 return ERR_PTR(-ENOENT); 470 return ERR_PTR(-ENOENT);
444 } 471 }
445 472
@@ -465,28 +492,15 @@ optee_config_shm_memremap(optee_invoke_fn *invoke_fn, void **memremaped_shm,
465 } 492 }
466 vaddr = (unsigned long)va; 493 vaddr = (unsigned long)va;
467 494
468 /* 495 rc = tee_shm_pool_mgr_alloc_res_mem(vaddr, paddr, sz,
469 * If OP-TEE can work with unregistered SHM, we will use own pool 496 3 /* 8 bytes aligned */);
470 * for private shm 497 if (IS_ERR(rc))
471 */ 498 goto err_memunmap;
472 if (sec_caps & OPTEE_SMC_SEC_CAP_DYNAMIC_SHM) { 499 priv_mgr = rc;
473 rc = optee_shm_pool_alloc_pages(); 500
474 if (IS_ERR(rc)) 501 vaddr += sz;
475 goto err_memunmap; 502 paddr += sz;
476 priv_mgr = rc; 503 size -= sz;
477 } else {
478 const size_t sz = OPTEE_SHM_NUM_PRIV_PAGES * PAGE_SIZE;
479
480 rc = tee_shm_pool_mgr_alloc_res_mem(vaddr, paddr, sz,
481 3 /* 8 bytes aligned */);
482 if (IS_ERR(rc))
483 goto err_memunmap;
484 priv_mgr = rc;
485
486 vaddr += sz;
487 paddr += sz;
488 size -= sz;
489 }
490 504
491 rc = tee_shm_pool_mgr_alloc_res_mem(vaddr, paddr, size, PAGE_SHIFT); 505 rc = tee_shm_pool_mgr_alloc_res_mem(vaddr, paddr, size, PAGE_SHIFT);
492 if (IS_ERR(rc)) 506 if (IS_ERR(rc))
@@ -552,7 +566,7 @@ static optee_invoke_fn *get_invoke_func(struct device_node *np)
552static struct optee *optee_probe(struct device_node *np) 566static struct optee *optee_probe(struct device_node *np)
553{ 567{
554 optee_invoke_fn *invoke_fn; 568 optee_invoke_fn *invoke_fn;
555 struct tee_shm_pool *pool; 569 struct tee_shm_pool *pool = ERR_PTR(-EINVAL);
556 struct optee *optee = NULL; 570 struct optee *optee = NULL;
557 void *memremaped_shm = NULL; 571 void *memremaped_shm = NULL;
558 struct tee_device *teedev; 572 struct tee_device *teedev;
@@ -581,13 +595,17 @@ static struct optee *optee_probe(struct device_node *np)
581 } 595 }
582 596
583 /* 597 /*
584 * We have no other option for shared memory, if secure world 598 * Try to use dynamic shared memory if possible
585 * doesn't have any reserved memory we can use we can't continue.
586 */ 599 */
587 if (!(sec_caps & OPTEE_SMC_SEC_CAP_HAVE_RESERVED_SHM)) 600 if (sec_caps & OPTEE_SMC_SEC_CAP_DYNAMIC_SHM)
588 return ERR_PTR(-EINVAL); 601 pool = optee_config_dyn_shm();
602
603 /*
604 * If dynamic shared memory is not available or failed - try static one
605 */
606 if (IS_ERR(pool) && (sec_caps & OPTEE_SMC_SEC_CAP_HAVE_RESERVED_SHM))
607 pool = optee_config_shm_memremap(invoke_fn, &memremaped_shm);
589 608
590 pool = optee_config_shm_memremap(invoke_fn, &memremaped_shm, sec_caps);
591 if (IS_ERR(pool)) 609 if (IS_ERR(pool))
592 return (void *)pool; 610 return (void *)pool;
593 611