diff options
| -rw-r--r-- | drivers/tee/optee/core.c | 80 |
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 | ||
| 422 | static 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 | |||
| 422 | static struct tee_shm_pool * | 449 | static struct tee_shm_pool * |
| 423 | optee_config_shm_memremap(optee_invoke_fn *invoke_fn, void **memremaped_shm, | 450 | optee_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) | |||
| 552 | static struct optee *optee_probe(struct device_node *np) | 566 | static 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 | ||
