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