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 <assert.h>
#include <context.h>
#include <context_mgmt.h>
#include <cpu_data.h> #include <cpu_data.h>
#include <debug.h> #include <debug.h>
#include <ehf.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 * Program Priority Mask to the original Non-secure priority such that
* Non-secure interrupts may preempt Secure execution, viz. during Yielding SMC * 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 * 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 * 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 * saved (after entry into EL3) and Secure context is restored (before entering
* Secure EL1). * 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; unsigned int old_pmr __unused;
pe_exc_data_t *pe_data = this_cpu_data(); pe_exc_data_t *pe_data = this_cpu_data();
@ -333,6 +337,15 @@ void ehf_allow_ns_preemption(void)
panic(); 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); 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); 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 * SPDX-License-Identifier: BSD-3-Clause
*/ */
@ -82,7 +82,7 @@ void ehf_init(void);
void ehf_activate_priority(unsigned int priority); void ehf_activate_priority(unsigned int priority);
void ehf_deactivate_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_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); unsigned int ehf_is_ns_preemption_allowed(void);
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */

View File

@ -549,9 +549,10 @@ uint64_t tspd_smc_handler(uint32_t smc_fid,
* preempt Secure execution. However, for * preempt Secure execution. However, for
* yielding SMCs, we want preemption to happen; * yielding SMCs, we want preemption to happen;
* so explicitly allow NS preemption in this * 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 #endif
} }
@ -662,9 +663,10 @@ uint64_t tspd_smc_handler(uint32_t smc_fid,
#if EL3_EXCEPTION_HANDLING #if EL3_EXCEPTION_HANDLING
/* /*
* Allow the resumed yielding SMC processing to be preempted by * 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 #endif
/* We just need to return to the preempted point in /* We just need to return to the preempted point in