1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2019, Linaro Limited 4 * Copyright (c) 2020, Arm Limited. 5 */ 6 7 #include <crypto/crypto.h> 8 #include <ffa.h> 9 #include <keep.h> 10 #include <kernel/abort.h> 11 #include <kernel/stmm_sp.h> 12 #include <kernel/tee_ta_manager.h> 13 #include <kernel/thread_private.h> 14 #include <kernel/user_mode_ctx.h> 15 #include <mempool.h> 16 #include <mm/fobj.h> 17 #include <mm/mobj.h> 18 #include <mm/vm.h> 19 #include <pta_stmm.h> 20 #include <tee_api_defines_extensions.h> 21 #include <tee/tee_pobj.h> 22 #include <tee/tee_svc.h> 23 #include <tee/tee_svc_storage.h> 24 #include <zlib.h> 25 26 #ifdef ARM64 27 #define SVC_REGS_A0(_regs) ((_regs)->x0) 28 #define SVC_REGS_A1(_regs) ((_regs)->x1) 29 #define SVC_REGS_A2(_regs) ((_regs)->x2) 30 #define SVC_REGS_A3(_regs) ((_regs)->x3) 31 #define SVC_REGS_A4(_regs) ((_regs)->x4) 32 #define SVC_REGS_A5(_regs) ((_regs)->x5) 33 #define SVC_REGS_A6(_regs) ((_regs)->x6) 34 #define SVC_REGS_A7(_regs) ((_regs)->x7) 35 #define __FFA_SVC_RPMB_READ FFA_SVC_RPMB_READ 36 #define __FFA_SVC_RPMB_WRITE FFA_SVC_RPMB_WRITE 37 #define __FFA_SVC_MEMORY_ATTRIBUTES_GET FFA_SVC_MEMORY_ATTRIBUTES_GET_64 38 #define __FFA_SVC_MEMORY_ATTRIBUTES_SET FFA_SVC_MEMORY_ATTRIBUTES_SET_64 39 #define __FFA_MSG_SEND_DIRECT_RESP FFA_MSG_SEND_DIRECT_RESP_64 40 #define __FFA_MSG_SEND_DIRECT_REQ FFA_MSG_SEND_DIRECT_REQ_64 41 #endif 42 #ifdef ARM32 43 #define SVC_REGS_A0(_regs) ((_regs)->r0) 44 #define SVC_REGS_A1(_regs) ((_regs)->r1) 45 #define SVC_REGS_A2(_regs) ((_regs)->r2) 46 #define SVC_REGS_A3(_regs) ((_regs)->r3) 47 #define SVC_REGS_A4(_regs) ((_regs)->r4) 48 #define SVC_REGS_A5(_regs) ((_regs)->r5) 49 #define SVC_REGS_A6(_regs) ((_regs)->r6) 50 #define SVC_REGS_A7(_regs) ((_regs)->r7) 51 #define __FFA_SVC_RPMB_READ FFA_SVC_RPMB_READ_32 52 #define __FFA_SVC_RPMB_WRITE FFA_SVC_RPMB_WRITE_32 53 #define __FFA_SVC_MEMORY_ATTRIBUTES_GET FFA_SVC_MEMORY_ATTRIBUTES_GET_32 54 #define __FFA_SVC_MEMORY_ATTRIBUTES_SET FFA_SVC_MEMORY_ATTRIBUTES_SET_32 55 #define __FFA_MSG_SEND_DIRECT_RESP FFA_MSG_SEND_DIRECT_RESP_32 56 #define __FFA_MSG_SEND_DIRECT_REQ FFA_MSG_SEND_DIRECT_REQ_32 57 #endif 58 59 static const TEE_UUID stmm_uuid = PTA_STMM_UUID; 60 61 /* 62 * Once a complete FFA spec is added, these will become discoverable. 63 * Until then these are considered part of the internal ABI between 64 * OP-TEE and StMM. 65 */ 66 static const uint16_t stmm_id = 1U; 67 static const uint16_t stmm_pta_id = 2U; 68 static const uint16_t mem_mgr_id = 3U; 69 static const uint16_t ffa_storage_id = 4U; 70 71 static const unsigned int stmm_stack_size = 4 * SMALL_PAGE_SIZE; 72 static const unsigned int stmm_heap_size = 398 * SMALL_PAGE_SIZE; 73 static const unsigned int stmm_sec_buf_size = 4 * SMALL_PAGE_SIZE; 74 static const unsigned int stmm_ns_comm_buf_size = 4 * SMALL_PAGE_SIZE; 75 76 extern unsigned char stmm_image[]; 77 extern const unsigned int stmm_image_size; 78 extern const unsigned int stmm_image_uncompressed_size; 79 80 const TEE_UUID *stmm_get_uuid(void) 81 { 82 return &stmm_uuid; 83 } 84 85 static struct stmm_ctx *stmm_alloc_ctx(const TEE_UUID *uuid) 86 { 87 TEE_Result res = TEE_SUCCESS; 88 struct stmm_ctx *spc = NULL; 89 90 spc = calloc(1, sizeof(*spc)); 91 if (!spc) 92 return NULL; 93 94 spc->ta_ctx.ts_ctx.ops = &stmm_sp_ops; 95 spc->ta_ctx.ts_ctx.uuid = *uuid; 96 spc->ta_ctx.flags = TA_FLAG_SINGLE_INSTANCE | 97 TA_FLAG_INSTANCE_KEEP_ALIVE; 98 99 res = vm_info_init(&spc->uctx, &spc->ta_ctx.ts_ctx); 100 if (res) { 101 free(spc); 102 return NULL; 103 } 104 105 spc->ta_ctx.ref_count = 1; 106 condvar_init(&spc->ta_ctx.busy_cv); 107 108 return spc; 109 } 110 111 static TEE_Result stmm_enter_user_mode(struct stmm_ctx *spc) 112 { 113 uint32_t exceptions = 0; 114 uint32_t panic_code = 0; 115 uint32_t panicked = 0; 116 uint64_t cntkctl = 0; 117 118 exceptions = thread_mask_exceptions(THREAD_EXCP_ALL); 119 cntkctl = read_cntkctl(); 120 write_cntkctl(cntkctl | CNTKCTL_PL0PCTEN); 121 122 #ifdef ARM32 123 /* Handle usr_lr in place of __thread_enter_user_mode() */ 124 thread_set_usr_lr(spc->regs.usr_lr); 125 #endif 126 127 __thread_enter_user_mode(&spc->regs, &panicked, &panic_code); 128 129 #ifdef ARM32 130 spc->regs.usr_lr = thread_get_usr_lr(); 131 #endif 132 133 write_cntkctl(cntkctl); 134 thread_unmask_exceptions(exceptions); 135 136 thread_user_clear_vfp(&spc->uctx); 137 138 if (panicked) { 139 abort_print_current_ts(); 140 DMSG("stmm panicked with code %#"PRIx32, panic_code); 141 return TEE_ERROR_TARGET_DEAD; 142 } 143 144 return TEE_SUCCESS; 145 } 146 147 #ifdef ARM64 148 static void init_stmm_regs(struct stmm_ctx *spc, unsigned long a0, 149 unsigned long a1, unsigned long sp, unsigned long pc) 150 { 151 spc->regs.x[0] = a0; 152 spc->regs.x[1] = a1; 153 spc->regs.sp = sp; 154 spc->regs.pc = pc; 155 } 156 #endif 157 158 #ifdef ARM32 159 static uint32_t __maybe_unused get_spsr(void) 160 { 161 uint32_t s = 0; 162 163 s = read_cpsr(); 164 s &= ~(CPSR_MODE_MASK | CPSR_T | ARM32_CPSR_IT_MASK); 165 s |= CPSR_MODE_USR; 166 167 return s; 168 } 169 170 static void init_stmm_regs(struct stmm_ctx *spc, unsigned long a0, 171 unsigned long a1, unsigned long sp, unsigned long pc) 172 { 173 spc->regs.r0 = a0; 174 spc->regs.r1 = a1; 175 spc->regs.usr_sp = sp; 176 spc->regs.cpsr = get_spsr(); 177 spc->regs.pc = pc; 178 } 179 #endif 180 181 static TEE_Result alloc_and_map_sp_fobj(struct stmm_ctx *spc, size_t sz, 182 uint32_t prot, vaddr_t *va) 183 { 184 size_t num_pgs = ROUNDUP_DIV(sz, SMALL_PAGE_SIZE); 185 struct fobj *fobj = fobj_ta_mem_alloc(num_pgs); 186 TEE_Result res = TEE_SUCCESS; 187 struct mobj *mobj = NULL; 188 189 mobj = mobj_with_fobj_alloc(fobj, NULL, TEE_MATTR_MEM_TYPE_TAGGED); 190 fobj_put(fobj); 191 if (!mobj) 192 return TEE_ERROR_OUT_OF_MEMORY; 193 194 res = vm_map(&spc->uctx, va, num_pgs * SMALL_PAGE_SIZE, 195 prot, 0, mobj, 0); 196 if (res) 197 mobj_put(mobj); 198 199 return TEE_SUCCESS; 200 } 201 202 static void *zalloc(void *opaque __unused, unsigned int items, 203 unsigned int size) 204 { 205 return mempool_alloc(mempool_default, items * size); 206 } 207 208 static void zfree(void *opaque __unused, void *address) 209 { 210 mempool_free(mempool_default, address); 211 } 212 213 static void uncompress_image(void *dst, size_t dst_size, void *src, 214 size_t src_size) 215 { 216 z_stream strm = { 217 .next_in = src, 218 .avail_in = src_size, 219 .next_out = dst, 220 .avail_out = dst_size, 221 .zalloc = zalloc, 222 .zfree = zfree, 223 }; 224 225 if (inflateInit(&strm) != Z_OK) 226 panic("inflateInit"); 227 228 if (inflate(&strm, Z_SYNC_FLUSH) != Z_STREAM_END) 229 panic("inflate"); 230 231 if (inflateEnd(&strm) != Z_OK) 232 panic("inflateEnd"); 233 } 234 235 static TEE_Result load_stmm(struct stmm_ctx *spc) 236 { 237 struct stmm_boot_info *boot_info = NULL; 238 struct stmm_mp_info *mp_info = NULL; 239 TEE_Result res = TEE_SUCCESS; 240 vaddr_t sp_addr = 0; 241 vaddr_t image_addr = 0; 242 vaddr_t heap_addr = 0; 243 vaddr_t stack_addr = 0; 244 vaddr_t sec_buf_addr = 0; 245 vaddr_t comm_buf_addr = 0; 246 unsigned int sp_size = 0; 247 unsigned int uncompressed_size_roundup = 0; 248 249 uncompressed_size_roundup = ROUNDUP(stmm_image_uncompressed_size, 250 SMALL_PAGE_SIZE); 251 sp_size = uncompressed_size_roundup + stmm_stack_size + 252 stmm_heap_size + stmm_sec_buf_size; 253 res = alloc_and_map_sp_fobj(spc, sp_size, 254 TEE_MATTR_PRW, &sp_addr); 255 if (res) 256 return res; 257 258 res = alloc_and_map_sp_fobj(spc, stmm_ns_comm_buf_size, 259 TEE_MATTR_URW | TEE_MATTR_PRW, 260 &comm_buf_addr); 261 /* 262 * We don't need to free the previous instance here, they'll all be 263 * handled during the destruction call (stmm_ctx_destroy()) 264 */ 265 if (res) 266 return res; 267 268 image_addr = sp_addr; 269 heap_addr = image_addr + uncompressed_size_roundup; 270 stack_addr = heap_addr + stmm_heap_size; 271 sec_buf_addr = stack_addr + stmm_stack_size; 272 273 vm_set_ctx(&spc->ta_ctx.ts_ctx); 274 uncompress_image((void *)image_addr, stmm_image_uncompressed_size, 275 stmm_image, stmm_image_size); 276 277 res = vm_set_prot(&spc->uctx, image_addr, uncompressed_size_roundup, 278 TEE_MATTR_URX | TEE_MATTR_PR); 279 if (res) 280 return res; 281 282 res = vm_set_prot(&spc->uctx, heap_addr, stmm_heap_size, 283 TEE_MATTR_URW | TEE_MATTR_PRW); 284 if (res) 285 return res; 286 287 res = vm_set_prot(&spc->uctx, stack_addr, stmm_stack_size, 288 TEE_MATTR_URW | TEE_MATTR_PRW); 289 if (res) 290 return res; 291 292 res = vm_set_prot(&spc->uctx, sec_buf_addr, stmm_sec_buf_size, 293 TEE_MATTR_URW | TEE_MATTR_PRW); 294 if (res) 295 return res; 296 297 DMSG("stmm load address %#"PRIxVA, image_addr); 298 299 boot_info = (struct stmm_boot_info *)sec_buf_addr; 300 mp_info = (struct stmm_mp_info *)(boot_info + 1); 301 *boot_info = (struct stmm_boot_info){ 302 .h.type = STMM_PARAM_SP_IMAGE_BOOT_INFO, 303 .h.version = STMM_PARAM_VERSION_1, 304 .h.size = sizeof(struct stmm_boot_info), 305 .h.attr = 0, 306 .sp_mem_base = sp_addr, 307 .sp_mem_limit = sp_addr + sp_size, 308 .sp_image_base = image_addr, 309 .sp_stack_base = stack_addr, 310 .sp_heap_base = heap_addr, 311 .sp_ns_comm_buf_base = comm_buf_addr, 312 .sp_shared_buf_base = sec_buf_addr, 313 .sp_image_size = stmm_image_size, 314 .sp_pcpu_stack_size = stmm_stack_size, 315 .sp_heap_size = stmm_heap_size, 316 .sp_ns_comm_buf_size = stmm_ns_comm_buf_size, 317 .sp_shared_buf_size = stmm_sec_buf_size, 318 .num_sp_mem_regions = 6, 319 .num_cpus = 1, 320 .mp_info = mp_info, 321 }; 322 mp_info->mpidr = read_mpidr(); 323 mp_info->linear_id = 0; 324 mp_info->flags = MP_INFO_FLAG_PRIMARY_CPU; 325 spc->ns_comm_buf_addr = comm_buf_addr; 326 spc->ns_comm_buf_size = stmm_ns_comm_buf_size; 327 328 init_stmm_regs(spc, sec_buf_addr, 329 (vaddr_t)(mp_info + 1) - sec_buf_addr, 330 stack_addr + stmm_stack_size, image_addr); 331 332 return stmm_enter_user_mode(spc); 333 } 334 335 TEE_Result stmm_init_session(const TEE_UUID *uuid, struct tee_ta_session *sess) 336 { 337 struct stmm_ctx *spc = NULL; 338 339 /* Caller is expected to hold tee_ta_mutex for safe changes in @sess */ 340 assert(mutex_is_locked(&tee_ta_mutex)); 341 342 if (memcmp(uuid, &stmm_uuid, sizeof(*uuid))) 343 return TEE_ERROR_ITEM_NOT_FOUND; 344 345 spc = stmm_alloc_ctx(uuid); 346 if (!spc) 347 return TEE_ERROR_OUT_OF_MEMORY; 348 349 spc->ta_ctx.is_initializing = true; 350 351 sess->ts_sess.ctx = &spc->ta_ctx.ts_ctx; 352 sess->ts_sess.handle_scall = sess->ts_sess.ctx->ops->handle_scall; 353 354 return TEE_SUCCESS; 355 } 356 357 TEE_Result stmm_complete_session(struct tee_ta_session *sess) 358 { 359 struct stmm_ctx *spc = to_stmm_ctx(sess->ts_sess.ctx); 360 TEE_Result res = TEE_SUCCESS; 361 362 ts_push_current_session(&sess->ts_sess); 363 res = load_stmm(spc); 364 ts_pop_current_session(); 365 vm_set_ctx(NULL); 366 if (res) { 367 sess->ts_sess.ctx = NULL; 368 spc->ta_ctx.ts_ctx.ops->destroy(&spc->ta_ctx.ts_ctx); 369 370 return res; 371 } 372 373 mutex_lock(&tee_ta_mutex); 374 spc->ta_ctx.is_initializing = false; 375 TAILQ_INSERT_TAIL(&tee_ctxes, &spc->ta_ctx, link); 376 mutex_unlock(&tee_ta_mutex); 377 378 return TEE_SUCCESS; 379 } 380 381 static TEE_Result stmm_enter_open_session(struct ts_session *s) 382 { 383 struct stmm_ctx *spc = to_stmm_ctx(s->ctx); 384 struct tee_ta_session *ta_sess = to_ta_session(s); 385 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE, 386 TEE_PARAM_TYPE_NONE, 387 TEE_PARAM_TYPE_NONE, 388 TEE_PARAM_TYPE_NONE); 389 390 if (ta_sess->param->types != exp_pt) 391 return TEE_ERROR_BAD_PARAMETERS; 392 393 if (spc->ta_ctx.is_initializing) { 394 /* StMM is initialized in stmm_init_session() */ 395 ta_sess->err_origin = TEE_ORIGIN_TEE; 396 return TEE_ERROR_BAD_STATE; 397 } 398 399 return TEE_SUCCESS; 400 } 401 402 static TEE_Result stmm_enter_invoke_cmd(struct ts_session *s, uint32_t cmd) 403 { 404 struct stmm_ctx *spc = to_stmm_ctx(s->ctx); 405 struct tee_ta_session *ta_sess = to_ta_session(s); 406 TEE_Result res = TEE_SUCCESS; 407 TEE_Result __maybe_unused tmp_res = TEE_SUCCESS; 408 unsigned int ns_buf_size = 0; 409 struct param_mem *mem = NULL; 410 void *va = NULL; 411 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 412 TEE_PARAM_TYPE_VALUE_OUTPUT, 413 TEE_PARAM_TYPE_NONE, 414 TEE_PARAM_TYPE_NONE); 415 416 if (cmd != PTA_STMM_CMD_COMMUNICATE) 417 return TEE_ERROR_BAD_PARAMETERS; 418 419 if (ta_sess->param->types != exp_pt) 420 return TEE_ERROR_BAD_PARAMETERS; 421 422 mem = &ta_sess->param->u[0].mem; 423 ns_buf_size = mem->size; 424 if (ns_buf_size > spc->ns_comm_buf_size) { 425 mem->size = spc->ns_comm_buf_size; 426 return TEE_ERROR_EXCESS_DATA; 427 } 428 429 res = mobj_inc_map(mem->mobj); 430 if (res) 431 return res; 432 433 va = mobj_get_va(mem->mobj, mem->offs, mem->size); 434 if (!va) { 435 EMSG("Can't get a valid VA for NS buffer"); 436 res = TEE_ERROR_BAD_PARAMETERS; 437 goto out_va; 438 } 439 440 #ifdef ARM64 441 spc->regs.x[0] = __FFA_MSG_SEND_DIRECT_REQ; 442 spc->regs.x[1] = (stmm_pta_id << 16) | stmm_id; 443 spc->regs.x[2] = FFA_PARAM_MBZ; 444 spc->regs.x[3] = spc->ns_comm_buf_addr; 445 spc->regs.x[4] = ns_buf_size; 446 spc->regs.x[5] = 0; 447 spc->regs.x[6] = 0; 448 spc->regs.x[7] = 0; 449 #endif 450 #ifdef ARM32 451 spc->regs.r0 = __FFA_MSG_SEND_DIRECT_REQ; 452 spc->regs.r1 = (stmm_pta_id << 16) | stmm_id; 453 spc->regs.r2 = FFA_PARAM_MBZ; 454 spc->regs.r3 = spc->ns_comm_buf_addr; 455 spc->regs.r4 = ns_buf_size; 456 spc->regs.r5 = 0; 457 spc->regs.r6 = 0; 458 spc->regs.r7 = 0; 459 #endif 460 461 ts_push_current_session(s); 462 463 memcpy((void *)spc->ns_comm_buf_addr, va, ns_buf_size); 464 465 res = stmm_enter_user_mode(spc); 466 if (res) 467 goto out_session; 468 /* 469 * Copy the SPM response from secure partition back to the non-secure 470 * buffer of the client that called us. 471 */ 472 #ifdef ARM64 473 ta_sess->param->u[1].val.a = spc->regs.x[4]; 474 #endif 475 #ifdef ARM32 476 ta_sess->param->u[1].val.a = spc->regs.r4; 477 #endif 478 479 memcpy(va, (void *)spc->ns_comm_buf_addr, ns_buf_size); 480 481 out_session: 482 ts_pop_current_session(); 483 out_va: 484 tmp_res = mobj_dec_map(mem->mobj); 485 assert(!tmp_res); 486 487 return res; 488 } 489 490 static void stmm_enter_close_session(struct ts_session *s __unused) 491 { 492 } 493 494 static void stmm_dump_state(struct ts_ctx *ctx) 495 { 496 user_mode_ctx_print_mappings(to_user_mode_ctx(ctx)); 497 } 498 DECLARE_KEEP_PAGER(stmm_dump_state); 499 500 static uint32_t stmm_get_instance_id(struct ts_ctx *ctx) 501 { 502 return to_stmm_ctx(ctx)->uctx.vm_info.asid; 503 } 504 505 static void stmm_ctx_destroy(struct ts_ctx *ctx) 506 { 507 struct stmm_ctx *spc = to_stmm_ctx(ctx); 508 509 vm_info_final(&spc->uctx); 510 free(spc); 511 } 512 513 static uint32_t sp_svc_get_mem_attr(vaddr_t va) 514 { 515 TEE_Result res = TEE_ERROR_BAD_PARAMETERS; 516 struct ts_session *sess = NULL; 517 struct stmm_ctx *spc = NULL; 518 uint16_t attrs = 0; 519 uint16_t perm = 0; 520 521 if (!va) 522 goto err; 523 524 sess = ts_get_current_session(); 525 spc = to_stmm_ctx(sess->ctx); 526 527 res = vm_get_prot(&spc->uctx, va, SMALL_PAGE_SIZE, &attrs); 528 if (res) 529 goto err; 530 531 if (attrs & TEE_MATTR_UR) 532 perm |= STMM_MEM_ATTR_ACCESS_RO; 533 else if (attrs & TEE_MATTR_UW) 534 perm |= STMM_MEM_ATTR_ACCESS_RW; 535 536 if (attrs & TEE_MATTR_UX) 537 perm |= STMM_MEM_ATTR_EXEC; 538 539 return perm; 540 err: 541 return STMM_RET_DENIED; 542 } 543 544 static int sp_svc_set_mem_attr(vaddr_t va, unsigned int nr_pages, uint32_t perm) 545 { 546 TEE_Result res = TEE_ERROR_BAD_PARAMETERS; 547 struct ts_session *sess = NULL; 548 struct stmm_ctx *spc = NULL; 549 size_t sz = 0; 550 uint32_t prot = 0; 551 552 if (!va || !nr_pages || MUL_OVERFLOW(nr_pages, SMALL_PAGE_SIZE, &sz)) 553 return STMM_RET_INVALID_PARAM; 554 555 if (perm & ~STMM_MEM_ATTR_ALL) 556 return STMM_RET_INVALID_PARAM; 557 558 sess = ts_get_current_session(); 559 spc = to_stmm_ctx(sess->ctx); 560 561 if ((perm & STMM_MEM_ATTR_ACCESS_MASK) == STMM_MEM_ATTR_ACCESS_RO) 562 prot |= TEE_MATTR_UR; 563 else if ((perm & STMM_MEM_ATTR_ACCESS_MASK) == STMM_MEM_ATTR_ACCESS_RW) 564 prot |= TEE_MATTR_URW; 565 566 if ((perm & STMM_MEM_ATTR_EXEC_NEVER) == STMM_MEM_ATTR_EXEC) 567 prot |= TEE_MATTR_UX; 568 569 res = vm_set_prot(&spc->uctx, va, sz, prot); 570 if (res) 571 return STMM_RET_DENIED; 572 573 return STMM_RET_SUCCESS; 574 } 575 576 #ifdef ARM64 577 static void save_sp_ctx(struct stmm_ctx *spc, 578 struct thread_scall_regs *regs) 579 { 580 size_t n = 0; 581 582 /* Save the return values from StMM */ 583 for (n = 0; n <= 7; n++) 584 spc->regs.x[n] = *(®s->x0 + n); 585 586 spc->regs.sp = regs->sp_el0; 587 spc->regs.pc = regs->elr; 588 spc->regs.cpsr = regs->spsr; 589 } 590 #endif 591 592 #ifdef ARM32 593 static void save_sp_ctx(struct stmm_ctx *spc, 594 struct thread_scall_regs *regs) 595 { 596 spc->regs.r0 = regs->r0; 597 spc->regs.r1 = regs->r1; 598 spc->regs.r2 = regs->r2; 599 spc->regs.r3 = regs->r3; 600 spc->regs.r4 = regs->r4; 601 spc->regs.r5 = regs->r5; 602 spc->regs.r6 = regs->r6; 603 spc->regs.r7 = regs->r7; 604 spc->regs.pc = regs->lr; 605 spc->regs.cpsr = regs->spsr; 606 spc->regs.usr_sp = thread_get_usr_sp(); 607 } 608 #endif 609 610 static void return_from_sp_helper(bool panic, uint32_t panic_code, 611 struct thread_scall_regs *regs) 612 { 613 struct ts_session *sess = ts_get_current_session(); 614 struct stmm_ctx *spc = to_stmm_ctx(sess->ctx); 615 616 if (panic) 617 spc->ta_ctx.panicked = true; 618 else 619 save_sp_ctx(spc, regs); 620 621 SVC_REGS_A0(regs) = 0; 622 SVC_REGS_A1(regs) = panic; 623 SVC_REGS_A2(regs) = panic_code; 624 } 625 626 static void service_compose_direct_resp(struct thread_scall_regs *regs, 627 uint32_t ret_val) 628 { 629 uint16_t src_id = 0; 630 uint16_t dst_id = 0; 631 632 /* extract from request */ 633 src_id = (SVC_REGS_A1(regs) >> 16) & UINT16_MAX; 634 dst_id = SVC_REGS_A1(regs) & UINT16_MAX; 635 636 /* compose message */ 637 SVC_REGS_A0(regs) = __FFA_MSG_SEND_DIRECT_RESP; 638 /* swap endpoint ids */ 639 SVC_REGS_A1(regs) = SHIFT_U32(dst_id, 16) | src_id; 640 SVC_REGS_A2(regs) = FFA_PARAM_MBZ; 641 SVC_REGS_A3(regs) = ret_val; 642 SVC_REGS_A4(regs) = 0; 643 SVC_REGS_A5(regs) = 0; 644 SVC_REGS_A6(regs) = 0; 645 SVC_REGS_A7(regs) = 0; 646 } 647 648 /* 649 * Combined read from secure partition, this will open, read and 650 * close the file object. 651 */ 652 static TEE_Result sec_storage_obj_read(unsigned long storage_id, char *obj_id, 653 unsigned long obj_id_len, void *data, 654 unsigned long len, unsigned long offset, 655 unsigned long flags) 656 { 657 const struct tee_file_operations *fops = NULL; 658 TEE_Result res = TEE_ERROR_BAD_STATE; 659 struct ts_session *sess = NULL; 660 struct tee_file_handle *fh = NULL; 661 struct tee_pobj *po = NULL; 662 size_t file_size = 0; 663 size_t read_len = 0; 664 665 fops = tee_svc_storage_file_ops(storage_id); 666 if (!fops) 667 return TEE_ERROR_ITEM_NOT_FOUND; 668 669 if (obj_id_len > TEE_OBJECT_ID_MAX_LEN) 670 return TEE_ERROR_BAD_PARAMETERS; 671 672 sess = ts_get_current_session(); 673 674 res = tee_pobj_get(&sess->ctx->uuid, obj_id, obj_id_len, flags, 675 TEE_POBJ_USAGE_OPEN, fops, &po); 676 if (res != TEE_SUCCESS) 677 return res; 678 679 res = po->fops->open(po, &file_size, &fh); 680 if (res != TEE_SUCCESS) 681 goto out; 682 683 read_len = len; 684 res = po->fops->read(fh, offset, NULL, data, &read_len); 685 if (res == TEE_ERROR_CORRUPT_OBJECT) { 686 EMSG("Object corrupt"); 687 po->fops->remove(po); 688 } else if (res == TEE_SUCCESS && len != read_len) { 689 res = TEE_ERROR_CORRUPT_OBJECT; 690 } 691 692 po->fops->close(&fh); 693 694 out: 695 tee_pobj_release(po); 696 697 return res; 698 } 699 700 /* 701 * Combined write from secure partition, this will create/open, write and 702 * close the file object. 703 */ 704 static TEE_Result sec_storage_obj_write(unsigned long storage_id, char *obj_id, 705 unsigned long obj_id_len, void *data, 706 unsigned long len, unsigned long offset, 707 unsigned long flags) 708 709 { 710 const struct tee_file_operations *fops = NULL; 711 struct ts_session *sess = NULL; 712 struct tee_file_handle *fh = NULL; 713 TEE_Result res = TEE_SUCCESS; 714 struct tee_pobj *po = NULL; 715 716 fops = tee_svc_storage_file_ops(storage_id); 717 if (!fops) 718 return TEE_ERROR_ITEM_NOT_FOUND; 719 720 if (obj_id_len > TEE_OBJECT_ID_MAX_LEN) 721 return TEE_ERROR_BAD_PARAMETERS; 722 723 sess = ts_get_current_session(); 724 725 res = tee_pobj_get(&sess->ctx->uuid, obj_id, obj_id_len, flags, 726 TEE_POBJ_USAGE_OPEN, fops, &po); 727 if (res != TEE_SUCCESS) 728 return res; 729 730 res = po->fops->open(po, NULL, &fh); 731 if (res == TEE_ERROR_ITEM_NOT_FOUND) 732 res = po->fops->create(po, false, NULL, 0, NULL, 0, 733 NULL, NULL, 0, &fh); 734 if (res == TEE_SUCCESS) { 735 res = po->fops->write(fh, offset, NULL, data, len); 736 po->fops->close(&fh); 737 } 738 739 tee_pobj_release(po); 740 741 return res; 742 } 743 744 static void stmm_handle_mem_mgr_service(struct thread_scall_regs *regs) 745 { 746 uint32_t action = SVC_REGS_A3(regs); 747 uintptr_t va = SVC_REGS_A4(regs); 748 uint32_t nr_pages = SVC_REGS_A5(regs); 749 uint32_t perm = SVC_REGS_A6(regs); 750 751 switch (action) { 752 case __FFA_SVC_MEMORY_ATTRIBUTES_GET: 753 service_compose_direct_resp(regs, sp_svc_get_mem_attr(va)); 754 break; 755 case __FFA_SVC_MEMORY_ATTRIBUTES_SET: 756 service_compose_direct_resp(regs, 757 sp_svc_set_mem_attr(va, nr_pages, 758 perm)); 759 break; 760 default: 761 EMSG("Undefined service id %#"PRIx32, action); 762 service_compose_direct_resp(regs, STMM_RET_INVALID_PARAM); 763 break; 764 } 765 } 766 767 static uint32_t tee2stmm_ret_val(TEE_Result res) 768 { 769 switch (res) { 770 case TEE_SUCCESS: 771 return STMM_RET_SUCCESS; 772 case TEE_ERROR_NOT_SUPPORTED: 773 return STMM_RET_NOT_SUPPORTED; 774 case TEE_ERROR_ACCESS_DENIED: 775 return STMM_RET_DENIED; 776 case TEE_ERROR_OUT_OF_MEMORY: 777 return STMM_RET_NO_MEM; 778 case TEE_ERROR_BAD_PARAMETERS: 779 default: 780 return STMM_RET_INVALID_PARAM; 781 } 782 } 783 784 #define FILENAME "EFI_VARS" 785 static void stmm_handle_storage_service(struct thread_scall_regs *regs) 786 { 787 uint32_t flags = TEE_DATA_FLAG_ACCESS_READ | 788 TEE_DATA_FLAG_ACCESS_WRITE | 789 TEE_DATA_FLAG_SHARE_READ | 790 TEE_DATA_FLAG_SHARE_WRITE; 791 uint32_t action = SVC_REGS_A3(regs); 792 void *va = (void *)SVC_REGS_A4(regs); 793 unsigned long len = SVC_REGS_A5(regs); 794 unsigned long offset = SVC_REGS_A6(regs); 795 char obj_id[] = FILENAME; 796 size_t obj_id_len = strlen(obj_id); 797 TEE_Result res = TEE_SUCCESS; 798 uint32_t stmm_rc = STMM_RET_INVALID_PARAM; 799 800 switch (action) { 801 case __FFA_SVC_RPMB_READ: 802 DMSG("RPMB read"); 803 res = sec_storage_obj_read(TEE_STORAGE_PRIVATE_RPMB, obj_id, 804 obj_id_len, va, len, offset, flags); 805 stmm_rc = tee2stmm_ret_val(res); 806 break; 807 case __FFA_SVC_RPMB_WRITE: 808 DMSG("RPMB write"); 809 res = sec_storage_obj_write(TEE_STORAGE_PRIVATE_RPMB, obj_id, 810 obj_id_len, va, len, offset, flags); 811 stmm_rc = tee2stmm_ret_val(res); 812 break; 813 default: 814 EMSG("Undefined service id %#"PRIx32, action); 815 break; 816 } 817 818 service_compose_direct_resp(regs, stmm_rc); 819 } 820 821 static void spm_eret_error(int32_t error_code, struct thread_scall_regs *regs) 822 { 823 SVC_REGS_A0(regs) = FFA_ERROR; 824 SVC_REGS_A1(regs) = FFA_PARAM_MBZ; 825 SVC_REGS_A2(regs) = error_code; 826 SVC_REGS_A3(regs) = FFA_PARAM_MBZ; 827 SVC_REGS_A4(regs) = FFA_PARAM_MBZ; 828 SVC_REGS_A5(regs) = FFA_PARAM_MBZ; 829 SVC_REGS_A6(regs) = FFA_PARAM_MBZ; 830 SVC_REGS_A7(regs) = FFA_PARAM_MBZ; 831 } 832 833 static void spm_handle_direct_req(struct thread_scall_regs *regs) 834 { 835 uint16_t dst_id = SVC_REGS_A1(regs) & UINT16_MAX; 836 837 if (dst_id == mem_mgr_id) { 838 stmm_handle_mem_mgr_service(regs); 839 } else if (dst_id == ffa_storage_id) { 840 stmm_handle_storage_service(regs); 841 } else { 842 EMSG("Undefined endpoint id %#"PRIx16, dst_id); 843 spm_eret_error(STMM_RET_INVALID_PARAM, regs); 844 } 845 } 846 847 /* Return true if returning to SP, false if returning to caller */ 848 static bool spm_handle_scall(struct thread_scall_regs *regs) 849 { 850 #ifdef ARM64 851 uint64_t *a0 = ®s->x0; 852 #endif 853 #ifdef ARM32 854 uint32_t *a0 = ®s->r0; 855 #endif 856 857 switch (*a0) { 858 case FFA_VERSION: 859 DMSG("Received FFA version"); 860 *a0 = FFA_VERSION_1_2; 861 return true; 862 case __FFA_MSG_SEND_DIRECT_RESP: 863 DMSG("Received FFA direct response"); 864 return_from_sp_helper(false, 0, regs); 865 return false; 866 case __FFA_MSG_SEND_DIRECT_REQ: 867 DMSG("Received FFA direct request"); 868 spm_handle_direct_req(regs); 869 return true; 870 default: 871 EMSG("Undefined syscall %#"PRIx32, (uint32_t)*a0); 872 return_from_sp_helper(true /*panic*/, 0xabcd, regs); 873 return false; 874 } 875 } 876 877 /* 878 * Note: this variable is weak just to ease breaking its dependency chain 879 * when added to the unpaged area. 880 */ 881 const struct ts_ops stmm_sp_ops __weak __relrodata_unpaged("stmm_sp_ops") = { 882 .enter_open_session = stmm_enter_open_session, 883 .enter_invoke_cmd = stmm_enter_invoke_cmd, 884 .enter_close_session = stmm_enter_close_session, 885 .dump_state = stmm_dump_state, 886 .destroy = stmm_ctx_destroy, 887 .get_instance_id = stmm_get_instance_id, 888 .handle_scall = spm_handle_scall, 889 }; 890