1 /* 2 * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <errno.h> 9 10 #include <arch_helpers.h> 11 #include <bl31/bl31.h> 12 #include <bl31/ehf.h> 13 #include <common/debug.h> 14 #include <common/fdt_wrappers.h> 15 #include <common/runtime_svc.h> 16 #include <lib/el3_runtime/context_mgmt.h> 17 #include <lib/smccc.h> 18 #include <lib/utils.h> 19 #include <lib/xlat_tables/xlat_tables_v2.h> 20 #include <libfdt.h> 21 #include <plat/common/platform.h> 22 #include <services/ffa_svc.h> 23 #include <services/spmc_svc.h> 24 #include <services/spmd_svc.h> 25 #include "spmc.h" 26 27 #include <platform_def.h> 28 29 /* 30 * Allocate a secure partition descriptor to describe each SP in the system that 31 * does not reside at EL3. 32 */ 33 static struct secure_partition_desc sp_desc[SECURE_PARTITION_COUNT]; 34 35 /* 36 * Allocate an NS endpoint descriptor to describe each VM and the Hypervisor in 37 * the system that interacts with a SP. It is used to track the Hypervisor 38 * buffer pair, version and ID for now. It could be extended to track VM 39 * properties when the SPMC supports indirect messaging. 40 */ 41 static struct ns_endpoint_desc ns_ep_desc[NS_PARTITION_COUNT]; 42 43 /* 44 * Helper function to obtain the descriptor of the last SP to whom control was 45 * handed to on this physical cpu. Currently, we assume there is only one SP. 46 * TODO: Expand to track multiple partitions when required. 47 */ 48 struct secure_partition_desc *spmc_get_current_sp_ctx(void) 49 { 50 return &(sp_desc[ACTIVE_SP_DESC_INDEX]); 51 } 52 53 /* 54 * Helper function to obtain the execution context of an SP on the 55 * current physical cpu. 56 */ 57 struct sp_exec_ctx *spmc_get_sp_ec(struct secure_partition_desc *sp) 58 { 59 return &(sp->ec[get_ec_index(sp)]); 60 } 61 62 /* Helper function to get pointer to SP context from its ID. */ 63 struct secure_partition_desc *spmc_get_sp_ctx(uint16_t id) 64 { 65 /* Check for SWd Partitions. */ 66 for (unsigned int i = 0U; i < SECURE_PARTITION_COUNT; i++) { 67 if (sp_desc[i].sp_id == id) { 68 return &(sp_desc[i]); 69 } 70 } 71 return NULL; 72 } 73 74 /****************************************************************************** 75 * This function returns to the place where spmc_sp_synchronous_entry() was 76 * called originally. 77 ******************************************************************************/ 78 __dead2 void spmc_sp_synchronous_exit(struct sp_exec_ctx *ec, uint64_t rc) 79 { 80 /* 81 * The SPM must have initiated the original request through a 82 * synchronous entry into the secure partition. Jump back to the 83 * original C runtime context with the value of rc in x0; 84 */ 85 spm_secure_partition_exit(ec->c_rt_ctx, rc); 86 87 panic(); 88 } 89 90 /******************************************************************************* 91 * Return FFA_ERROR with specified error code. 92 ******************************************************************************/ 93 uint64_t spmc_ffa_error_return(void *handle, int error_code) 94 { 95 SMC_RET8(handle, FFA_ERROR, 96 FFA_TARGET_INFO_MBZ, error_code, 97 FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, 98 FFA_PARAM_MBZ, FFA_PARAM_MBZ); 99 } 100 101 /****************************************************************************** 102 * Helper function to validate a secure partition ID to ensure it does not 103 * conflict with any other FF-A component and follows the convention to 104 * indicate it resides within the secure world. 105 ******************************************************************************/ 106 bool is_ffa_secure_id_valid(uint16_t partition_id) 107 { 108 /* Ensure the ID is not the invalid partition ID. */ 109 if (partition_id == INV_SP_ID) { 110 return false; 111 } 112 113 /* Ensure the ID is not the SPMD ID. */ 114 if (partition_id == SPMD_DIRECT_MSG_ENDPOINT_ID) { 115 return false; 116 } 117 118 /* 119 * Ensure the ID follows the convention to indicate it resides 120 * in the secure world. 121 */ 122 if (!ffa_is_secure_world_id(partition_id)) { 123 return false; 124 } 125 126 /* Ensure we don't conflict with the SPMC partition ID. */ 127 if (partition_id == FFA_SPMC_ID) { 128 return false; 129 } 130 131 /* Ensure we do not already have an SP context with this ID. */ 132 if (spmc_get_sp_ctx(partition_id)) { 133 return false; 134 } 135 136 return true; 137 } 138 139 /******************************************************************************* 140 * This function either forwards the request to the other world or returns 141 * with an ERET depending on the source of the call. 142 ******************************************************************************/ 143 static uint64_t spmc_smc_return(uint32_t smc_fid, 144 bool secure_origin, 145 uint64_t x1, 146 uint64_t x2, 147 uint64_t x3, 148 uint64_t x4, 149 void *handle, 150 void *cookie, 151 uint64_t flags, 152 uint16_t dst_id) 153 { 154 /* If the destination is in the normal world always go via the SPMD. */ 155 if (ffa_is_normal_world_id(dst_id)) { 156 return spmd_smc_handler(smc_fid, x1, x2, x3, x4, 157 cookie, handle, flags); 158 } 159 /* 160 * If the caller is secure and we want to return to the secure world, 161 * ERET directly. 162 */ 163 else if (secure_origin && ffa_is_secure_world_id(dst_id)) { 164 SMC_RET5(handle, smc_fid, x1, x2, x3, x4); 165 } 166 /* If we originated in the normal world then switch contexts. */ 167 else if (!secure_origin && ffa_is_secure_world_id(dst_id)) { 168 return spmd_smc_switch_state(smc_fid, secure_origin, x1, x2, 169 x3, x4, handle); 170 } else { 171 /* Unknown State. */ 172 panic(); 173 } 174 175 /* Shouldn't be Reached. */ 176 return 0; 177 } 178 179 /******************************************************************************* 180 * FF-A ABI Handlers. 181 ******************************************************************************/ 182 /******************************************************************************* 183 * This function handles the FFA_MSG_WAIT SMC to allow an SP to relinquish its 184 * cycles. 185 ******************************************************************************/ 186 static uint64_t msg_wait_handler(uint32_t smc_fid, 187 bool secure_origin, 188 uint64_t x1, 189 uint64_t x2, 190 uint64_t x3, 191 uint64_t x4, 192 void *cookie, 193 void *handle, 194 uint64_t flags) 195 { 196 struct secure_partition_desc *sp; 197 unsigned int idx; 198 199 /* 200 * Check that the response did not originate from the Normal world as 201 * only the secure world can call this ABI. 202 */ 203 if (!secure_origin) { 204 VERBOSE("Normal world cannot call FFA_MSG_WAIT.\n"); 205 return spmc_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED); 206 } 207 208 /* Get the descriptor of the SP that invoked FFA_MSG_WAIT. */ 209 sp = spmc_get_current_sp_ctx(); 210 if (sp == NULL) { 211 return spmc_ffa_error_return(handle, 212 FFA_ERROR_INVALID_PARAMETER); 213 } 214 215 /* 216 * Get the execution context of the SP that invoked FFA_MSG_WAIT. 217 */ 218 idx = get_ec_index(sp); 219 220 /* Ensure SP execution context was in the right runtime model. */ 221 if (sp->ec[idx].rt_model == RT_MODEL_DIR_REQ) { 222 return spmc_ffa_error_return(handle, FFA_ERROR_DENIED); 223 } 224 225 /* Sanity check the state is being tracked correctly in the SPMC. */ 226 assert(sp->ec[idx].rt_state == RT_STATE_RUNNING); 227 228 /* 229 * Perform a synchronous exit if the partition was initialising. The 230 * state is updated after the exit. 231 */ 232 if (sp->ec[idx].rt_model == RT_MODEL_INIT) { 233 spmc_sp_synchronous_exit(&sp->ec[idx], x4); 234 /* Should not get here */ 235 panic(); 236 } 237 238 /* Update the state of the SP execution context. */ 239 sp->ec[idx].rt_state = RT_STATE_WAITING; 240 241 /* Resume normal world if a secure interrupt was handled. */ 242 if (sp->ec[idx].rt_model == RT_MODEL_INTR) { 243 /* FFA_MSG_WAIT can only be called from the secure world. */ 244 unsigned int secure_state_in = SECURE; 245 unsigned int secure_state_out = NON_SECURE; 246 247 cm_el1_sysregs_context_save(secure_state_in); 248 cm_el1_sysregs_context_restore(secure_state_out); 249 cm_set_next_eret_context(secure_state_out); 250 SMC_RET0(cm_get_context(secure_state_out)); 251 } 252 253 /* Forward the response to the Normal world. */ 254 return spmc_smc_return(smc_fid, secure_origin, x1, x2, x3, x4, 255 handle, cookie, flags, FFA_NWD_ID); 256 } 257 258 static uint64_t ffa_error_handler(uint32_t smc_fid, 259 bool secure_origin, 260 uint64_t x1, 261 uint64_t x2, 262 uint64_t x3, 263 uint64_t x4, 264 void *cookie, 265 void *handle, 266 uint64_t flags) 267 { 268 struct secure_partition_desc *sp; 269 unsigned int idx; 270 271 /* Check that the response did not originate from the Normal world. */ 272 if (!secure_origin) { 273 return spmc_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED); 274 } 275 276 /* Get the descriptor of the SP that invoked FFA_ERROR. */ 277 sp = spmc_get_current_sp_ctx(); 278 if (sp == NULL) { 279 return spmc_ffa_error_return(handle, 280 FFA_ERROR_INVALID_PARAMETER); 281 } 282 283 /* Get the execution context of the SP that invoked FFA_ERROR. */ 284 idx = get_ec_index(sp); 285 286 /* 287 * We only expect FFA_ERROR to be received during SP initialisation 288 * otherwise this is an invalid call. 289 */ 290 if (sp->ec[idx].rt_model == RT_MODEL_INIT) { 291 ERROR("SP 0x%x failed to initialize.\n", sp->sp_id); 292 spmc_sp_synchronous_exit(&sp->ec[idx], x2); 293 /* Should not get here. */ 294 panic(); 295 } 296 297 return spmc_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED); 298 } 299 300 /******************************************************************************* 301 * This function will parse the Secure Partition Manifest. From manifest, it 302 * will fetch details for preparing Secure partition image context and secure 303 * partition image boot arguments if any. 304 ******************************************************************************/ 305 static int sp_manifest_parse(void *sp_manifest, int offset, 306 struct secure_partition_desc *sp, 307 entry_point_info_t *ep_info) 308 { 309 int32_t ret, node; 310 uint32_t config_32; 311 312 /* 313 * Look for the mandatory fields that are expected to be present in 314 * the SP manifests. 315 */ 316 node = fdt_path_offset(sp_manifest, "/"); 317 if (node < 0) { 318 ERROR("Did not find root node.\n"); 319 return node; 320 } 321 322 ret = fdt_read_uint32(sp_manifest, node, "exception-level", &config_32); 323 if (ret != 0) { 324 ERROR("Missing SP Exception Level information.\n"); 325 return ret; 326 } 327 328 sp->runtime_el = config_32; 329 330 ret = fdt_read_uint32(sp_manifest, node, "ffa-version", &config_32); 331 if (ret != 0) { 332 ERROR("Missing Secure Partition FF-A Version.\n"); 333 return ret; 334 } 335 336 sp->ffa_version = config_32; 337 338 ret = fdt_read_uint32(sp_manifest, node, "execution-state", &config_32); 339 if (ret != 0) { 340 ERROR("Missing Secure Partition Execution State.\n"); 341 return ret; 342 } 343 344 sp->execution_state = config_32; 345 346 /* 347 * Look for the optional fields that are expected to be present in 348 * an SP manifest. 349 */ 350 ret = fdt_read_uint32(sp_manifest, node, "id", &config_32); 351 if (ret != 0) { 352 WARN("Missing Secure Partition ID.\n"); 353 } else { 354 if (!is_ffa_secure_id_valid(config_32)) { 355 ERROR("Invalid Secure Partition ID (0x%x).\n", 356 config_32); 357 return -EINVAL; 358 } 359 sp->sp_id = config_32; 360 } 361 362 return 0; 363 } 364 365 /******************************************************************************* 366 * This function gets the Secure Partition Manifest base and maps the manifest 367 * region. 368 * Currently only one Secure Partition manifest is considered which is used to 369 * prepare the context for the single Secure Partition. 370 ******************************************************************************/ 371 static int find_and_prepare_sp_context(void) 372 { 373 void *sp_manifest; 374 uintptr_t manifest_base; 375 uintptr_t manifest_base_align; 376 entry_point_info_t *next_image_ep_info; 377 int32_t ret; 378 struct secure_partition_desc *sp; 379 380 next_image_ep_info = bl31_plat_get_next_image_ep_info(SECURE); 381 if (next_image_ep_info == NULL) { 382 WARN("No Secure Partition image provided by BL2.\n"); 383 return -ENOENT; 384 } 385 386 sp_manifest = (void *)next_image_ep_info->args.arg0; 387 if (sp_manifest == NULL) { 388 WARN("Secure Partition manifest absent.\n"); 389 return -ENOENT; 390 } 391 392 manifest_base = (uintptr_t)sp_manifest; 393 manifest_base_align = page_align(manifest_base, DOWN); 394 395 /* 396 * Map the secure partition manifest region in the EL3 translation 397 * regime. 398 * Map an area equal to (2 * PAGE_SIZE) for now. During manifest base 399 * alignment the region of 1 PAGE_SIZE from manifest align base may 400 * not completely accommodate the secure partition manifest region. 401 */ 402 ret = mmap_add_dynamic_region((unsigned long long)manifest_base_align, 403 manifest_base_align, 404 PAGE_SIZE * 2, 405 MT_RO_DATA); 406 if (ret != 0) { 407 ERROR("Error while mapping SP manifest (%d).\n", ret); 408 return ret; 409 } 410 411 ret = fdt_node_offset_by_compatible(sp_manifest, -1, 412 "arm,ffa-manifest-1.0"); 413 if (ret < 0) { 414 ERROR("Error happened in SP manifest reading.\n"); 415 return -EINVAL; 416 } 417 418 /* 419 * Store the size of the manifest so that it can be used later to pass 420 * the manifest as boot information later. 421 */ 422 next_image_ep_info->args.arg1 = fdt_totalsize(sp_manifest); 423 INFO("Manifest size = %lu bytes.\n", next_image_ep_info->args.arg1); 424 425 /* 426 * Select an SP descriptor for initialising the partition's execution 427 * context on the primary CPU. 428 */ 429 sp = spmc_get_current_sp_ctx(); 430 431 /* Initialize entry point information for the SP */ 432 SET_PARAM_HEAD(next_image_ep_info, PARAM_EP, VERSION_1, 433 SECURE | EP_ST_ENABLE); 434 435 /* Parse the SP manifest. */ 436 ret = sp_manifest_parse(sp_manifest, ret, sp, next_image_ep_info); 437 if (ret != 0) { 438 ERROR("Error in Secure Partition manifest parsing.\n"); 439 return ret; 440 } 441 442 /* Check that the runtime EL in the manifest was correct. */ 443 if (sp->runtime_el != S_EL1) { 444 ERROR("Unexpected runtime EL: %d\n", sp->runtime_el); 445 return -EINVAL; 446 } 447 448 /* Perform any common initialisation. */ 449 spmc_sp_common_setup(sp, next_image_ep_info); 450 451 /* Perform any initialisation specific to S-EL1 SPs. */ 452 spmc_el1_sp_setup(sp, next_image_ep_info); 453 454 /* Initialize the SP context with the required ep info. */ 455 spmc_sp_common_ep_commit(sp, next_image_ep_info); 456 457 return 0; 458 } 459 460 /******************************************************************************* 461 * This function takes an SP context pointer and performs a synchronous entry 462 * into it. 463 ******************************************************************************/ 464 uint64_t spmc_sp_synchronous_entry(struct sp_exec_ctx *ec) 465 { 466 uint64_t rc; 467 468 assert(ec != NULL); 469 470 /* Assign the context of the SP to this CPU */ 471 cm_set_context(&(ec->cpu_ctx), SECURE); 472 473 /* Restore the context assigned above */ 474 cm_el1_sysregs_context_restore(SECURE); 475 cm_set_next_eret_context(SECURE); 476 477 /* Invalidate TLBs at EL1. */ 478 tlbivmalle1(); 479 dsbish(); 480 481 /* Enter Secure Partition */ 482 rc = spm_secure_partition_enter(&ec->c_rt_ctx); 483 484 /* Save secure state */ 485 cm_el1_sysregs_context_save(SECURE); 486 487 return rc; 488 } 489 490 /******************************************************************************* 491 * SPMC Helper Functions. 492 ******************************************************************************/ 493 static int32_t sp_init(void) 494 { 495 uint64_t rc; 496 struct secure_partition_desc *sp; 497 struct sp_exec_ctx *ec; 498 499 sp = spmc_get_current_sp_ctx(); 500 ec = spmc_get_sp_ec(sp); 501 ec->rt_model = RT_MODEL_INIT; 502 ec->rt_state = RT_STATE_RUNNING; 503 504 INFO("Secure Partition (0x%x) init start.\n", sp->sp_id); 505 506 rc = spmc_sp_synchronous_entry(ec); 507 if (rc != 0) { 508 /* Indicate SP init was not successful. */ 509 ERROR("SP (0x%x) failed to initialize (%lu).\n", 510 sp->sp_id, rc); 511 return 0; 512 } 513 514 ec->rt_state = RT_STATE_WAITING; 515 INFO("Secure Partition initialized.\n"); 516 517 return 1; 518 } 519 520 static void initalize_sp_descs(void) 521 { 522 struct secure_partition_desc *sp; 523 524 for (unsigned int i = 0U; i < SECURE_PARTITION_COUNT; i++) { 525 sp = &sp_desc[i]; 526 sp->sp_id = INV_SP_ID; 527 sp->secondary_ep = 0; 528 } 529 } 530 531 static void initalize_ns_ep_descs(void) 532 { 533 struct ns_endpoint_desc *ns_ep; 534 535 for (unsigned int i = 0U; i < NS_PARTITION_COUNT; i++) { 536 ns_ep = &ns_ep_desc[i]; 537 /* 538 * Clashes with the Hypervisor ID but will not be a 539 * problem in practice. 540 */ 541 ns_ep->ns_ep_id = 0; 542 ns_ep->ffa_version = 0; 543 } 544 } 545 546 /******************************************************************************* 547 * Initialize SPMC attributes for the SPMD. 548 ******************************************************************************/ 549 void spmc_populate_attrs(spmc_manifest_attribute_t *spmc_attrs) 550 { 551 spmc_attrs->major_version = FFA_VERSION_MAJOR; 552 spmc_attrs->minor_version = FFA_VERSION_MINOR; 553 spmc_attrs->exec_state = MODE_RW_64; 554 spmc_attrs->spmc_id = FFA_SPMC_ID; 555 } 556 557 /******************************************************************************* 558 * Initialize contexts of all Secure Partitions. 559 ******************************************************************************/ 560 int32_t spmc_setup(void) 561 { 562 int32_t ret; 563 564 /* Initialize endpoint descriptors */ 565 initalize_sp_descs(); 566 initalize_ns_ep_descs(); 567 568 /* Perform physical SP setup. */ 569 570 /* Disable MMU at EL1 (initialized by BL2) */ 571 disable_mmu_icache_el1(); 572 573 /* Initialize context of the SP */ 574 INFO("Secure Partition context setup start.\n"); 575 576 ret = find_and_prepare_sp_context(); 577 if (ret != 0) { 578 ERROR("Error in SP finding and context preparation.\n"); 579 return ret; 580 } 581 582 /* Register init function for deferred init. */ 583 bl31_register_bl32_init(&sp_init); 584 585 INFO("Secure Partition setup done.\n"); 586 587 return 0; 588 } 589 590 /******************************************************************************* 591 * Secure Partition Manager SMC handler. 592 ******************************************************************************/ 593 uint64_t spmc_smc_handler(uint32_t smc_fid, 594 bool secure_origin, 595 uint64_t x1, 596 uint64_t x2, 597 uint64_t x3, 598 uint64_t x4, 599 void *cookie, 600 void *handle, 601 uint64_t flags) 602 { 603 switch (smc_fid) { 604 605 case FFA_MSG_WAIT: 606 return msg_wait_handler(smc_fid, secure_origin, x1, x2, x3, x4, 607 cookie, handle, flags); 608 609 case FFA_ERROR: 610 return ffa_error_handler(smc_fid, secure_origin, x1, x2, x3, x4, 611 cookie, handle, flags); 612 613 default: 614 WARN("Unsupported FF-A call 0x%08x.\n", smc_fid); 615 break; 616 } 617 return spmc_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED); 618 } 619