1 /* 2 * Copyright (c) 2015, Linaro Limited 3 * 4 * This software is licensed under the terms of the GNU General Public 5 * License version 2, as published by the Free Software Foundation, and 6 * may be copied, distributed, and modified under those terms. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 */ 14 15 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 16 17 #include <linux/arm-smccc.h> 18 #include <linux/errno.h> 19 #include <linux/io.h> 20 #include <linux/module.h> 21 #include <linux/of.h> 22 #include <linux/of_platform.h> 23 #include <linux/platform_device.h> 24 #include <linux/slab.h> 25 #include <linux/string.h> 26 #include <linux/tee_drv.h> 27 #include <linux/types.h> 28 #include <linux/uaccess.h> 29 #include "optee_private.h" 30 #include "optee_smc.h" 31 #include "shm_pool.h" 32 33 #define DRIVER_NAME "optee" 34 35 #define OPTEE_SHM_NUM_PRIV_PAGES CONFIG_OPTEE_SHM_NUM_PRIV_PAGES 36 37 /** 38 * optee_from_msg_param() - convert from OPTEE_MSG parameters to 39 * struct tee_param 40 * @params: subsystem internal parameter representation 41 * @num_params: number of elements in the parameter arrays 42 * @msg_params: OPTEE_MSG parameters 43 * Returns 0 on success or <0 on failure 44 */ 45 int optee_from_msg_param(struct tee_param *params, size_t num_params, 46 const struct optee_msg_param *msg_params) 47 { 48 int rc; 49 size_t n; 50 struct tee_shm *shm; 51 phys_addr_t pa; 52 53 for (n = 0; n < num_params; n++) { 54 struct tee_param *p = params + n; 55 const struct optee_msg_param *mp = msg_params + n; 56 u32 attr = mp->attr & OPTEE_MSG_ATTR_TYPE_MASK; 57 58 switch (attr) { 59 case OPTEE_MSG_ATTR_TYPE_NONE: 60 p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE; 61 memset(&p->u, 0, sizeof(p->u)); 62 break; 63 case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT: 64 case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT: 65 case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT: 66 p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT + 67 attr - OPTEE_MSG_ATTR_TYPE_VALUE_INPUT; 68 p->u.value.a = mp->u.value.a; 69 p->u.value.b = mp->u.value.b; 70 p->u.value.c = mp->u.value.c; 71 break; 72 case OPTEE_MSG_ATTR_TYPE_TMEM_INPUT: 73 case OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT: 74 case OPTEE_MSG_ATTR_TYPE_TMEM_INOUT: 75 p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT + 76 attr - OPTEE_MSG_ATTR_TYPE_TMEM_INPUT; 77 p->u.memref.size = mp->u.tmem.size; 78 shm = (struct tee_shm *)(unsigned long) 79 mp->u.tmem.shm_ref; 80 if (!shm) { 81 p->u.memref.shm_offs = 0; 82 p->u.memref.shm = NULL; 83 break; 84 } 85 rc = tee_shm_get_pa(shm, 0, &pa); 86 if (rc) 87 return rc; 88 p->u.memref.shm_offs = mp->u.tmem.buf_ptr - pa; 89 p->u.memref.shm = shm; 90 91 /* Check that the memref is covered by the shm object */ 92 if (p->u.memref.size) { 93 size_t o = p->u.memref.shm_offs + 94 p->u.memref.size - 1; 95 96 rc = tee_shm_get_pa(shm, o, NULL); 97 if (rc) 98 return rc; 99 } 100 break; 101 case OPTEE_MSG_ATTR_TYPE_RMEM_INPUT: 102 case OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT: 103 case OPTEE_MSG_ATTR_TYPE_RMEM_INOUT: 104 p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT + 105 attr - OPTEE_MSG_ATTR_TYPE_RMEM_INPUT; 106 p->u.memref.size = mp->u.rmem.size; 107 shm = (struct tee_shm *)(unsigned long) 108 mp->u.rmem.shm_ref; 109 110 if (!shm) { 111 p->u.memref.shm_offs = 0; 112 p->u.memref.shm = NULL; 113 break; 114 } 115 p->u.memref.shm_offs = mp->u.rmem.offs; 116 p->u.memref.shm = shm; 117 118 break; 119 120 default: 121 return -EINVAL; 122 } 123 } 124 return 0; 125 } 126 127 static int to_msg_param_tmp_mem(struct optee_msg_param *mp, 128 const struct tee_param *p) 129 { 130 int rc; 131 phys_addr_t pa; 132 133 mp->attr = OPTEE_MSG_ATTR_TYPE_TMEM_INPUT + p->attr - 134 TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT; 135 136 mp->u.tmem.shm_ref = (unsigned long)p->u.memref.shm; 137 mp->u.tmem.size = p->u.memref.size; 138 139 if (!p->u.memref.shm) { 140 mp->u.tmem.buf_ptr = 0; 141 return 0; 142 } 143 144 rc = tee_shm_get_pa(p->u.memref.shm, p->u.memref.shm_offs, &pa); 145 if (rc) 146 return rc; 147 148 mp->u.tmem.buf_ptr = pa; 149 mp->attr |= OPTEE_MSG_ATTR_CACHE_PREDEFINED << 150 OPTEE_MSG_ATTR_CACHE_SHIFT; 151 152 return 0; 153 } 154 155 static int to_msg_param_reg_mem(struct optee_msg_param *mp, 156 const struct tee_param *p) 157 { 158 mp->attr = OPTEE_MSG_ATTR_TYPE_RMEM_INPUT + p->attr - 159 TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT; 160 161 mp->u.rmem.shm_ref = (unsigned long)p->u.memref.shm; 162 mp->u.rmem.size = p->u.memref.size; 163 mp->u.rmem.offs = p->u.memref.shm_offs; 164 return 0; 165 } 166 167 /** 168 * optee_to_msg_param() - convert from struct tee_params to OPTEE_MSG parameters 169 * @msg_params: OPTEE_MSG parameters 170 * @num_params: number of elements in the parameter arrays 171 * @params: subsystem itnernal parameter representation 172 * Returns 0 on success or <0 on failure 173 */ 174 int optee_to_msg_param(struct optee_msg_param *msg_params, size_t num_params, 175 const struct tee_param *params) 176 { 177 int rc; 178 size_t n; 179 180 for (n = 0; n < num_params; n++) { 181 const struct tee_param *p = params + n; 182 struct optee_msg_param *mp = msg_params + n; 183 184 switch (p->attr) { 185 case TEE_IOCTL_PARAM_ATTR_TYPE_NONE: 186 mp->attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE; 187 memset(&mp->u, 0, sizeof(mp->u)); 188 break; 189 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT: 190 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT: 191 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT: 192 mp->attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT + p->attr - 193 TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT; 194 mp->u.value.a = p->u.value.a; 195 mp->u.value.b = p->u.value.b; 196 mp->u.value.c = p->u.value.c; 197 break; 198 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT: 199 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT: 200 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT: 201 if (tee_shm_is_registered(p->u.memref.shm)) 202 rc = to_msg_param_reg_mem(mp, p); 203 else 204 rc = to_msg_param_tmp_mem(mp, p); 205 if (rc) 206 return rc; 207 break; 208 default: 209 return -EINVAL; 210 } 211 } 212 return 0; 213 } 214 215 static void optee_get_version(struct tee_device *teedev, 216 struct tee_ioctl_version_data *vers) 217 { 218 struct tee_ioctl_version_data v = { 219 .impl_id = TEE_IMPL_ID_OPTEE, 220 .impl_caps = TEE_OPTEE_CAP_TZ, 221 .gen_caps = TEE_GEN_CAP_GP, 222 }; 223 struct optee *optee = tee_get_drvdata(teedev); 224 225 if (optee->sec_caps & OPTEE_SMC_SEC_CAP_DYNAMIC_SHM) 226 v.gen_caps |= TEE_GEN_CAP_REG_MEM; 227 *vers = v; 228 } 229 230 static int optee_open(struct tee_context *ctx) 231 { 232 struct optee_context_data *ctxdata; 233 struct tee_device *teedev = ctx->teedev; 234 struct optee *optee = tee_get_drvdata(teedev); 235 236 ctxdata = kzalloc(sizeof(*ctxdata), GFP_KERNEL); 237 if (!ctxdata) 238 return -ENOMEM; 239 240 if (teedev == optee->supp_teedev) { 241 bool busy = true; 242 243 mutex_lock(&optee->supp.mutex); 244 if (!optee->supp.ctx) { 245 busy = false; 246 optee->supp.ctx = ctx; 247 } 248 mutex_unlock(&optee->supp.mutex); 249 if (busy) { 250 kfree(ctxdata); 251 return -EBUSY; 252 } 253 } 254 255 mutex_init(&ctxdata->mutex); 256 INIT_LIST_HEAD(&ctxdata->sess_list); 257 258 ctx->data = ctxdata; 259 return 0; 260 } 261 262 static void optee_release(struct tee_context *ctx) 263 { 264 struct optee_context_data *ctxdata = ctx->data; 265 struct tee_device *teedev = ctx->teedev; 266 struct optee *optee = tee_get_drvdata(teedev); 267 struct tee_shm *shm; 268 struct optee_msg_arg *arg = NULL; 269 phys_addr_t parg; 270 struct optee_session *sess; 271 struct optee_session *sess_tmp; 272 273 if (!ctxdata) 274 return; 275 276 shm = tee_shm_alloc(ctx, sizeof(struct optee_msg_arg), TEE_SHM_MAPPED); 277 if (!IS_ERR(shm)) { 278 arg = tee_shm_get_va(shm, 0); 279 /* 280 * If va2pa fails for some reason, we can't call into 281 * secure world, only free the memory. Secure OS will leak 282 * sessions and finally refuse more sessions, but we will 283 * at least let normal world reclaim its memory. 284 */ 285 if (!IS_ERR(arg)) 286 if (tee_shm_va2pa(shm, arg, &parg)) 287 arg = NULL; /* prevent usage of parg below */ 288 } 289 290 list_for_each_entry_safe(sess, sess_tmp, &ctxdata->sess_list, 291 list_node) { 292 list_del(&sess->list_node); 293 if (!IS_ERR_OR_NULL(arg)) { 294 memset(arg, 0, sizeof(*arg)); 295 arg->cmd = OPTEE_MSG_CMD_CLOSE_SESSION; 296 arg->session = sess->session_id; 297 optee_do_call_with_arg(ctx, parg); 298 } 299 kfree(sess); 300 } 301 kfree(ctxdata); 302 303 if (!IS_ERR(shm)) 304 tee_shm_free(shm); 305 306 ctx->data = NULL; 307 308 if (teedev == optee->supp_teedev) 309 optee_supp_release(&optee->supp); 310 } 311 312 static const struct tee_driver_ops optee_ops = { 313 .get_version = optee_get_version, 314 .open = optee_open, 315 .release = optee_release, 316 .open_session = optee_open_session, 317 .close_session = optee_close_session, 318 .invoke_func = optee_invoke_func, 319 .cancel_req = optee_cancel_req, 320 .shm_register = optee_shm_register, 321 .shm_unregister = optee_shm_unregister, 322 }; 323 324 static const struct tee_desc optee_desc = { 325 .name = DRIVER_NAME "-clnt", 326 .ops = &optee_ops, 327 .owner = THIS_MODULE, 328 }; 329 330 static const struct tee_driver_ops optee_supp_ops = { 331 .get_version = optee_get_version, 332 .open = optee_open, 333 .release = optee_release, 334 .supp_recv = optee_supp_recv, 335 .supp_send = optee_supp_send, 336 .shm_register = optee_shm_register_supp, 337 .shm_unregister = optee_shm_unregister_supp, 338 }; 339 340 static const struct tee_desc optee_supp_desc = { 341 .name = DRIVER_NAME "-supp", 342 .ops = &optee_supp_ops, 343 .owner = THIS_MODULE, 344 .flags = TEE_DESC_PRIVILEGED, 345 }; 346 347 static bool optee_msg_api_uid_is_optee_api(optee_invoke_fn *invoke_fn) 348 { 349 struct arm_smccc_res res; 350 351 invoke_fn(OPTEE_SMC_CALLS_UID, 0, 0, 0, 0, 0, 0, 0, &res); 352 353 if (res.a0 == OPTEE_MSG_UID_0 && res.a1 == OPTEE_MSG_UID_1 && 354 res.a2 == OPTEE_MSG_UID_2 && res.a3 == OPTEE_MSG_UID_3) 355 return true; 356 return false; 357 } 358 359 static void optee_msg_get_os_revision(optee_invoke_fn *invoke_fn) 360 { 361 union { 362 struct arm_smccc_res smccc; 363 struct optee_smc_call_get_os_revision_result result; 364 } res = { 365 .result = { 366 .build_id = 0 367 } 368 }; 369 370 invoke_fn(OPTEE_SMC_CALL_GET_OS_REVISION, 0, 0, 0, 0, 0, 0, 0, 371 &res.smccc); 372 373 if (res.result.build_id) 374 pr_info("revision %lu.%lu (%08lx)", res.result.major, 375 res.result.minor, res.result.build_id); 376 else 377 pr_info("revision %lu.%lu", res.result.major, res.result.minor); 378 } 379 380 static bool optee_msg_api_revision_is_compatible(optee_invoke_fn *invoke_fn) 381 { 382 union { 383 struct arm_smccc_res smccc; 384 struct optee_smc_calls_revision_result result; 385 } res; 386 387 invoke_fn(OPTEE_SMC_CALLS_REVISION, 0, 0, 0, 0, 0, 0, 0, &res.smccc); 388 389 if (res.result.major == OPTEE_MSG_REVISION_MAJOR && 390 (int)res.result.minor >= OPTEE_MSG_REVISION_MINOR) 391 return true; 392 return false; 393 } 394 395 static bool optee_msg_exchange_capabilities(optee_invoke_fn *invoke_fn, 396 u32 *sec_caps) 397 { 398 union { 399 struct arm_smccc_res smccc; 400 struct optee_smc_exchange_capabilities_result result; 401 } res; 402 u32 a1 = 0; 403 404 /* 405 * TODO This isn't enough to tell if it's UP system (from kernel 406 * point of view) or not, is_smp() returns the the information 407 * needed, but can't be called directly from here. 408 */ 409 if (!IS_ENABLED(CONFIG_SMP) || nr_cpu_ids == 1) 410 a1 |= OPTEE_SMC_NSEC_CAP_UNIPROCESSOR; 411 412 invoke_fn(OPTEE_SMC_EXCHANGE_CAPABILITIES, a1, 0, 0, 0, 0, 0, 0, 413 &res.smccc); 414 415 if (res.result.status != OPTEE_SMC_RETURN_OK) 416 return false; 417 418 *sec_caps = res.result.capabilities; 419 return true; 420 } 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 449 static struct tee_shm_pool * 450 optee_config_shm_memremap(optee_invoke_fn *invoke_fn, void **memremaped_shm) 451 { 452 union { 453 struct arm_smccc_res smccc; 454 struct optee_smc_get_shm_config_result result; 455 } res; 456 unsigned long vaddr; 457 phys_addr_t paddr; 458 size_t size; 459 phys_addr_t begin; 460 phys_addr_t end; 461 void *va; 462 struct tee_shm_pool_mgr *priv_mgr; 463 struct tee_shm_pool_mgr *dmabuf_mgr; 464 void *rc; 465 const int sz = OPTEE_SHM_NUM_PRIV_PAGES * PAGE_SIZE; 466 467 invoke_fn(OPTEE_SMC_GET_SHM_CONFIG, 0, 0, 0, 0, 0, 0, 0, &res.smccc); 468 if (res.result.status != OPTEE_SMC_RETURN_OK) { 469 pr_err("static shm service not available\n"); 470 return ERR_PTR(-ENOENT); 471 } 472 473 if (res.result.settings != OPTEE_SMC_SHM_CACHED) { 474 pr_err("only normal cached shared memory supported\n"); 475 return ERR_PTR(-EINVAL); 476 } 477 478 begin = roundup(res.result.start, PAGE_SIZE); 479 end = rounddown(res.result.start + res.result.size, PAGE_SIZE); 480 paddr = begin; 481 size = end - begin; 482 483 if (size < 2 * OPTEE_SHM_NUM_PRIV_PAGES * PAGE_SIZE) { 484 pr_err("too small shared memory area\n"); 485 return ERR_PTR(-EINVAL); 486 } 487 488 va = memremap(paddr, size, MEMREMAP_WB); 489 if (!va) { 490 pr_err("shared memory ioremap failed\n"); 491 return ERR_PTR(-EINVAL); 492 } 493 vaddr = (unsigned long)va; 494 495 rc = tee_shm_pool_mgr_alloc_res_mem(vaddr, paddr, sz, 496 3 /* 8 bytes aligned */); 497 if (IS_ERR(rc)) 498 goto err_memunmap; 499 priv_mgr = rc; 500 501 vaddr += sz; 502 paddr += sz; 503 size -= sz; 504 505 rc = tee_shm_pool_mgr_alloc_res_mem(vaddr, paddr, size, PAGE_SHIFT); 506 if (IS_ERR(rc)) 507 goto err_free_priv_mgr; 508 dmabuf_mgr = rc; 509 510 rc = tee_shm_pool_alloc(priv_mgr, dmabuf_mgr); 511 if (IS_ERR(rc)) 512 goto err_free_dmabuf_mgr; 513 514 *memremaped_shm = va; 515 516 return rc; 517 518 err_free_dmabuf_mgr: 519 tee_shm_pool_mgr_destroy(dmabuf_mgr); 520 err_free_priv_mgr: 521 tee_shm_pool_mgr_destroy(priv_mgr); 522 err_memunmap: 523 memunmap(va); 524 return rc; 525 } 526 527 /* Simple wrapper functions to be able to use a function pointer */ 528 static void optee_smccc_smc(unsigned long a0, unsigned long a1, 529 unsigned long a2, unsigned long a3, 530 unsigned long a4, unsigned long a5, 531 unsigned long a6, unsigned long a7, 532 struct arm_smccc_res *res) 533 { 534 arm_smccc_smc(a0, a1, a2, a3, a4, a5, a6, a7, res); 535 } 536 537 static void optee_smccc_hvc(unsigned long a0, unsigned long a1, 538 unsigned long a2, unsigned long a3, 539 unsigned long a4, unsigned long a5, 540 unsigned long a6, unsigned long a7, 541 struct arm_smccc_res *res) 542 { 543 arm_smccc_hvc(a0, a1, a2, a3, a4, a5, a6, a7, res); 544 } 545 546 static optee_invoke_fn *get_invoke_func(struct device_node *np) 547 { 548 const char *method; 549 550 pr_info("probing for conduit method from DT.\n"); 551 552 if (of_property_read_string(np, "method", &method)) { 553 pr_warn("missing \"method\" property\n"); 554 return ERR_PTR(-ENXIO); 555 } 556 557 if (!strcmp("hvc", method)) 558 return optee_smccc_hvc; 559 else if (!strcmp("smc", method)) 560 return optee_smccc_smc; 561 562 pr_warn("invalid \"method\" property: %s\n", method); 563 return ERR_PTR(-EINVAL); 564 } 565 566 static struct optee *optee_probe(struct device_node *np) 567 { 568 optee_invoke_fn *invoke_fn; 569 struct tee_shm_pool *pool = ERR_PTR(-EINVAL); 570 struct optee *optee = NULL; 571 void *memremaped_shm = NULL; 572 struct tee_device *teedev; 573 u32 sec_caps; 574 int rc; 575 576 invoke_fn = get_invoke_func(np); 577 if (IS_ERR(invoke_fn)) 578 return (void *)invoke_fn; 579 580 if (!optee_msg_api_uid_is_optee_api(invoke_fn)) { 581 pr_warn("api uid mismatch\n"); 582 return ERR_PTR(-EINVAL); 583 } 584 585 optee_msg_get_os_revision(invoke_fn); 586 587 if (!optee_msg_api_revision_is_compatible(invoke_fn)) { 588 pr_warn("api revision mismatch\n"); 589 return ERR_PTR(-EINVAL); 590 } 591 592 if (!optee_msg_exchange_capabilities(invoke_fn, &sec_caps)) { 593 pr_warn("capabilities mismatch\n"); 594 return ERR_PTR(-EINVAL); 595 } 596 597 /* 598 * Try to use dynamic shared memory if possible 599 */ 600 if (sec_caps & OPTEE_SMC_SEC_CAP_DYNAMIC_SHM) 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); 608 609 if (IS_ERR(pool)) 610 return (void *)pool; 611 612 optee = kzalloc(sizeof(*optee), GFP_KERNEL); 613 if (!optee) { 614 rc = -ENOMEM; 615 goto err; 616 } 617 618 optee->invoke_fn = invoke_fn; 619 optee->sec_caps = sec_caps; 620 621 teedev = tee_device_alloc(&optee_desc, NULL, pool, optee); 622 if (IS_ERR(teedev)) { 623 rc = PTR_ERR(teedev); 624 goto err; 625 } 626 optee->teedev = teedev; 627 628 teedev = tee_device_alloc(&optee_supp_desc, NULL, pool, optee); 629 if (IS_ERR(teedev)) { 630 rc = PTR_ERR(teedev); 631 goto err; 632 } 633 optee->supp_teedev = teedev; 634 635 rc = tee_device_register(optee->teedev); 636 if (rc) 637 goto err; 638 639 rc = tee_device_register(optee->supp_teedev); 640 if (rc) 641 goto err; 642 643 mutex_init(&optee->call_queue.mutex); 644 INIT_LIST_HEAD(&optee->call_queue.waiters); 645 optee_wait_queue_init(&optee->wait_queue); 646 optee_supp_init(&optee->supp); 647 optee->memremaped_shm = memremaped_shm; 648 optee->pool = pool; 649 650 optee_enable_shm_cache(optee); 651 652 if (optee->sec_caps & OPTEE_SMC_SEC_CAP_DYNAMIC_SHM) 653 pr_info("dynamic shared memory is enabled\n"); 654 655 rc = optee_enumerate_devices(); 656 if (rc) 657 goto err; 658 659 pr_info("initialized driver\n"); 660 return optee; 661 err: 662 if (optee) { 663 /* 664 * tee_device_unregister() is safe to call even if the 665 * devices hasn't been registered with 666 * tee_device_register() yet. 667 */ 668 tee_device_unregister(optee->supp_teedev); 669 tee_device_unregister(optee->teedev); 670 kfree(optee); 671 } 672 if (pool) 673 tee_shm_pool_free(pool); 674 if (memremaped_shm) 675 memunmap(memremaped_shm); 676 return ERR_PTR(rc); 677 } 678 679 static void optee_remove(struct optee *optee) 680 { 681 /* 682 * Ask OP-TEE to free all cached shared memory objects to decrease 683 * reference counters and also avoid wild pointers in secure world 684 * into the old shared memory range. 685 */ 686 optee_disable_shm_cache(optee); 687 688 /* 689 * The two devices has to be unregistered before we can free the 690 * other resources. 691 */ 692 tee_device_unregister(optee->supp_teedev); 693 tee_device_unregister(optee->teedev); 694 695 tee_shm_pool_free(optee->pool); 696 if (optee->memremaped_shm) 697 memunmap(optee->memremaped_shm); 698 optee_wait_queue_exit(&optee->wait_queue); 699 optee_supp_uninit(&optee->supp); 700 mutex_destroy(&optee->call_queue.mutex); 701 702 kfree(optee); 703 } 704 705 static const struct of_device_id optee_match[] = { 706 { .compatible = "linaro,optee-tz" }, 707 {}, 708 }; 709 710 static struct optee *optee_svc; 711 712 static int __init optee_driver_init(void) 713 { 714 struct device_node *fw_np; 715 struct device_node *np; 716 struct optee *optee; 717 718 /* Node is supposed to be below /firmware */ 719 fw_np = of_find_node_by_name(NULL, "firmware"); 720 if (!fw_np) 721 return -ENODEV; 722 723 np = of_find_matching_node(fw_np, optee_match); 724 if (!np || !of_device_is_available(np)) { 725 of_node_put(np); 726 return -ENODEV; 727 } 728 729 optee = optee_probe(np); 730 of_node_put(np); 731 732 if (IS_ERR(optee)) 733 return PTR_ERR(optee); 734 735 optee_svc = optee; 736 737 return 0; 738 } 739 module_init(optee_driver_init); 740 741 static void __exit optee_driver_exit(void) 742 { 743 struct optee *optee = optee_svc; 744 745 optee_svc = NULL; 746 if (optee) 747 optee_remove(optee); 748 } 749 module_exit(optee_driver_exit); 750 751 MODULE_AUTHOR("Linaro"); 752 MODULE_DESCRIPTION("OP-TEE driver"); 753 MODULE_SUPPORTED_DEVICE(""); 754 MODULE_VERSION("1.0"); 755 MODULE_LICENSE("GPL v2"); 756