mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-24 13:55:56 +00:00
Merge "feat(optee): add loading OP-TEE image via an SMC" into integration
This commit is contained in:
commit
8b47f87a5f
10 changed files with 373 additions and 62 deletions
docs
include/lib
lib/optee
services/spd/opteed
|
@ -6,9 +6,26 @@ OP-TEE Dispatcher
|
|||
To build and execute OP-TEE follow the instructions at
|
||||
`OP-TEE build.git`_
|
||||
|
||||
There are two different modes for loading the OP-TEE OS. The default mode will
|
||||
load it as the BL32 payload during boot, and is the recommended technique for
|
||||
platforms to use. There is also another technique that will load OP-TEE OS after
|
||||
boot via an SMC call by enabling the option for OPTEE_ALLOW_SMC_LOAD that was
|
||||
specifically added for ChromeOS. Loading OP-TEE via an SMC call may be insecure
|
||||
depending upon the platform configuration. If using that option, be sure to
|
||||
understand the risks involved with allowing the Trusted OS to be loaded this
|
||||
way. ChromeOS uses a boot flow where it verifies the signature of the firmware
|
||||
before executing it, and then only if the signature is valid will the 'secrets'
|
||||
used by the TEE become accessible. The firmware then verifies the signature of
|
||||
the kernel using depthcharge, and the kernel verifies the rootfs using
|
||||
dm-verity. The SMC call to load OP-TEE is then invoked immediately after the
|
||||
kernel finishes loading and before any attack vectors can be opened up by
|
||||
mounting writable filesystems or opening network/device connections. this
|
||||
ensures the platform is 'closed' and running signed code through the point where
|
||||
OP-TEE is loaded.
|
||||
|
||||
--------------
|
||||
|
||||
*Copyright (c) 2014-2018, Arm Limited and Contributors. All rights reserved.*
|
||||
*Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved.*
|
||||
|
||||
.. _OP-TEE OS: https://github.com/OP-TEE/build
|
||||
.. _OP-TEE build.git: https://github.com/OP-TEE/build
|
||||
|
|
|
@ -918,9 +918,54 @@ These are highlighted in the ``Mitigations implemented?`` box.
|
|||
| Mitigations | | Yes / Platform specific |
|
||||
+------------------------+-----------------------------------------------------+
|
||||
|
||||
+------------------------+-----------------------------------------------------+
|
||||
| ID | 14 |
|
||||
+========================+=====================================================+
|
||||
| Threat | | **Security vulnerabilities in the Non-secure OS |
|
||||
| | can lead to secure world compromise if the option |
|
||||
| | OPTEE_ALLOW_SMC_LOAD is enabled.** |
|
||||
| | |
|
||||
| | | This option trusts the non-secure world up until |
|
||||
| | the point it issues the SMC call to load the |
|
||||
| | Secure BL32 payload. If a compromise occurs |
|
||||
| | before the SMC call is invoked, then arbitrary |
|
||||
| | code execution in S-EL1 can occur or arbitrary |
|
||||
| | memory in EL3 can be overwritten. |
|
||||
+------------------------+-----------------------------------------------------+
|
||||
| Diagram Elements | DF5 |
|
||||
+------------------------+-----------------------------------------------------+
|
||||
| Affected TF-A | BL31, BL32 |
|
||||
| Components | |
|
||||
+------------------------+-----------------------------------------------------+
|
||||
| Assets | Code Execution, Sensitive Data |
|
||||
+------------------------+-----------------------------------------------------+
|
||||
| Threat Agent | NSCode |
|
||||
+------------------------+-----------------------------------------------------+
|
||||
| Threat Type | Tampering, Information Disclosure, |
|
||||
| | Elevation of privilege |
|
||||
+------------------------+-----------------+-----------------+-----------------+
|
||||
| Application | Server | IoT | Mobile |
|
||||
+------------------------+-----------------+-----------------+-----------------+
|
||||
| Impact | Critical (5) | Critical (5) | Critical (5) |
|
||||
+------------------------+-----------------+-----------------+-----------------+
|
||||
| Likelihood | Low (2) | Low (2) | Low (2) |
|
||||
+------------------------+-----------------+-----------------+-----------------+
|
||||
| Total Risk Rating | Medium (10) | Medium (10) | Medium (10) |
|
||||
+------------------------+-----------------+-----------------+-----------------+
|
||||
| Mitigations | When enabling the option OPTEE_ALLOW_SMC_LOAD, |
|
||||
| | the non-secure OS must be considered a closed |
|
||||
| | platform up until the point the SMC can be invoked |
|
||||
| | to load OP-TEE. |
|
||||
+------------------------+-----------------------------------------------------+
|
||||
| Mitigations | | None in TF-A itself. This option is only used by |
|
||||
| implemented? | ChromeOS currently which has other mechanisms to |
|
||||
| | to mitigate this threat which are described in |
|
||||
| | `OP-TEE Dispatcher`_. |
|
||||
+------------------------+-----------------------------------------------------+
|
||||
|
||||
--------------
|
||||
|
||||
*Copyright (c) 2021-2022, Arm Limited. All rights reserved.*
|
||||
*Copyright (c) 2021-2023, Arm Limited. All rights reserved.*
|
||||
|
||||
|
||||
.. _STRIDE threat analysis technique: https://docs.microsoft.com/en-us/azure/security/develop/threat-modeling-tool-threats#stride-model
|
||||
|
@ -932,3 +977,4 @@ These are highlighted in the ``Mitigations implemented?`` box.
|
|||
.. _TF-A error handling policy: https://trustedfirmware-a.readthedocs.io/en/latest/process/coding-guidelines.html#error-handling-and-robustness
|
||||
.. _Secure Development Guidelines: https://trustedfirmware-a.readthedocs.io/en/latest/process/security-hardening.html#secure-development-guidelines
|
||||
.. _Trusted Firmware-A Tests: https://git.trustedfirmware.org/TF-A/tf-a-tests.git/about/
|
||||
.. _OP-TEE Dispatcher: https://github.com/ARM-software/arm-trusted-firmware/blob/master/docs/components/spd/optee-dispatcher.rst
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2017-2023, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -17,4 +17,40 @@ int parse_optee_header(entry_point_info_t *header_ep,
|
|||
image_info_t *pager_image_info,
|
||||
image_info_t *paged_image_info);
|
||||
|
||||
/*
|
||||
* load_addr_hi and load_addr_lo: image load address.
|
||||
* image_id: 0 - pager, 1 - paged
|
||||
* size: image size in bytes.
|
||||
*/
|
||||
typedef struct optee_image {
|
||||
uint32_t load_addr_hi;
|
||||
uint32_t load_addr_lo;
|
||||
uint32_t image_id;
|
||||
uint32_t size;
|
||||
} optee_image_t;
|
||||
|
||||
#define OPTEE_PAGER_IMAGE_ID 0
|
||||
#define OPTEE_PAGED_IMAGE_ID 1
|
||||
|
||||
#define OPTEE_MAX_NUM_IMAGES 2u
|
||||
|
||||
#define TEE_MAGIC_NUM_OPTEE 0x4554504f
|
||||
/*
|
||||
* magic: header magic number.
|
||||
* version: OPTEE header version:
|
||||
* 1 - not supported
|
||||
* 2 - supported
|
||||
* arch: OPTEE os architecture type: 0 - AARCH32, 1 - AARCH64.
|
||||
* flags: unused currently.
|
||||
* nb_images: number of images.
|
||||
*/
|
||||
typedef struct optee_header {
|
||||
uint32_t magic;
|
||||
uint8_t version;
|
||||
uint8_t arch;
|
||||
uint16_t flags;
|
||||
uint32_t nb_images;
|
||||
optee_image_t optee_image_list[];
|
||||
} optee_header_t;
|
||||
|
||||
#endif /* OPTEE_UTILS_H */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2017-2023, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -11,42 +11,6 @@
|
|||
|
||||
#include <platform_def.h>
|
||||
|
||||
/*
|
||||
* load_addr_hi and load_addr_lo: image load address.
|
||||
* image_id: 0 - pager, 1 - paged
|
||||
* size: image size in bytes.
|
||||
*/
|
||||
typedef struct optee_image {
|
||||
uint32_t load_addr_hi;
|
||||
uint32_t load_addr_lo;
|
||||
uint32_t image_id;
|
||||
uint32_t size;
|
||||
} optee_image_t;
|
||||
|
||||
#define OPTEE_PAGER_IMAGE_ID 0
|
||||
#define OPTEE_PAGED_IMAGE_ID 1
|
||||
|
||||
#define OPTEE_MAX_NUM_IMAGES 2u
|
||||
|
||||
#define TEE_MAGIC_NUM_OPTEE 0x4554504f
|
||||
/*
|
||||
* magic: header magic number.
|
||||
* version: OPTEE header version:
|
||||
* 1 - not supported
|
||||
* 2 - supported
|
||||
* arch: OPTEE os architecture type: 0 - AARCH32, 1 - AARCH64.
|
||||
* flags: unused currently.
|
||||
* nb_images: number of images.
|
||||
*/
|
||||
typedef struct optee_header {
|
||||
uint32_t magic;
|
||||
uint8_t version;
|
||||
uint8_t arch;
|
||||
uint16_t flags;
|
||||
uint32_t nb_images;
|
||||
optee_image_t optee_image_list[];
|
||||
} optee_header_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* Check if it is a valid tee header
|
||||
* Return true if valid
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
|
||||
# Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
#
|
||||
|
@ -16,3 +16,19 @@ NEED_BL32 := yes
|
|||
|
||||
# required so that optee code can control access to the timer registers
|
||||
NS_TIMER_SWITCH := 1
|
||||
|
||||
# WARNING: This enables loading of OP-TEE via an SMC, which can be potentially
|
||||
# insecure. This removes the boundary between the startup of the secure and
|
||||
# non-secure worlds until the point where this SMC is invoked. Only use this
|
||||
# setting if you can ensure that the non-secure OS can remain trusted up until
|
||||
# the point where this SMC is invoked.
|
||||
OPTEE_ALLOW_SMC_LOAD := 0
|
||||
ifeq ($(OPTEE_ALLOW_SMC_LOAD),1)
|
||||
ifeq ($(PLAT_XLAT_TABLES_DYNAMIC),0)
|
||||
$(error When OPTEE_ALLOW_SMC_LOAD=1, PLAT_XLAT_TABLES_DYNAMIC must also be 1)
|
||||
endif
|
||||
$(warning "OPTEE_ALLOW_SMC_LOAD is enabled which may result in an insecure \
|
||||
platform")
|
||||
$(eval $(call add_define,PLAT_XLAT_TABLES_DYNAMIC))
|
||||
$(eval $(call add_define,OPTEE_ALLOW_SMC_LOAD))
|
||||
endif
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -16,6 +16,7 @@
|
|||
******************************************************************************/
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <arch_helpers.h>
|
||||
|
@ -24,12 +25,13 @@
|
|||
#include <common/debug.h>
|
||||
#include <common/runtime_svc.h>
|
||||
#include <lib/el3_runtime/context_mgmt.h>
|
||||
#include <lib/optee_utils.h>
|
||||
#include <lib/xlat_tables/xlat_tables_v2.h>
|
||||
#include <plat/common/platform.h>
|
||||
#include <tools_share/uuid.h>
|
||||
|
||||
#include "opteed_private.h"
|
||||
#include "teesmc_opteed.h"
|
||||
#include "teesmc_opteed_macros.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Address of the entrypoint vector table in OPTEE. It is
|
||||
|
@ -43,7 +45,16 @@ struct optee_vectors *optee_vector_table;
|
|||
optee_context_t opteed_sp_context[OPTEED_CORE_COUNT];
|
||||
uint32_t opteed_rw;
|
||||
|
||||
#if OPTEE_ALLOW_SMC_LOAD
|
||||
static bool opteed_allow_load;
|
||||
#else
|
||||
static int32_t opteed_init(void);
|
||||
#endif
|
||||
|
||||
uint64_t dual32to64(uint32_t high, uint32_t low)
|
||||
{
|
||||
return ((uint64_t)high << 32) | low;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* This function is the handler registered for S-EL1 interrupts by the
|
||||
|
@ -93,6 +104,11 @@ static uint64_t opteed_sel1_interrupt_handler(uint32_t id,
|
|||
******************************************************************************/
|
||||
static int32_t opteed_setup(void)
|
||||
{
|
||||
#if OPTEE_ALLOW_SMC_LOAD
|
||||
opteed_allow_load = true;
|
||||
INFO("Delaying OP-TEE setup until we receive an SMC call to load it\n");
|
||||
return 0;
|
||||
#else
|
||||
entry_point_info_t *optee_ep_info;
|
||||
uint32_t linear_id;
|
||||
uint64_t opteed_pageable_part;
|
||||
|
@ -142,6 +158,7 @@ static int32_t opteed_setup(void)
|
|||
bl31_register_bl32_init(&opteed_init);
|
||||
|
||||
return 0;
|
||||
#endif /* OPTEE_ALLOW_SMC_LOAD */
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
|
@ -153,18 +170,12 @@ static int32_t opteed_setup(void)
|
|||
* non-secure state. This function performs a synchronous entry into
|
||||
* OPTEE. OPTEE passes control back to this routine through a SMC.
|
||||
******************************************************************************/
|
||||
static int32_t opteed_init(void)
|
||||
static int32_t
|
||||
opteed_init_with_entry_point(entry_point_info_t *optee_entry_point)
|
||||
{
|
||||
uint32_t linear_id = plat_my_core_pos();
|
||||
optee_context_t *optee_ctx = &opteed_sp_context[linear_id];
|
||||
entry_point_info_t *optee_entry_point;
|
||||
uint64_t rc;
|
||||
|
||||
/*
|
||||
* Get information about the OPTEE (BL32) image. Its
|
||||
* absence is a critical failure.
|
||||
*/
|
||||
optee_entry_point = bl31_plat_get_next_image_ep_info(SECURE);
|
||||
assert(optee_entry_point);
|
||||
|
||||
cm_init_my_context(optee_entry_point);
|
||||
|
@ -179,6 +190,115 @@ static int32_t opteed_init(void)
|
|||
return rc;
|
||||
}
|
||||
|
||||
#if !OPTEE_ALLOW_SMC_LOAD
|
||||
static int32_t opteed_init(void)
|
||||
{
|
||||
entry_point_info_t *optee_entry_point;
|
||||
/*
|
||||
* Get information about the OP-TEE (BL32) image. Its
|
||||
* absence is a critical failure.
|
||||
*/
|
||||
optee_entry_point = bl31_plat_get_next_image_ep_info(SECURE);
|
||||
return opteed_init_with_entry_point(optee_entry_point);
|
||||
}
|
||||
#endif /* !OPTEE_ALLOW_SMC_LOAD */
|
||||
|
||||
#if OPTEE_ALLOW_SMC_LOAD
|
||||
/*******************************************************************************
|
||||
* This function is responsible for handling the SMC that loads the OP-TEE
|
||||
* binary image via a non-secure SMC call. It takes the size and physical
|
||||
* address of the payload as parameters.
|
||||
******************************************************************************/
|
||||
static int32_t opteed_handle_smc_load(uint64_t data_size, uint32_t data_pa)
|
||||
{
|
||||
uintptr_t data_va = data_pa;
|
||||
uint64_t mapped_data_pa;
|
||||
uintptr_t mapped_data_va;
|
||||
uint64_t data_map_size;
|
||||
int32_t rc;
|
||||
optee_header_t *image_header;
|
||||
uint8_t *image_ptr;
|
||||
uint64_t target_pa;
|
||||
uint64_t target_end_pa;
|
||||
uint64_t image_pa;
|
||||
uintptr_t image_va;
|
||||
optee_image_t *curr_image;
|
||||
uintptr_t target_va;
|
||||
uint64_t target_size;
|
||||
entry_point_info_t optee_ep_info;
|
||||
uint32_t linear_id = plat_my_core_pos();
|
||||
|
||||
mapped_data_pa = page_align(data_pa, DOWN);
|
||||
mapped_data_va = mapped_data_pa;
|
||||
data_map_size = page_align(data_size + (mapped_data_pa - data_pa), UP);
|
||||
|
||||
rc = mmap_add_dynamic_region(mapped_data_pa, mapped_data_va,
|
||||
data_map_size, MT_MEMORY | MT_RO | MT_NS);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
image_header = (optee_header_t *)data_va;
|
||||
if (image_header->magic != TEE_MAGIC_NUM_OPTEE ||
|
||||
image_header->version != 2 || image_header->nb_images != 1) {
|
||||
mmap_remove_dynamic_region(mapped_data_va, data_map_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
image_ptr = (uint8_t *)data_va + sizeof(optee_header_t) +
|
||||
sizeof(optee_image_t);
|
||||
if (image_header->arch == 1) {
|
||||
opteed_rw = OPTEE_AARCH64;
|
||||
} else {
|
||||
opteed_rw = OPTEE_AARCH32;
|
||||
}
|
||||
|
||||
curr_image = &image_header->optee_image_list[0];
|
||||
image_pa = dual32to64(curr_image->load_addr_hi,
|
||||
curr_image->load_addr_lo);
|
||||
image_va = image_pa;
|
||||
target_end_pa = image_pa + curr_image->size;
|
||||
|
||||
/* Now also map the memory we want to copy it to. */
|
||||
target_pa = page_align(image_pa, DOWN);
|
||||
target_va = target_pa;
|
||||
target_size = page_align(target_end_pa, UP) - target_pa;
|
||||
|
||||
rc = mmap_add_dynamic_region(target_pa, target_va, target_size,
|
||||
MT_MEMORY | MT_RW | MT_SECURE);
|
||||
if (rc != 0) {
|
||||
mmap_remove_dynamic_region(mapped_data_va, data_map_size);
|
||||
return rc;
|
||||
}
|
||||
|
||||
INFO("Loaded OP-TEE via SMC: size %d addr 0x%" PRIx64 "\n",
|
||||
curr_image->size, image_va);
|
||||
|
||||
memcpy((void *)image_va, image_ptr, curr_image->size);
|
||||
flush_dcache_range(target_pa, target_size);
|
||||
|
||||
mmap_remove_dynamic_region(mapped_data_va, data_map_size);
|
||||
mmap_remove_dynamic_region(target_va, target_size);
|
||||
|
||||
/* Save the non-secure state */
|
||||
cm_el1_sysregs_context_save(NON_SECURE);
|
||||
|
||||
opteed_init_optee_ep_state(&optee_ep_info,
|
||||
opteed_rw,
|
||||
image_pa,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
&opteed_sp_context[linear_id]);
|
||||
rc = opteed_init_with_entry_point(&optee_ep_info);
|
||||
|
||||
/* Restore non-secure state */
|
||||
cm_el1_sysregs_context_restore(NON_SECURE);
|
||||
cm_set_next_eret_context(NON_SECURE);
|
||||
|
||||
return rc;
|
||||
}
|
||||
#endif /* OPTEE_ALLOW_SMC_LOAD */
|
||||
|
||||
/*******************************************************************************
|
||||
* This function is responsible for handling all SMCs in the Trusted OS/App
|
||||
|
@ -207,6 +327,34 @@ static uintptr_t opteed_smc_handler(uint32_t smc_fid,
|
|||
*/
|
||||
|
||||
if (is_caller_non_secure(flags)) {
|
||||
#if OPTEE_ALLOW_SMC_LOAD
|
||||
if (smc_fid == NSSMC_OPTEED_CALL_LOAD_IMAGE) {
|
||||
/*
|
||||
* TODO: Consider wiping the code for SMC loading from
|
||||
* memory after it has been invoked similar to what is
|
||||
* done under RECLAIM_INIT, but extended to happen
|
||||
* later.
|
||||
*/
|
||||
if (!opteed_allow_load) {
|
||||
SMC_RET1(handle, -EPERM);
|
||||
}
|
||||
|
||||
opteed_allow_load = false;
|
||||
uint64_t data_size = dual32to64(x1, x2);
|
||||
uint64_t data_pa = dual32to64(x3, x4);
|
||||
if (!data_size || !data_pa) {
|
||||
/*
|
||||
* This is invoked when the OP-TEE image didn't
|
||||
* load correctly in the kernel but we want to
|
||||
* block off loading of it later for security
|
||||
* reasons.
|
||||
*/
|
||||
SMC_RET1(handle, -EINVAL);
|
||||
}
|
||||
SMC_RET1(handle, opteed_handle_smc_load(
|
||||
data_size, data_pa));
|
||||
}
|
||||
#endif /* OPTEE_ALLOW_SMC_LOAD */
|
||||
/*
|
||||
* This is a fresh request from the non-secure client.
|
||||
* The parameters are in x1 and x2. Figure out which
|
||||
|
@ -219,8 +367,18 @@ static uintptr_t opteed_smc_handler(uint32_t smc_fid,
|
|||
|
||||
/*
|
||||
* We are done stashing the non-secure context. Ask the
|
||||
* OPTEE to do the work now.
|
||||
* OP-TEE to do the work now. If we are loading vi an SMC,
|
||||
* then we also need to init this CPU context if not done
|
||||
* already.
|
||||
*/
|
||||
if (optee_vector_table == NULL) {
|
||||
SMC_RET1(handle, -EINVAL);
|
||||
}
|
||||
|
||||
if (get_optee_pstate(optee_ctx->state) ==
|
||||
OPTEE_PSTATE_UNKNOWN) {
|
||||
opteed_cpu_on_finish_handler(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify if there is a valid context to use, copy the
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -32,6 +32,10 @@ static int32_t opteed_cpu_off_handler(u_register_t unused)
|
|||
uint32_t linear_id = plat_my_core_pos();
|
||||
optee_context_t *optee_ctx = &opteed_sp_context[linear_id];
|
||||
|
||||
if (get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_UNKNOWN) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert(optee_vector_table);
|
||||
assert(get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_ON);
|
||||
|
||||
|
@ -65,6 +69,10 @@ static void opteed_cpu_suspend_handler(u_register_t max_off_pwrlvl)
|
|||
uint32_t linear_id = plat_my_core_pos();
|
||||
optee_context_t *optee_ctx = &opteed_sp_context[linear_id];
|
||||
|
||||
if (get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_UNKNOWN) {
|
||||
return;
|
||||
}
|
||||
|
||||
assert(optee_vector_table);
|
||||
assert(get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_ON);
|
||||
|
||||
|
@ -92,7 +100,7 @@ static void opteed_cpu_suspend_handler(u_register_t max_off_pwrlvl)
|
|||
* after initialising minimal architectural state that guarantees safe
|
||||
* execution.
|
||||
******************************************************************************/
|
||||
static void opteed_cpu_on_finish_handler(u_register_t unused)
|
||||
void opteed_cpu_on_finish_handler(u_register_t unused)
|
||||
{
|
||||
int32_t rc = 0;
|
||||
uint32_t linear_id = plat_my_core_pos();
|
||||
|
@ -100,7 +108,8 @@ static void opteed_cpu_on_finish_handler(u_register_t unused)
|
|||
entry_point_info_t optee_on_entrypoint;
|
||||
|
||||
assert(optee_vector_table);
|
||||
assert(get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_OFF);
|
||||
assert(get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_OFF ||
|
||||
get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_UNKNOWN);
|
||||
|
||||
opteed_init_optee_ep_state(&optee_on_entrypoint, opteed_rw,
|
||||
(uint64_t)&optee_vector_table->cpu_on_entry,
|
||||
|
@ -134,6 +143,10 @@ static void opteed_cpu_suspend_finish_handler(u_register_t max_off_pwrlvl)
|
|||
uint32_t linear_id = plat_my_core_pos();
|
||||
optee_context_t *optee_ctx = &opteed_sp_context[linear_id];
|
||||
|
||||
if (get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_UNKNOWN) {
|
||||
return;
|
||||
}
|
||||
|
||||
assert(optee_vector_table);
|
||||
assert(get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_SUSPEND);
|
||||
|
||||
|
@ -173,6 +186,14 @@ static void opteed_system_off(void)
|
|||
uint32_t linear_id = plat_my_core_pos();
|
||||
optee_context_t *optee_ctx = &opteed_sp_context[linear_id];
|
||||
|
||||
/*
|
||||
* OP-TEE must have been initialized in order to reach this location so
|
||||
* it is safe to init the CPU context if not already done for this core.
|
||||
*/
|
||||
if (get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_UNKNOWN) {
|
||||
opteed_cpu_on_finish_handler(0);
|
||||
}
|
||||
|
||||
assert(optee_vector_table);
|
||||
assert(get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_ON);
|
||||
|
||||
|
@ -193,6 +214,14 @@ static void opteed_system_reset(void)
|
|||
uint32_t linear_id = plat_my_core_pos();
|
||||
optee_context_t *optee_ctx = &opteed_sp_context[linear_id];
|
||||
|
||||
/*
|
||||
* OP-TEE must have been initialized in order to reach this location so
|
||||
* it is safe to init the CPU context if not already done for this core.
|
||||
*/
|
||||
if (get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_UNKNOWN) {
|
||||
opteed_cpu_on_finish_handler(0);
|
||||
}
|
||||
|
||||
assert(optee_vector_table);
|
||||
assert(get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_ON);
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -18,9 +18,10 @@
|
|||
* OPTEE PM state information e.g. OPTEE is suspended, uninitialised etc
|
||||
* and macros to access the state information in the per-cpu 'state' flags
|
||||
******************************************************************************/
|
||||
#define OPTEE_PSTATE_OFF 0
|
||||
#define OPTEE_PSTATE_ON 1
|
||||
#define OPTEE_PSTATE_SUSPEND 2
|
||||
#define OPTEE_PSTATE_OFF 1
|
||||
#define OPTEE_PSTATE_ON 2
|
||||
#define OPTEE_PSTATE_SUSPEND 3
|
||||
#define OPTEE_PSTATE_UNKNOWN 0
|
||||
#define OPTEE_PSTATE_SHIFT 0
|
||||
#define OPTEE_PSTATE_MASK 0x3
|
||||
#define get_optee_pstate(state) ((state >> OPTEE_PSTATE_SHIFT) & \
|
||||
|
@ -153,6 +154,7 @@ void opteed_init_optee_ep_state(struct entry_point_info *optee_entry_point,
|
|||
uint64_t mem_limit,
|
||||
uint64_t dt_addr,
|
||||
optee_context_t *optee_ctx);
|
||||
void opteed_cpu_on_finish_handler(u_register_t unused);
|
||||
|
||||
extern optee_context_t opteed_sp_context[OPTEED_CORE_COUNT];
|
||||
extern uint32_t opteed_rw;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2014-2023, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -9,8 +9,10 @@
|
|||
#ifndef TEESMC_OPTEED_H
|
||||
#define TEESMC_OPTEED_H
|
||||
|
||||
#include "teesmc_opteed_macros.h"
|
||||
|
||||
/*
|
||||
* This file specifies SMC function IDs used when returning from TEE to the
|
||||
* This section specifies SMC function IDs used when returning from TEE to the
|
||||
* secure monitor.
|
||||
*
|
||||
* All SMC Function IDs indicates SMC32 Calling Convention but will carry
|
||||
|
@ -120,4 +122,39 @@
|
|||
#define TEESMC_OPTEED_RETURN_SYSTEM_RESET_DONE \
|
||||
TEESMC_OPTEED_RV(TEESMC_OPTEED_FUNCID_RETURN_SYSTEM_RESET_DONE)
|
||||
|
||||
/*
|
||||
* This section specifies SMC function IDs used when the secure monitor is
|
||||
* invoked from the non-secure world.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Load OP-TEE image from the payload specified in the registers.
|
||||
*
|
||||
* WARNING: Use this cautiously as it could lead to insecure loading of the
|
||||
* Trusted OS. Further details are in opteed.mk.
|
||||
*
|
||||
* Call register usage:
|
||||
* x0 SMC Function ID, OPTEE_SMC_CALL_LOAD_IMAGE
|
||||
* x1 Upper 32bit of a 64bit size for the payload
|
||||
* x2 Lower 32bit of a 64bit size for the payload
|
||||
* x3 Upper 32bit of the physical address for the payload
|
||||
* x4 Lower 32bit of the physical address for the payload
|
||||
*
|
||||
* The payload consists of a optee_header struct that contains optee_image
|
||||
* structs in a flex array, immediately following that in memory is the data
|
||||
* referenced by the optee_image structs.
|
||||
* Example:
|
||||
*
|
||||
* struct optee_header (with n images specified)
|
||||
* image 0 data
|
||||
* image 1 data
|
||||
* ...
|
||||
* image n-1 data
|
||||
*
|
||||
* Returns 0 on success and an error code otherwise.
|
||||
*/
|
||||
#define NSSMC_OPTEED_FUNCID_LOAD_IMAGE 2
|
||||
#define NSSMC_OPTEED_CALL_LOAD_IMAGE \
|
||||
NSSMC_OPTEED_CALL(NSSMC_OPTEED_FUNCID_LOAD_IMAGE)
|
||||
|
||||
#endif /*TEESMC_OPTEED_H*/
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2014-2023, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -14,4 +14,10 @@
|
|||
(62 << FUNCID_OEN_SHIFT) | \
|
||||
((func_num) & FUNCID_NUM_MASK))
|
||||
|
||||
#define NSSMC_OPTEED_CALL(func_num) \
|
||||
((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT) | \
|
||||
((SMC_32) << FUNCID_CC_SHIFT) | \
|
||||
(50 << FUNCID_OEN_SHIFT) | \
|
||||
((func_num) & FUNCID_NUM_MASK))
|
||||
|
||||
#endif /* TEESMC_OPTEED_MACROS_H */
|
||||
|
|
Loading…
Add table
Reference in a new issue