1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2020-2023, Arm Limited. 4 */ 5 #include <bench.h> 6 #include <crypto/crypto.h> 7 #include <initcall.h> 8 #include <kernel/boot.h> 9 #include <kernel/embedded_ts.h> 10 #include <kernel/ldelf_loader.h> 11 #include <kernel/secure_partition.h> 12 #include <kernel/spinlock.h> 13 #include <kernel/spmc_sp_handler.h> 14 #include <kernel/thread_private.h> 15 #include <kernel/thread_spmc.h> 16 #include <kernel/tpm.h> 17 #include <kernel/ts_store.h> 18 #include <ldelf.h> 19 #include <libfdt.h> 20 #include <mm/core_mmu.h> 21 #include <mm/fobj.h> 22 #include <mm/mobj.h> 23 #include <mm/vm.h> 24 #include <optee_ffa.h> 25 #include <stdio.h> 26 #include <string.h> 27 #include <tee_api_types.h> 28 #include <tee/uuid.h> 29 #include <trace.h> 30 #include <types_ext.h> 31 #include <utee_defines.h> 32 #include <util.h> 33 #include <zlib.h> 34 35 #define SP_MANIFEST_ATTR_READ BIT(0) 36 #define SP_MANIFEST_ATTR_WRITE BIT(1) 37 #define SP_MANIFEST_ATTR_EXEC BIT(2) 38 #define SP_MANIFEST_ATTR_NSEC BIT(3) 39 40 #define SP_MANIFEST_ATTR_RO (SP_MANIFEST_ATTR_READ) 41 #define SP_MANIFEST_ATTR_RW (SP_MANIFEST_ATTR_READ | \ 42 SP_MANIFEST_ATTR_WRITE) 43 #define SP_MANIFEST_ATTR_RX (SP_MANIFEST_ATTR_READ | \ 44 SP_MANIFEST_ATTR_EXEC) 45 #define SP_MANIFEST_ATTR_RWX (SP_MANIFEST_ATTR_READ | \ 46 SP_MANIFEST_ATTR_WRITE | \ 47 SP_MANIFEST_ATTR_EXEC) 48 49 #define SP_PKG_HEADER_MAGIC (0x474b5053) 50 #define SP_PKG_HEADER_VERSION_V1 (0x1) 51 #define SP_PKG_HEADER_VERSION_V2 (0x2) 52 53 struct sp_pkg_header { 54 uint32_t magic; 55 uint32_t version; 56 uint32_t pm_offset; 57 uint32_t pm_size; 58 uint32_t img_offset; 59 uint32_t img_size; 60 }; 61 62 struct fip_sp_head fip_sp_list = STAILQ_HEAD_INITIALIZER(fip_sp_list); 63 64 static const struct ts_ops sp_ops; 65 66 /* List that holds all of the loaded SP's */ 67 static struct sp_sessions_head open_sp_sessions = 68 TAILQ_HEAD_INITIALIZER(open_sp_sessions); 69 70 static const struct embedded_ts *find_secure_partition(const TEE_UUID *uuid) 71 { 72 const struct sp_image *sp = NULL; 73 const struct fip_sp *fip_sp = NULL; 74 75 for_each_secure_partition(sp) { 76 if (!memcmp(&sp->image.uuid, uuid, sizeof(*uuid))) 77 return &sp->image; 78 } 79 80 for_each_fip_sp(fip_sp) { 81 if (!memcmp(&fip_sp->sp_img.image.uuid, uuid, sizeof(*uuid))) 82 return &fip_sp->sp_img.image; 83 } 84 85 return NULL; 86 } 87 88 bool is_sp_ctx(struct ts_ctx *ctx) 89 { 90 return ctx && (ctx->ops == &sp_ops); 91 } 92 93 static void set_sp_ctx_ops(struct ts_ctx *ctx) 94 { 95 ctx->ops = &sp_ops; 96 } 97 98 TEE_Result sp_find_session_id(const TEE_UUID *uuid, uint32_t *session_id) 99 { 100 struct sp_session *s = NULL; 101 102 TAILQ_FOREACH(s, &open_sp_sessions, link) { 103 if (!memcmp(&s->ts_sess.ctx->uuid, uuid, sizeof(*uuid))) { 104 if (s->state == sp_dead) 105 return TEE_ERROR_TARGET_DEAD; 106 107 *session_id = s->endpoint_id; 108 return TEE_SUCCESS; 109 } 110 } 111 112 return TEE_ERROR_ITEM_NOT_FOUND; 113 } 114 115 struct sp_session *sp_get_session(uint32_t session_id) 116 { 117 struct sp_session *s = NULL; 118 119 TAILQ_FOREACH(s, &open_sp_sessions, link) { 120 if (s->endpoint_id == session_id) 121 return s; 122 } 123 124 return NULL; 125 } 126 127 TEE_Result sp_partition_info_get_all(struct ffa_partition_info *fpi, 128 size_t *elem_count) 129 { 130 size_t in_count = *elem_count; 131 struct sp_session *s = NULL; 132 size_t count = 0; 133 134 TAILQ_FOREACH(s, &open_sp_sessions, link) { 135 if (s->state == sp_dead) 136 continue; 137 if (count < in_count) { 138 spmc_fill_partition_entry(fpi, s->endpoint_id, 1); 139 fpi++; 140 } 141 count++; 142 } 143 144 *elem_count = count; 145 if (count > in_count) 146 return TEE_ERROR_SHORT_BUFFER; 147 148 return TEE_SUCCESS; 149 } 150 151 bool sp_has_exclusive_access(struct sp_mem_map_region *mem, 152 struct user_mode_ctx *uctx) 153 { 154 /* 155 * Check that we have access to the region if it is supposed to be 156 * mapped to the current context. 157 */ 158 if (uctx) { 159 struct vm_region *region = NULL; 160 161 /* Make sure that each mobj belongs to the SP */ 162 TAILQ_FOREACH(region, &uctx->vm_info.regions, link) { 163 if (region->mobj == mem->mobj) 164 break; 165 } 166 167 if (!region) 168 return false; 169 } 170 171 /* Check that it is not shared with another SP */ 172 return !sp_mem_is_shared(mem); 173 } 174 175 static uint16_t new_session_id(struct sp_sessions_head *open_sessions) 176 { 177 struct sp_session *last = NULL; 178 uint16_t id = SPMC_ENDPOINT_ID + 1; 179 180 last = TAILQ_LAST(open_sessions, sp_sessions_head); 181 if (last) 182 id = last->endpoint_id + 1; 183 184 assert(id > SPMC_ENDPOINT_ID); 185 return id; 186 } 187 188 static TEE_Result sp_create_ctx(const TEE_UUID *uuid, struct sp_session *s) 189 { 190 TEE_Result res = TEE_SUCCESS; 191 struct sp_ctx *spc = NULL; 192 193 /* Register context */ 194 spc = calloc(1, sizeof(struct sp_ctx)); 195 if (!spc) 196 return TEE_ERROR_OUT_OF_MEMORY; 197 198 spc->open_session = s; 199 s->ts_sess.ctx = &spc->ts_ctx; 200 spc->ts_ctx.uuid = *uuid; 201 202 res = vm_info_init(&spc->uctx, &spc->ts_ctx); 203 if (res) 204 goto err; 205 206 set_sp_ctx_ops(&spc->ts_ctx); 207 208 return TEE_SUCCESS; 209 210 err: 211 free(spc); 212 return res; 213 } 214 215 static TEE_Result sp_create_session(struct sp_sessions_head *open_sessions, 216 const TEE_UUID *uuid, 217 struct sp_session **sess) 218 { 219 TEE_Result res = TEE_SUCCESS; 220 struct sp_session *s = calloc(1, sizeof(struct sp_session)); 221 222 if (!s) 223 return TEE_ERROR_OUT_OF_MEMORY; 224 225 s->endpoint_id = new_session_id(open_sessions); 226 if (!s->endpoint_id) { 227 res = TEE_ERROR_OVERFLOW; 228 goto err; 229 } 230 231 DMSG("Loading Secure Partition %pUl", (void *)uuid); 232 res = sp_create_ctx(uuid, s); 233 if (res) 234 goto err; 235 236 TAILQ_INSERT_TAIL(open_sessions, s, link); 237 *sess = s; 238 return TEE_SUCCESS; 239 240 err: 241 free(s); 242 return res; 243 } 244 245 static TEE_Result sp_init_set_registers(struct sp_ctx *ctx) 246 { 247 struct thread_ctx_regs *sp_regs = &ctx->sp_regs; 248 249 memset(sp_regs, 0, sizeof(*sp_regs)); 250 sp_regs->sp = ctx->uctx.stack_ptr; 251 sp_regs->pc = ctx->uctx.entry_func; 252 253 return TEE_SUCCESS; 254 } 255 256 TEE_Result sp_map_shared(struct sp_session *s, 257 struct sp_mem_receiver *receiver, 258 struct sp_mem *smem, 259 uint64_t *va) 260 { 261 TEE_Result res = TEE_SUCCESS; 262 struct sp_ctx *ctx = NULL; 263 uint32_t perm = TEE_MATTR_UR; 264 struct sp_mem_map_region *reg = NULL; 265 266 ctx = to_sp_ctx(s->ts_sess.ctx); 267 268 /* Get the permission */ 269 if (receiver->perm.perm & FFA_MEM_ACC_EXE) 270 perm |= TEE_MATTR_UX; 271 272 if (receiver->perm.perm & FFA_MEM_ACC_RW) { 273 if (receiver->perm.perm & FFA_MEM_ACC_EXE) 274 return TEE_ERROR_ACCESS_CONFLICT; 275 276 perm |= TEE_MATTR_UW; 277 } 278 /* 279 * Currently we don't support passing a va. We can't guarantee that the 280 * full region will be mapped in a contiguous region. A smem->region can 281 * have multiple mobj for one share. Currently there doesn't seem to be 282 * an option to guarantee that these will be mapped in a contiguous va 283 * space. 284 */ 285 if (*va) 286 return TEE_ERROR_NOT_SUPPORTED; 287 288 SLIST_FOREACH(reg, &smem->regions, link) { 289 res = vm_map(&ctx->uctx, va, reg->page_count * SMALL_PAGE_SIZE, 290 perm, 0, reg->mobj, reg->page_offset); 291 292 if (res != TEE_SUCCESS) { 293 EMSG("Failed to map memory region %#"PRIx32, res); 294 return res; 295 } 296 } 297 return TEE_SUCCESS; 298 } 299 300 TEE_Result sp_unmap_ffa_regions(struct sp_session *s, struct sp_mem *smem) 301 { 302 TEE_Result res = TEE_SUCCESS; 303 vaddr_t vaddr = 0; 304 size_t len = 0; 305 struct sp_ctx *ctx = to_sp_ctx(s->ts_sess.ctx); 306 struct sp_mem_map_region *reg = NULL; 307 308 SLIST_FOREACH(reg, &smem->regions, link) { 309 vaddr = (vaddr_t)sp_mem_get_va(&ctx->uctx, reg->page_offset, 310 reg->mobj); 311 len = reg->page_count * SMALL_PAGE_SIZE; 312 313 res = vm_unmap(&ctx->uctx, vaddr, len); 314 if (res != TEE_SUCCESS) 315 return res; 316 } 317 318 return TEE_SUCCESS; 319 } 320 321 static TEE_Result sp_open_session(struct sp_session **sess, 322 struct sp_sessions_head *open_sessions, 323 const TEE_UUID *uuid) 324 { 325 TEE_Result res = TEE_SUCCESS; 326 struct sp_session *s = NULL; 327 struct sp_ctx *ctx = NULL; 328 329 if (!find_secure_partition(uuid)) 330 return TEE_ERROR_ITEM_NOT_FOUND; 331 332 res = sp_create_session(open_sessions, uuid, &s); 333 if (res != TEE_SUCCESS) { 334 DMSG("sp_create_session failed %#"PRIx32, res); 335 return res; 336 } 337 338 ctx = to_sp_ctx(s->ts_sess.ctx); 339 assert(ctx); 340 if (!ctx) 341 return TEE_ERROR_TARGET_DEAD; 342 *sess = s; 343 344 ts_push_current_session(&s->ts_sess); 345 /* Load the SP using ldelf. */ 346 ldelf_load_ldelf(&ctx->uctx); 347 res = ldelf_init_with_ldelf(&s->ts_sess, &ctx->uctx); 348 349 if (res != TEE_SUCCESS) { 350 EMSG("Failed. loading SP using ldelf %#"PRIx32, res); 351 ts_pop_current_session(); 352 return TEE_ERROR_TARGET_DEAD; 353 } 354 355 /* Make the SP ready for its first run */ 356 s->state = sp_idle; 357 s->caller_id = 0; 358 sp_init_set_registers(ctx); 359 ts_pop_current_session(); 360 361 return TEE_SUCCESS; 362 } 363 364 static TEE_Result sp_dt_get_u64(const void *fdt, int node, const char *property, 365 uint64_t *value) 366 { 367 const fdt64_t *p = NULL; 368 int len = 0; 369 370 p = fdt_getprop(fdt, node, property, &len); 371 if (!p || len != sizeof(*p)) 372 return TEE_ERROR_ITEM_NOT_FOUND; 373 374 *value = fdt64_ld(p); 375 376 return TEE_SUCCESS; 377 } 378 379 static TEE_Result sp_dt_get_u32(const void *fdt, int node, const char *property, 380 uint32_t *value) 381 { 382 const fdt32_t *p = NULL; 383 int len = 0; 384 385 p = fdt_getprop(fdt, node, property, &len); 386 if (!p || len != sizeof(*p)) 387 return TEE_ERROR_ITEM_NOT_FOUND; 388 389 *value = fdt32_to_cpu(*p); 390 391 return TEE_SUCCESS; 392 } 393 394 static TEE_Result sp_dt_get_uuid(const void *fdt, int node, 395 const char *property, TEE_UUID *uuid) 396 { 397 uint32_t uuid_array[4] = { 0 }; 398 const fdt32_t *p = NULL; 399 int len = 0; 400 int i = 0; 401 402 p = fdt_getprop(fdt, node, property, &len); 403 if (!p || len != sizeof(TEE_UUID)) 404 return TEE_ERROR_ITEM_NOT_FOUND; 405 406 for (i = 0; i < 4; i++) 407 uuid_array[i] = fdt32_to_cpu(p[i]); 408 409 tee_uuid_from_octets(uuid, (uint8_t *)uuid_array); 410 411 return TEE_SUCCESS; 412 } 413 414 static TEE_Result check_fdt(const void * const fdt, const TEE_UUID *uuid) 415 { 416 const struct fdt_property *description = NULL; 417 int description_name_len = 0; 418 TEE_UUID fdt_uuid = { }; 419 420 if (fdt_node_check_compatible(fdt, 0, "arm,ffa-manifest-1.0")) { 421 EMSG("Failed loading SP, manifest not found"); 422 return TEE_ERROR_BAD_PARAMETERS; 423 } 424 425 description = fdt_get_property(fdt, 0, "description", 426 &description_name_len); 427 if (description) 428 DMSG("Loading SP: %s", description->data); 429 430 if (sp_dt_get_uuid(fdt, 0, "uuid", &fdt_uuid)) { 431 EMSG("Missing or invalid UUID in SP manifest"); 432 return TEE_ERROR_BAD_FORMAT; 433 } 434 435 if (memcmp(uuid, &fdt_uuid, sizeof(fdt_uuid))) { 436 EMSG("Failed loading SP, UUID mismatch"); 437 return TEE_ERROR_BAD_FORMAT; 438 } 439 440 return TEE_SUCCESS; 441 } 442 443 /* 444 * sp_init_info allocates and maps the sp_ffa_init_info for the SP. It will copy 445 * the fdt into the allocated page(s) and return a pointer to the new location 446 * of the fdt. This pointer can be used to update data inside the fdt. 447 */ 448 static TEE_Result sp_init_info(struct sp_ctx *ctx, struct thread_smc_args *args, 449 const void * const input_fdt, vaddr_t *va, 450 size_t *num_pgs, void **fdt_copy) 451 { 452 struct sp_ffa_init_info *info = NULL; 453 int nvp_count = 1; 454 size_t total_size = ROUNDUP(CFG_SP_INIT_INFO_MAX_SIZE, SMALL_PAGE_SIZE); 455 size_t nvp_size = sizeof(struct sp_name_value_pair) * nvp_count; 456 size_t info_size = sizeof(*info) + nvp_size; 457 size_t fdt_size = total_size - info_size; 458 TEE_Result res = TEE_SUCCESS; 459 uint32_t perm = TEE_MATTR_URW | TEE_MATTR_PRW; 460 struct fobj *f = NULL; 461 struct mobj *m = NULL; 462 static const char fdt_name[16] = "TYPE_DT\0\0\0\0\0\0\0\0"; 463 464 *num_pgs = total_size / SMALL_PAGE_SIZE; 465 466 f = fobj_sec_mem_alloc(*num_pgs); 467 m = mobj_with_fobj_alloc(f, NULL, TEE_MATTR_MEM_TYPE_TAGGED); 468 469 fobj_put(f); 470 if (!m) 471 return TEE_ERROR_OUT_OF_MEMORY; 472 473 res = vm_map(&ctx->uctx, va, total_size, perm, 0, m, 0); 474 mobj_put(m); 475 if (res) 476 return res; 477 478 info = (struct sp_ffa_init_info *)*va; 479 480 /* magic field is 4 bytes, we don't copy /0 byte. */ 481 memcpy(&info->magic, "FF-A", 4); 482 info->count = nvp_count; 483 args->a0 = (vaddr_t)info; 484 485 /* 486 * Store the fdt after the boot_info and store the pointer in the 487 * first element. 488 */ 489 COMPILE_TIME_ASSERT(sizeof(info->nvp[0].name) == sizeof(fdt_name)); 490 memcpy(info->nvp[0].name, fdt_name, sizeof(fdt_name)); 491 info->nvp[0].value = *va + info_size; 492 info->nvp[0].size = fdt_size; 493 *fdt_copy = (void *)info->nvp[0].value; 494 495 if (fdt_open_into(input_fdt, *fdt_copy, fdt_size)) 496 return TEE_ERROR_GENERIC; 497 498 return TEE_SUCCESS; 499 } 500 501 static TEE_Result handle_fdt_dev_regions(struct sp_ctx *ctx, void *fdt) 502 { 503 int node = 0; 504 int subnode = 0; 505 TEE_Result res = TEE_SUCCESS; 506 const char *dt_device_match_table = { 507 "arm,ffa-manifest-device-regions", 508 }; 509 510 /* 511 * Device regions are optional in the SP manifest, it's not an error if 512 * we don't find any 513 */ 514 node = fdt_node_offset_by_compatible(fdt, 0, dt_device_match_table); 515 if (node < 0) 516 return TEE_SUCCESS; 517 518 fdt_for_each_subnode(subnode, fdt, node) { 519 uint64_t base_addr = 0; 520 uint32_t pages_cnt = 0; 521 uint32_t attributes = 0; 522 struct mobj *m = NULL; 523 bool is_secure = true; 524 uint32_t perm = 0; 525 vaddr_t va = 0; 526 unsigned int idx = 0; 527 528 /* 529 * Physical base address of a device MMIO region. 530 * Currently only physically contiguous region is supported. 531 */ 532 if (sp_dt_get_u64(fdt, subnode, "base-address", &base_addr)) { 533 EMSG("Mandatory field is missing: base-address"); 534 return TEE_ERROR_BAD_FORMAT; 535 } 536 537 /* Total size of MMIO region as count of 4K pages */ 538 if (sp_dt_get_u32(fdt, subnode, "pages-count", &pages_cnt)) { 539 EMSG("Mandatory field is missing: pages-count"); 540 return TEE_ERROR_BAD_FORMAT; 541 } 542 543 /* Data access, instruction access and security attributes */ 544 if (sp_dt_get_u32(fdt, subnode, "attributes", &attributes)) { 545 EMSG("Mandatory field is missing: attributes"); 546 return TEE_ERROR_BAD_FORMAT; 547 } 548 549 /* Check instruction and data access permissions */ 550 switch (attributes & SP_MANIFEST_ATTR_RWX) { 551 case SP_MANIFEST_ATTR_RO: 552 perm = TEE_MATTR_UR; 553 break; 554 case SP_MANIFEST_ATTR_RW: 555 perm = TEE_MATTR_URW; 556 break; 557 default: 558 EMSG("Invalid memory access permissions"); 559 return TEE_ERROR_BAD_FORMAT; 560 } 561 562 /* 563 * The SP is a secure endpoint, security attribute can be 564 * secure or non-secure 565 */ 566 if (attributes & SP_MANIFEST_ATTR_NSEC) 567 is_secure = false; 568 569 /* Memory attributes must be Device-nGnRnE */ 570 m = sp_mem_new_mobj(pages_cnt, TEE_MATTR_MEM_TYPE_STRONGLY_O, 571 is_secure); 572 if (!m) 573 return TEE_ERROR_OUT_OF_MEMORY; 574 575 res = sp_mem_add_pages(m, &idx, (paddr_t)base_addr, pages_cnt); 576 if (res) { 577 mobj_put(m); 578 return res; 579 } 580 581 res = vm_map(&ctx->uctx, &va, pages_cnt * SMALL_PAGE_SIZE, 582 perm, 0, m, 0); 583 mobj_put(m); 584 if (res) 585 return res; 586 587 /* 588 * Overwrite the device region's PA in the fdt with the VA. This 589 * fdt will be passed to the SP. 590 */ 591 res = fdt_setprop_u64(fdt, subnode, "base-address", va); 592 593 /* 594 * Unmap the region if the overwrite failed since the SP won't 595 * be able to access it without knowing the VA. 596 */ 597 if (res) { 598 vm_unmap(&ctx->uctx, va, pages_cnt * SMALL_PAGE_SIZE); 599 return res; 600 } 601 } 602 603 return TEE_SUCCESS; 604 } 605 606 static TEE_Result swap_sp_endpoints(uint32_t endpoint_id, 607 uint32_t new_endpoint_id) 608 { 609 struct sp_session *session = sp_get_session(endpoint_id); 610 uint32_t manifest_endpoint_id = 0; 611 612 /* 613 * We don't know in which order the SPs are loaded. The endpoint ID 614 * defined in the manifest could already be generated by 615 * new_session_id() and used by another SP. If this is the case, we swap 616 * the ID's of the two SPs. We also have to make sure that the ID's are 617 * not defined twice in the manifest. 618 */ 619 620 /* The endpoint ID was not assigned yet */ 621 if (!session) 622 return TEE_SUCCESS; 623 624 /* 625 * Read the manifest file from the SP who originally had the endpoint. 626 * We can safely swap the endpoint ID's if the manifest file doesn't 627 * have an endpoint ID defined. 628 */ 629 if (!sp_dt_get_u32(session->fdt, 0, "id", &manifest_endpoint_id)) { 630 assert(manifest_endpoint_id == endpoint_id); 631 EMSG("SP: Found duplicated endpoint ID %#"PRIx32, endpoint_id); 632 return TEE_ERROR_ACCESS_CONFLICT; 633 } 634 635 session->endpoint_id = new_endpoint_id; 636 637 return TEE_SUCCESS; 638 } 639 640 static TEE_Result read_manifest_endpoint_id(struct sp_session *s) 641 { 642 uint32_t endpoint_id = 0; 643 644 /* 645 * The endpoint ID can be optionally defined in the manifest file. We 646 * have to map the ID inside the manifest to the SP if it's defined. 647 * If not, the endpoint ID generated inside new_session_id() will be 648 * used. 649 */ 650 if (!sp_dt_get_u32(s->fdt, 0, "id", &endpoint_id)) { 651 TEE_Result res = TEE_ERROR_GENERIC; 652 653 if (endpoint_id <= SPMC_ENDPOINT_ID) 654 return TEE_ERROR_BAD_FORMAT; 655 656 res = swap_sp_endpoints(endpoint_id, s->endpoint_id); 657 if (res) 658 return res; 659 660 DMSG("SP: endpoint ID (0x%"PRIx32") found in manifest", 661 endpoint_id); 662 /* Assign the endpoint ID to the current SP */ 663 s->endpoint_id = endpoint_id; 664 } 665 return TEE_SUCCESS; 666 } 667 668 static TEE_Result handle_fdt_mem_regions(struct sp_ctx *ctx, void *fdt) 669 { 670 int node = 0; 671 int subnode = 0; 672 tee_mm_entry_t *mm = NULL; 673 TEE_Result res = TEE_SUCCESS; 674 675 /* 676 * Memory regions are optional in the SP manifest, it's not an error if 677 * we don't find any. 678 */ 679 node = fdt_node_offset_by_compatible(fdt, 0, 680 "arm,ffa-manifest-memory-regions"); 681 if (node < 0) 682 return TEE_SUCCESS; 683 684 fdt_for_each_subnode(subnode, fdt, node) { 685 bool alloc_needed = false; 686 uint32_t attributes = 0; 687 uint64_t base_addr = 0; 688 uint32_t pages_cnt = 0; 689 bool is_secure = true; 690 struct mobj *m = NULL; 691 unsigned int idx = 0; 692 uint32_t perm = 0; 693 size_t size = 0; 694 vaddr_t va = 0; 695 696 mm = NULL; 697 698 /* 699 * Base address of a memory region. 700 * If not present, we have to allocate the specified memory. 701 * If present, this field could specify a PA or VA. Currently 702 * only a PA is supported. 703 */ 704 if (sp_dt_get_u64(fdt, subnode, "base-address", &base_addr)) 705 alloc_needed = true; 706 707 /* Size of memory region as count of 4K pages */ 708 if (sp_dt_get_u32(fdt, subnode, "pages-count", &pages_cnt)) { 709 EMSG("Mandatory field is missing: pages-count"); 710 return TEE_ERROR_BAD_FORMAT; 711 } 712 713 if (MUL_OVERFLOW(pages_cnt, SMALL_PAGE_SIZE, &size)) 714 return TEE_ERROR_OVERFLOW; 715 716 /* 717 * Memory region attributes: 718 * - Instruction/data access permissions 719 * - Cacheability/shareability attributes 720 * - Security attributes 721 * 722 * Cacheability/shareability attributes can be ignored for now. 723 * OP-TEE only supports a single type for normal cached memory 724 * and currently there is no use case that would require to 725 * change this. 726 */ 727 if (sp_dt_get_u32(fdt, subnode, "attributes", &attributes)) { 728 EMSG("Mandatory field is missing: attributes"); 729 return TEE_ERROR_BAD_FORMAT; 730 } 731 732 /* Check instruction and data access permissions */ 733 switch (attributes & SP_MANIFEST_ATTR_RWX) { 734 case SP_MANIFEST_ATTR_RO: 735 perm = TEE_MATTR_UR; 736 break; 737 case SP_MANIFEST_ATTR_RW: 738 perm = TEE_MATTR_URW; 739 break; 740 case SP_MANIFEST_ATTR_RX: 741 perm = TEE_MATTR_URX; 742 break; 743 default: 744 EMSG("Invalid memory access permissions"); 745 return TEE_ERROR_BAD_FORMAT; 746 } 747 748 /* 749 * The SP is a secure endpoint, security attribute can be 750 * secure or non-secure. 751 * The SPMC cannot allocate non-secure memory, i.e. if the base 752 * address is missing this attribute must be secure. 753 */ 754 if (attributes & SP_MANIFEST_ATTR_NSEC) { 755 if (alloc_needed) { 756 EMSG("Invalid memory security attribute"); 757 return TEE_ERROR_BAD_FORMAT; 758 } 759 is_secure = false; 760 } 761 762 if (alloc_needed) { 763 /* Base address is missing, we have to allocate */ 764 mm = tee_mm_alloc(&tee_mm_sec_ddr, size); 765 if (!mm) 766 return TEE_ERROR_OUT_OF_MEMORY; 767 768 base_addr = tee_mm_get_smem(mm); 769 } 770 771 m = sp_mem_new_mobj(pages_cnt, TEE_MATTR_MEM_TYPE_CACHED, 772 is_secure); 773 if (!m) { 774 res = TEE_ERROR_OUT_OF_MEMORY; 775 goto err_mm_free; 776 } 777 778 res = sp_mem_add_pages(m, &idx, base_addr, pages_cnt); 779 if (res) { 780 mobj_put(m); 781 goto err_mm_free; 782 } 783 784 res = vm_map(&ctx->uctx, &va, size, perm, 0, m, 0); 785 mobj_put(m); 786 if (res) 787 goto err_mm_free; 788 789 /* 790 * Overwrite the memory region's base address in the fdt with 791 * the VA. This fdt will be passed to the SP. 792 * If the base-address field was not present in the original 793 * fdt, this function will create it. This doesn't cause issues 794 * since the necessary extra space has been allocated when 795 * opening the fdt. 796 */ 797 res = fdt_setprop_u64(fdt, subnode, "base-address", va); 798 799 /* 800 * Unmap the region if the overwrite failed since the SP won't 801 * be able to access it without knowing the VA. 802 */ 803 if (res) { 804 vm_unmap(&ctx->uctx, va, size); 805 goto err_mm_free; 806 } 807 } 808 809 return TEE_SUCCESS; 810 811 err_mm_free: 812 tee_mm_free(mm); 813 return res; 814 } 815 816 static TEE_Result handle_tpm_event_log(struct sp_ctx *ctx, void *fdt) 817 { 818 uint32_t perm = TEE_MATTR_URW | TEE_MATTR_PRW; 819 uint32_t dummy_size __maybe_unused = 0; 820 TEE_Result res = TEE_SUCCESS; 821 size_t page_count = 0; 822 struct fobj *f = NULL; 823 struct mobj *m = NULL; 824 vaddr_t log_addr = 0; 825 size_t log_size = 0; 826 int node = 0; 827 828 node = fdt_node_offset_by_compatible(fdt, 0, "arm,tpm_event_log"); 829 if (node < 0) 830 return TEE_SUCCESS; 831 832 /* Checking the existence and size of the event log properties */ 833 if (sp_dt_get_u64(fdt, node, "tpm_event_log_addr", &log_addr)) { 834 EMSG("tpm_event_log_addr not found or has invalid size"); 835 return TEE_ERROR_BAD_FORMAT; 836 } 837 838 if (sp_dt_get_u32(fdt, node, "tpm_event_log_size", &dummy_size)) { 839 EMSG("tpm_event_log_size not found or has invalid size"); 840 return TEE_ERROR_BAD_FORMAT; 841 } 842 843 /* Validating event log */ 844 res = tpm_get_event_log_size(&log_size); 845 if (res) 846 return res; 847 848 if (!log_size) { 849 EMSG("Empty TPM event log was provided"); 850 return TEE_ERROR_ITEM_NOT_FOUND; 851 } 852 853 /* Allocating memory area for the event log to share with the SP */ 854 page_count = ROUNDUP_DIV(log_size, SMALL_PAGE_SIZE); 855 856 f = fobj_sec_mem_alloc(page_count); 857 m = mobj_with_fobj_alloc(f, NULL, TEE_MATTR_MEM_TYPE_TAGGED); 858 fobj_put(f); 859 if (!m) 860 return TEE_ERROR_OUT_OF_MEMORY; 861 862 res = vm_map(&ctx->uctx, &log_addr, log_size, perm, 0, m, 0); 863 mobj_put(m); 864 if (res) 865 return res; 866 867 /* Copy event log */ 868 res = tpm_get_event_log((void *)log_addr, &log_size); 869 if (res) 870 goto err_unmap; 871 872 /* Setting event log details in the manifest */ 873 res = fdt_setprop_u64(fdt, node, "tpm_event_log_addr", log_addr); 874 if (res) 875 goto err_unmap; 876 877 res = fdt_setprop_u32(fdt, node, "tpm_event_log_size", log_size); 878 if (res) 879 goto err_unmap; 880 881 return TEE_SUCCESS; 882 883 err_unmap: 884 vm_unmap(&ctx->uctx, log_addr, log_size); 885 886 return res; 887 } 888 889 static TEE_Result sp_init_uuid(const TEE_UUID *uuid, const void * const fdt) 890 { 891 TEE_Result res = TEE_SUCCESS; 892 struct sp_session *sess = NULL; 893 894 res = sp_open_session(&sess, 895 &open_sp_sessions, 896 uuid); 897 if (res) 898 return res; 899 900 res = check_fdt(fdt, uuid); 901 if (res) 902 return res; 903 904 sess->fdt = fdt; 905 res = read_manifest_endpoint_id(sess); 906 if (res) 907 return res; 908 DMSG("endpoint is 0x%"PRIx16, sess->endpoint_id); 909 910 return TEE_SUCCESS; 911 } 912 913 static TEE_Result sp_first_run(struct sp_session *sess) 914 { 915 TEE_Result res = TEE_SUCCESS; 916 struct thread_smc_args args = { }; 917 vaddr_t va = 0; 918 size_t num_pgs = 0; 919 struct sp_ctx *ctx = NULL; 920 void *fdt_copy = NULL; 921 922 ctx = to_sp_ctx(sess->ts_sess.ctx); 923 ts_push_current_session(&sess->ts_sess); 924 925 res = sp_init_info(ctx, &args, sess->fdt, &va, &num_pgs, &fdt_copy); 926 if (res) 927 goto out; 928 929 res = handle_fdt_dev_regions(ctx, fdt_copy); 930 if (res) 931 goto out; 932 933 res = handle_fdt_mem_regions(ctx, fdt_copy); 934 if (res) 935 goto out; 936 937 if (IS_ENABLED(CFG_CORE_TPM_EVENT_LOG)) { 938 res = handle_tpm_event_log(ctx, fdt_copy); 939 if (res) 940 goto out; 941 } 942 943 ts_pop_current_session(); 944 945 sess->is_initialized = false; 946 if (sp_enter(&args, sess)) { 947 vm_unmap(&ctx->uctx, va, num_pgs); 948 return FFA_ABORTED; 949 } 950 951 spmc_sp_msg_handler(&args, sess); 952 953 sess->is_initialized = true; 954 955 ts_push_current_session(&sess->ts_sess); 956 out: 957 /* Free the boot info page from the SP memory */ 958 vm_unmap(&ctx->uctx, va, num_pgs); 959 ts_pop_current_session(); 960 961 return res; 962 } 963 964 TEE_Result sp_enter(struct thread_smc_args *args, struct sp_session *sp) 965 { 966 TEE_Result res = FFA_OK; 967 struct sp_ctx *ctx = to_sp_ctx(sp->ts_sess.ctx); 968 969 ctx->sp_regs.x[0] = args->a0; 970 ctx->sp_regs.x[1] = args->a1; 971 ctx->sp_regs.x[2] = args->a2; 972 ctx->sp_regs.x[3] = args->a3; 973 ctx->sp_regs.x[4] = args->a4; 974 ctx->sp_regs.x[5] = args->a5; 975 ctx->sp_regs.x[6] = args->a6; 976 ctx->sp_regs.x[7] = args->a7; 977 978 res = sp->ts_sess.ctx->ops->enter_invoke_cmd(&sp->ts_sess, 0); 979 980 args->a0 = ctx->sp_regs.x[0]; 981 args->a1 = ctx->sp_regs.x[1]; 982 args->a2 = ctx->sp_regs.x[2]; 983 args->a3 = ctx->sp_regs.x[3]; 984 args->a4 = ctx->sp_regs.x[4]; 985 args->a5 = ctx->sp_regs.x[5]; 986 args->a6 = ctx->sp_regs.x[6]; 987 args->a7 = ctx->sp_regs.x[7]; 988 989 return res; 990 } 991 992 static TEE_Result sp_enter_invoke_cmd(struct ts_session *s, 993 uint32_t cmd __unused) 994 { 995 struct sp_ctx *ctx = to_sp_ctx(s->ctx); 996 TEE_Result res = TEE_SUCCESS; 997 uint32_t exceptions = 0; 998 uint64_t cpsr = 0; 999 struct sp_session *sp_s = to_sp_session(s); 1000 struct ts_session *sess = NULL; 1001 struct thread_ctx_regs *sp_regs = NULL; 1002 uint32_t panicked = false; 1003 uint32_t panic_code = 0; 1004 1005 bm_timestamp(); 1006 1007 sp_regs = &ctx->sp_regs; 1008 ts_push_current_session(s); 1009 1010 cpsr = sp_regs->cpsr; 1011 sp_regs->cpsr = read_daif() & (SPSR_64_DAIF_MASK << SPSR_64_DAIF_SHIFT); 1012 1013 exceptions = thread_mask_exceptions(THREAD_EXCP_ALL); 1014 __thread_enter_user_mode(sp_regs, &panicked, &panic_code); 1015 sp_regs->cpsr = cpsr; 1016 thread_unmask_exceptions(exceptions); 1017 1018 thread_user_clear_vfp(&ctx->uctx); 1019 1020 if (panicked) { 1021 DMSG("SP panicked with code %#"PRIx32, panic_code); 1022 abort_print_current_ts(); 1023 1024 sess = ts_pop_current_session(); 1025 cpu_spin_lock(&sp_s->spinlock); 1026 sp_s->state = sp_dead; 1027 cpu_spin_unlock(&sp_s->spinlock); 1028 1029 return TEE_ERROR_TARGET_DEAD; 1030 } 1031 1032 sess = ts_pop_current_session(); 1033 assert(sess == s); 1034 1035 bm_timestamp(); 1036 1037 return res; 1038 } 1039 1040 /* We currently don't support 32 bits */ 1041 #ifdef ARM64 1042 static void sp_svc_store_registers(struct thread_scall_regs *regs, 1043 struct thread_ctx_regs *sp_regs) 1044 { 1045 COMPILE_TIME_ASSERT(sizeof(sp_regs->x[0]) == sizeof(regs->x0)); 1046 memcpy(sp_regs->x, ®s->x0, 31 * sizeof(regs->x0)); 1047 sp_regs->pc = regs->elr; 1048 sp_regs->sp = regs->sp_el0; 1049 } 1050 #endif 1051 1052 static bool sp_handle_scall(struct thread_scall_regs *regs) 1053 { 1054 struct ts_session *ts = ts_get_current_session(); 1055 struct sp_ctx *uctx = to_sp_ctx(ts->ctx); 1056 struct sp_session *s = uctx->open_session; 1057 1058 assert(s); 1059 1060 sp_svc_store_registers(regs, &uctx->sp_regs); 1061 1062 regs->x0 = 0; 1063 regs->x1 = 0; /* panic */ 1064 regs->x2 = 0; /* panic code */ 1065 1066 /* 1067 * All the registers of the SP are saved in the SP session by the SVC 1068 * handler. 1069 * We always return to S-El1 after handling the SVC. We will continue 1070 * in sp_enter_invoke_cmd() (return from __thread_enter_user_mode). 1071 * The sp_enter() function copies the FF-A parameters (a0-a7) from the 1072 * saved registers to the thread_smc_args. The thread_smc_args object is 1073 * afterward used by the spmc_sp_msg_handler() to handle the 1074 * FF-A message send by the SP. 1075 */ 1076 return false; 1077 } 1078 1079 static void sp_dump_state(struct ts_ctx *ctx) 1080 { 1081 struct sp_ctx *utc = to_sp_ctx(ctx); 1082 1083 if (utc->uctx.dump_entry_func) { 1084 TEE_Result res = ldelf_dump_state(&utc->uctx); 1085 1086 if (!res || res == TEE_ERROR_TARGET_DEAD) 1087 return; 1088 } 1089 1090 user_mode_ctx_print_mappings(&utc->uctx); 1091 } 1092 1093 static const struct ts_ops sp_ops = { 1094 .enter_invoke_cmd = sp_enter_invoke_cmd, 1095 .handle_scall = sp_handle_scall, 1096 .dump_state = sp_dump_state, 1097 }; 1098 1099 static TEE_Result process_sp_pkg(uint64_t sp_pkg_pa, TEE_UUID *sp_uuid) 1100 { 1101 enum teecore_memtypes mtype = MEM_AREA_RAM_SEC; 1102 struct sp_pkg_header *sp_pkg_hdr = NULL; 1103 TEE_Result res = TEE_SUCCESS; 1104 tee_mm_entry_t *mm = NULL; 1105 struct fip_sp *sp = NULL; 1106 uint64_t sp_fdt_end = 0; 1107 size_t sp_pkg_size = 0; 1108 vaddr_t sp_pkg_va = 0; 1109 size_t num_pages = 0; 1110 1111 /* Map only the first page of the SP package to parse the header */ 1112 if (!tee_pbuf_is_sec(sp_pkg_pa, SMALL_PAGE_SIZE)) 1113 return TEE_ERROR_GENERIC; 1114 1115 mm = tee_mm_alloc(&tee_mm_sec_ddr, SMALL_PAGE_SIZE); 1116 if (!mm) 1117 return TEE_ERROR_OUT_OF_MEMORY; 1118 1119 sp_pkg_va = tee_mm_get_smem(mm); 1120 1121 if (core_mmu_map_contiguous_pages(sp_pkg_va, sp_pkg_pa, 1, mtype)) { 1122 res = TEE_ERROR_GENERIC; 1123 goto err; 1124 } 1125 1126 sp_pkg_hdr = (struct sp_pkg_header *)sp_pkg_va; 1127 1128 if (sp_pkg_hdr->magic != SP_PKG_HEADER_MAGIC) { 1129 EMSG("Invalid SP package magic"); 1130 res = TEE_ERROR_BAD_FORMAT; 1131 goto err_unmap; 1132 } 1133 1134 if (sp_pkg_hdr->version != SP_PKG_HEADER_VERSION_V1 && 1135 sp_pkg_hdr->version != SP_PKG_HEADER_VERSION_V2) { 1136 EMSG("Invalid SP header version"); 1137 res = TEE_ERROR_BAD_FORMAT; 1138 goto err_unmap; 1139 } 1140 1141 if (ADD_OVERFLOW(sp_pkg_hdr->img_offset, sp_pkg_hdr->img_size, 1142 &sp_pkg_size)) { 1143 EMSG("Invalid SP package size"); 1144 res = TEE_ERROR_BAD_FORMAT; 1145 goto err_unmap; 1146 } 1147 1148 if (ADD_OVERFLOW(sp_pkg_hdr->pm_offset, sp_pkg_hdr->pm_size, 1149 &sp_fdt_end) || sp_fdt_end > sp_pkg_hdr->img_offset) { 1150 EMSG("Invalid SP manifest size"); 1151 res = TEE_ERROR_BAD_FORMAT; 1152 goto err_unmap; 1153 } 1154 1155 core_mmu_unmap_pages(sp_pkg_va, 1); 1156 tee_mm_free(mm); 1157 1158 /* Map the whole package */ 1159 if (!tee_pbuf_is_sec(sp_pkg_pa, sp_pkg_size)) 1160 return TEE_ERROR_GENERIC; 1161 1162 num_pages = ROUNDUP_DIV(sp_pkg_size, SMALL_PAGE_SIZE); 1163 1164 mm = tee_mm_alloc(&tee_mm_sec_ddr, sp_pkg_size); 1165 if (!mm) 1166 return TEE_ERROR_OUT_OF_MEMORY; 1167 1168 sp_pkg_va = tee_mm_get_smem(mm); 1169 1170 if (core_mmu_map_contiguous_pages(sp_pkg_va, sp_pkg_pa, num_pages, 1171 mtype)) { 1172 res = TEE_ERROR_GENERIC; 1173 goto err; 1174 } 1175 1176 sp_pkg_hdr = (struct sp_pkg_header *)tee_mm_get_smem(mm); 1177 1178 sp = calloc(1, sizeof(struct fip_sp)); 1179 if (!sp) { 1180 res = TEE_ERROR_OUT_OF_MEMORY; 1181 goto err_unmap; 1182 } 1183 1184 memcpy(&sp->sp_img.image.uuid, sp_uuid, sizeof(*sp_uuid)); 1185 sp->sp_img.image.ts = (uint8_t *)(sp_pkg_va + sp_pkg_hdr->img_offset); 1186 sp->sp_img.image.size = sp_pkg_hdr->img_size; 1187 sp->sp_img.image.flags = 0; 1188 sp->sp_img.fdt = (uint8_t *)(sp_pkg_va + sp_pkg_hdr->pm_offset); 1189 sp->mm = mm; 1190 1191 STAILQ_INSERT_TAIL(&fip_sp_list, sp, link); 1192 1193 return TEE_SUCCESS; 1194 1195 err_unmap: 1196 core_mmu_unmap_pages(tee_mm_get_smem(mm), 1197 ROUNDUP_DIV(tee_mm_get_bytes(mm), 1198 SMALL_PAGE_SIZE)); 1199 err: 1200 tee_mm_free(mm); 1201 1202 return res; 1203 } 1204 1205 static TEE_Result fip_sp_map_all(void) 1206 { 1207 TEE_Result res = TEE_SUCCESS; 1208 uint64_t sp_pkg_addr = 0; 1209 const void *fdt = NULL; 1210 TEE_UUID sp_uuid = { }; 1211 int sp_pkgs_node = 0; 1212 int subnode = 0; 1213 int root = 0; 1214 1215 fdt = get_external_dt(); 1216 if (!fdt) { 1217 EMSG("No SPMC manifest found"); 1218 return TEE_ERROR_GENERIC; 1219 } 1220 1221 root = fdt_path_offset(fdt, "/"); 1222 if (root < 0) 1223 return TEE_ERROR_BAD_FORMAT; 1224 1225 if (fdt_node_check_compatible(fdt, root, "arm,ffa-core-manifest-1.0")) 1226 return TEE_ERROR_BAD_FORMAT; 1227 1228 /* SP packages are optional, it's not an error if we don't find any */ 1229 sp_pkgs_node = fdt_node_offset_by_compatible(fdt, root, "arm,sp_pkg"); 1230 if (sp_pkgs_node < 0) 1231 return TEE_SUCCESS; 1232 1233 fdt_for_each_subnode(subnode, fdt, sp_pkgs_node) { 1234 res = sp_dt_get_u64(fdt, subnode, "load-address", &sp_pkg_addr); 1235 if (res) { 1236 EMSG("Invalid FIP SP load address"); 1237 return res; 1238 } 1239 1240 res = sp_dt_get_uuid(fdt, subnode, "uuid", &sp_uuid); 1241 if (res) { 1242 EMSG("Invalid FIP SP uuid"); 1243 return res; 1244 } 1245 1246 res = process_sp_pkg(sp_pkg_addr, &sp_uuid); 1247 if (res) { 1248 EMSG("Invalid FIP SP package"); 1249 return res; 1250 } 1251 } 1252 1253 return TEE_SUCCESS; 1254 } 1255 1256 static void fip_sp_unmap_all(void) 1257 { 1258 while (!STAILQ_EMPTY(&fip_sp_list)) { 1259 struct fip_sp *sp = STAILQ_FIRST(&fip_sp_list); 1260 1261 STAILQ_REMOVE_HEAD(&fip_sp_list, link); 1262 core_mmu_unmap_pages(tee_mm_get_smem(sp->mm), 1263 ROUNDUP_DIV(tee_mm_get_bytes(sp->mm), 1264 SMALL_PAGE_SIZE)); 1265 tee_mm_free(sp->mm); 1266 free(sp); 1267 } 1268 } 1269 1270 static TEE_Result sp_init_all(void) 1271 { 1272 TEE_Result res = TEE_SUCCESS; 1273 const struct sp_image *sp = NULL; 1274 const struct fip_sp *fip_sp = NULL; 1275 char __maybe_unused msg[60] = { '\0', }; 1276 struct sp_session *s = NULL; 1277 1278 for_each_secure_partition(sp) { 1279 if (sp->image.uncompressed_size) 1280 snprintf(msg, sizeof(msg), 1281 " (compressed, uncompressed %u)", 1282 sp->image.uncompressed_size); 1283 else 1284 msg[0] = '\0'; 1285 DMSG("SP %pUl size %u%s", (void *)&sp->image.uuid, 1286 sp->image.size, msg); 1287 1288 res = sp_init_uuid(&sp->image.uuid, sp->fdt); 1289 1290 if (res != TEE_SUCCESS) { 1291 EMSG("Failed initializing SP(%pUl) err:%#"PRIx32, 1292 &sp->image.uuid, res); 1293 if (!IS_ENABLED(CFG_SP_SKIP_FAILED)) 1294 panic(); 1295 } 1296 } 1297 1298 res = fip_sp_map_all(); 1299 if (res) 1300 panic("Failed mapping FIP SPs"); 1301 1302 for_each_fip_sp(fip_sp) { 1303 sp = &fip_sp->sp_img; 1304 1305 DMSG("SP %pUl size %u", (void *)&sp->image.uuid, 1306 sp->image.size); 1307 1308 res = sp_init_uuid(&sp->image.uuid, sp->fdt); 1309 1310 if (res != TEE_SUCCESS) { 1311 EMSG("Failed initializing SP(%pUl) err:%#"PRIx32, 1312 &sp->image.uuid, res); 1313 if (!IS_ENABLED(CFG_SP_SKIP_FAILED)) 1314 panic(); 1315 } 1316 } 1317 1318 /* Continue the initialization and run the SP */ 1319 TAILQ_FOREACH(s, &open_sp_sessions, link) { 1320 res = sp_first_run(s); 1321 if (res != TEE_SUCCESS) { 1322 EMSG("Failed starting SP(0x%"PRIx16") err:%#"PRIx32, 1323 s->endpoint_id, res); 1324 if (!IS_ENABLED(CFG_SP_SKIP_FAILED)) 1325 panic(); 1326 } 1327 } 1328 /* 1329 * At this point all FIP SPs are loaded by ldelf so the original images 1330 * (loaded by BL2 earlier) can be unmapped 1331 */ 1332 fip_sp_unmap_all(); 1333 1334 return TEE_SUCCESS; 1335 } 1336 1337 boot_final(sp_init_all); 1338 1339 static TEE_Result secure_partition_open(const TEE_UUID *uuid, 1340 struct ts_store_handle **h) 1341 { 1342 return emb_ts_open(uuid, h, find_secure_partition); 1343 } 1344 1345 REGISTER_SP_STORE(2) = { 1346 .description = "SP store", 1347 .open = secure_partition_open, 1348 .get_size = emb_ts_get_size, 1349 .get_tag = emb_ts_get_tag, 1350 .read = emb_ts_read, 1351 .close = emb_ts_close, 1352 }; 1353