Merge pull request #1284 from jeenu-arm/tspd-ehf

TSPD and EHF
This commit is contained in:
davidcunado-arm 2018-02-28 00:30:55 +00:00 committed by GitHub
commit 99e198ecd8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 23 additions and 8 deletions

View File

@ -9,6 +9,8 @@
*/
#include <assert.h>
#include <context.h>
#include <context_mgmt.h>
#include <cpu_data.h>
#include <debug.h>
#include <ehf.h>
@ -308,15 +310,17 @@ static void *ehf_entering_normal_world(const void *arg)
/*
* Program Priority Mask to the original Non-secure priority such that
* Non-secure interrupts may preempt Secure execution, viz. during Yielding SMC
* calls.
* calls. The 'preempt_ret_code' parameter indicates the Yielding SMC's return
* value in case the call was preempted.
*
* This API is expected to be invoked before delegating a yielding SMC to Secure
* EL1. I.e. within the window of secure execution after Non-secure context is
* saved (after entry into EL3) and Secure context is restored (before entering
* Secure EL1).
*/
void ehf_allow_ns_preemption(void)
void ehf_allow_ns_preemption(uint64_t preempt_ret_code)
{
cpu_context_t *ns_ctx;
unsigned int old_pmr __unused;
pe_exc_data_t *pe_data = this_cpu_data();
@ -333,6 +337,15 @@ void ehf_allow_ns_preemption(void)
panic();
}
/*
* Program preempted return code to x0 right away so that, if the
* Yielding SMC was indeed preempted before a dispatcher gets a chance
* to populate it, the caller would find the correct return value.
*/
ns_ctx = cm_get_context(NON_SECURE);
assert(ns_ctx);
write_ctx_reg(get_gpregs_ctx(ns_ctx), CTX_GPREG_X0, preempt_ret_code);
old_pmr = plat_ic_set_priority_mask(pe_data->ns_pri_mask);
EHF_LOG("Priority Mask: 0x%x => 0x%x\n", old_pmr, pe_data->ns_pri_mask);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -82,7 +82,7 @@ void ehf_init(void);
void ehf_activate_priority(unsigned int priority);
void ehf_deactivate_priority(unsigned int priority);
void ehf_register_priority_handler(unsigned int pri, ehf_handler_t handler);
void ehf_allow_ns_preemption(void);
void ehf_allow_ns_preemption(uint64_t preempt_ret_code);
unsigned int ehf_is_ns_preemption_allowed(void);
#endif /* __ASSEMBLY__ */

View File

@ -549,9 +549,10 @@ uint64_t tspd_smc_handler(uint32_t smc_fid,
* preempt Secure execution. However, for
* yielding SMCs, we want preemption to happen;
* so explicitly allow NS preemption in this
* case.
* case, and supply the preemption return code
* for TSP.
*/
ehf_allow_ns_preemption();
ehf_allow_ns_preemption(TSP_PREEMPTED);
#endif
}
@ -662,9 +663,10 @@ uint64_t tspd_smc_handler(uint32_t smc_fid,
#if EL3_EXCEPTION_HANDLING
/*
* Allow the resumed yielding SMC processing to be preempted by
* Non-secure interrupts.
* Non-secure interrupts. Also, supply the preemption return
* code for TSP.
*/
ehf_allow_ns_preemption();
ehf_allow_ns_preemption(TSP_PREEMPTED);
#endif
/* We just need to return to the preempted point in