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 /******************************************************************************* 259 * This function will parse the Secure Partition Manifest. From manifest, it 260 * will fetch details for preparing Secure partition image context and secure 261 * partition image boot arguments if any. 262 ******************************************************************************/ 263 static int sp_manifest_parse(void *sp_manifest, int offset, 264 struct secure_partition_desc *sp, 265 entry_point_info_t *ep_info) 266 { 267 int32_t ret, node; 268 uint32_t config_32; 269 270 /* 271 * Look for the mandatory fields that are expected to be present in 272 * the SP manifests. 273 */ 274 node = fdt_path_offset(sp_manifest, "/"); 275 if (node < 0) { 276 ERROR("Did not find root node.\n"); 277 return node; 278 } 279 280 ret = fdt_read_uint32(sp_manifest, node, "exception-level", &config_32); 281 if (ret != 0) { 282 ERROR("Missing SP Exception Level information.\n"); 283 return ret; 284 } 285 286 sp->runtime_el = config_32; 287 288 ret = fdt_read_uint32(sp_manifest, node, "ffa-version", &config_32); 289 if (ret != 0) { 290 ERROR("Missing Secure Partition FF-A Version.\n"); 291 return ret; 292 } 293 294 sp->ffa_version = config_32; 295 296 ret = fdt_read_uint32(sp_manifest, node, "execution-state", &config_32); 297 if (ret != 0) { 298 ERROR("Missing Secure Partition Execution State.\n"); 299 return ret; 300 } 301 302 sp->execution_state = config_32; 303 304 /* 305 * Look for the optional fields that are expected to be present in 306 * an SP manifest. 307 */ 308 ret = fdt_read_uint32(sp_manifest, node, "id", &config_32); 309 if (ret != 0) { 310 WARN("Missing Secure Partition ID.\n"); 311 } else { 312 if (!is_ffa_secure_id_valid(config_32)) { 313 ERROR("Invalid Secure Partition ID (0x%x).\n", 314 config_32); 315 return -EINVAL; 316 } 317 sp->sp_id = config_32; 318 } 319 320 return 0; 321 } 322 323 /******************************************************************************* 324 * This function gets the Secure Partition Manifest base and maps the manifest 325 * region. 326 * Currently only one Secure Partition manifest is considered which is used to 327 * prepare the context for the single Secure Partition. 328 ******************************************************************************/ 329 static int find_and_prepare_sp_context(void) 330 { 331 void *sp_manifest; 332 uintptr_t manifest_base; 333 uintptr_t manifest_base_align; 334 entry_point_info_t *next_image_ep_info; 335 int32_t ret; 336 struct secure_partition_desc *sp; 337 338 next_image_ep_info = bl31_plat_get_next_image_ep_info(SECURE); 339 if (next_image_ep_info == NULL) { 340 WARN("No Secure Partition image provided by BL2.\n"); 341 return -ENOENT; 342 } 343 344 sp_manifest = (void *)next_image_ep_info->args.arg0; 345 if (sp_manifest == NULL) { 346 WARN("Secure Partition manifest absent.\n"); 347 return -ENOENT; 348 } 349 350 manifest_base = (uintptr_t)sp_manifest; 351 manifest_base_align = page_align(manifest_base, DOWN); 352 353 /* 354 * Map the secure partition manifest region in the EL3 translation 355 * regime. 356 * Map an area equal to (2 * PAGE_SIZE) for now. During manifest base 357 * alignment the region of 1 PAGE_SIZE from manifest align base may 358 * not completely accommodate the secure partition manifest region. 359 */ 360 ret = mmap_add_dynamic_region((unsigned long long)manifest_base_align, 361 manifest_base_align, 362 PAGE_SIZE * 2, 363 MT_RO_DATA); 364 if (ret != 0) { 365 ERROR("Error while mapping SP manifest (%d).\n", ret); 366 return ret; 367 } 368 369 ret = fdt_node_offset_by_compatible(sp_manifest, -1, 370 "arm,ffa-manifest-1.0"); 371 if (ret < 0) { 372 ERROR("Error happened in SP manifest reading.\n"); 373 return -EINVAL; 374 } 375 376 /* 377 * Store the size of the manifest so that it can be used later to pass 378 * the manifest as boot information later. 379 */ 380 next_image_ep_info->args.arg1 = fdt_totalsize(sp_manifest); 381 INFO("Manifest size = %lu bytes.\n", next_image_ep_info->args.arg1); 382 383 /* 384 * Select an SP descriptor for initialising the partition's execution 385 * context on the primary CPU. 386 */ 387 sp = spmc_get_current_sp_ctx(); 388 389 /* Initialize entry point information for the SP */ 390 SET_PARAM_HEAD(next_image_ep_info, PARAM_EP, VERSION_1, 391 SECURE | EP_ST_ENABLE); 392 393 /* Parse the SP manifest. */ 394 ret = sp_manifest_parse(sp_manifest, ret, sp, next_image_ep_info); 395 if (ret != 0) { 396 ERROR("Error in Secure Partition manifest parsing.\n"); 397 return ret; 398 } 399 400 /* Check that the runtime EL in the manifest was correct. */ 401 if (sp->runtime_el != S_EL1) { 402 ERROR("Unexpected runtime EL: %d\n", sp->runtime_el); 403 return -EINVAL; 404 } 405 406 /* Perform any common initialisation. */ 407 spmc_sp_common_setup(sp, next_image_ep_info); 408 409 /* Perform any initialisation specific to S-EL1 SPs. */ 410 spmc_el1_sp_setup(sp, next_image_ep_info); 411 412 /* Initialize the SP context with the required ep info. */ 413 spmc_sp_common_ep_commit(sp, next_image_ep_info); 414 415 return 0; 416 } 417 418 /******************************************************************************* 419 * This function takes an SP context pointer and performs a synchronous entry 420 * into it. 421 ******************************************************************************/ 422 uint64_t spmc_sp_synchronous_entry(struct sp_exec_ctx *ec) 423 { 424 uint64_t rc; 425 426 assert(ec != NULL); 427 428 /* Assign the context of the SP to this CPU */ 429 cm_set_context(&(ec->cpu_ctx), SECURE); 430 431 /* Restore the context assigned above */ 432 cm_el1_sysregs_context_restore(SECURE); 433 cm_set_next_eret_context(SECURE); 434 435 /* Invalidate TLBs at EL1. */ 436 tlbivmalle1(); 437 dsbish(); 438 439 /* Enter Secure Partition */ 440 rc = spm_secure_partition_enter(&ec->c_rt_ctx); 441 442 /* Save secure state */ 443 cm_el1_sysregs_context_save(SECURE); 444 445 return rc; 446 } 447 448 /******************************************************************************* 449 * SPMC Helper Functions. 450 ******************************************************************************/ 451 static int32_t sp_init(void) 452 { 453 uint64_t rc; 454 struct secure_partition_desc *sp; 455 struct sp_exec_ctx *ec; 456 457 sp = spmc_get_current_sp_ctx(); 458 ec = spmc_get_sp_ec(sp); 459 ec->rt_model = RT_MODEL_INIT; 460 ec->rt_state = RT_STATE_RUNNING; 461 462 INFO("Secure Partition (0x%x) init start.\n", sp->sp_id); 463 464 rc = spmc_sp_synchronous_entry(ec); 465 if (rc != 0) { 466 /* Indicate SP init was not successful. */ 467 ERROR("SP (0x%x) failed to initialize (%lu).\n", 468 sp->sp_id, rc); 469 return 0; 470 } 471 472 ec->rt_state = RT_STATE_WAITING; 473 INFO("Secure Partition initialized.\n"); 474 475 return 1; 476 } 477 478 static void initalize_sp_descs(void) 479 { 480 struct secure_partition_desc *sp; 481 482 for (unsigned int i = 0U; i < SECURE_PARTITION_COUNT; i++) { 483 sp = &sp_desc[i]; 484 sp->sp_id = INV_SP_ID; 485 sp->secondary_ep = 0; 486 } 487 } 488 489 static void initalize_ns_ep_descs(void) 490 { 491 struct ns_endpoint_desc *ns_ep; 492 493 for (unsigned int i = 0U; i < NS_PARTITION_COUNT; i++) { 494 ns_ep = &ns_ep_desc[i]; 495 /* 496 * Clashes with the Hypervisor ID but will not be a 497 * problem in practice. 498 */ 499 ns_ep->ns_ep_id = 0; 500 ns_ep->ffa_version = 0; 501 } 502 } 503 504 /******************************************************************************* 505 * Initialize SPMC attributes for the SPMD. 506 ******************************************************************************/ 507 void spmc_populate_attrs(spmc_manifest_attribute_t *spmc_attrs) 508 { 509 spmc_attrs->major_version = FFA_VERSION_MAJOR; 510 spmc_attrs->minor_version = FFA_VERSION_MINOR; 511 spmc_attrs->exec_state = MODE_RW_64; 512 spmc_attrs->spmc_id = FFA_SPMC_ID; 513 } 514 515 /******************************************************************************* 516 * Initialize contexts of all Secure Partitions. 517 ******************************************************************************/ 518 int32_t spmc_setup(void) 519 { 520 int32_t ret; 521 522 /* Initialize endpoint descriptors */ 523 initalize_sp_descs(); 524 initalize_ns_ep_descs(); 525 526 /* Perform physical SP setup. */ 527 528 /* Disable MMU at EL1 (initialized by BL2) */ 529 disable_mmu_icache_el1(); 530 531 /* Initialize context of the SP */ 532 INFO("Secure Partition context setup start.\n"); 533 534 ret = find_and_prepare_sp_context(); 535 if (ret != 0) { 536 ERROR("Error in SP finding and context preparation.\n"); 537 return ret; 538 } 539 540 /* Register init function for deferred init. */ 541 bl31_register_bl32_init(&sp_init); 542 543 INFO("Secure Partition setup done.\n"); 544 545 return 0; 546 } 547 548 /******************************************************************************* 549 * Secure Partition Manager SMC handler. 550 ******************************************************************************/ 551 uint64_t spmc_smc_handler(uint32_t smc_fid, 552 bool secure_origin, 553 uint64_t x1, 554 uint64_t x2, 555 uint64_t x3, 556 uint64_t x4, 557 void *cookie, 558 void *handle, 559 uint64_t flags) 560 { 561 switch (smc_fid) { 562 563 case FFA_MSG_WAIT: 564 return msg_wait_handler(smc_fid, secure_origin, x1, x2, x3, x4, 565 cookie, handle, flags); 566 567 default: 568 WARN("Unsupported FF-A call 0x%08x.\n", smc_fid); 569 break; 570 } 571 return spmc_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED); 572 } 573