diff options
author | davidcunado-arm <david.cunado@arm.com> | 2018-02-28 00:30:55 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-02-28 00:30:55 +0000 |
commit | 99e198ecd869d33a5948445dd17c5e0920ef5477 (patch) | |
tree | fcb32f01655de3e22a040c81bfab2360aabbbe2e /bl31 | |
parent | b39d2896b3f6e79c98ea781ee20ad639793ae135 (diff) | |
parent | 472be0f74e8d4559471c6eb95169455001f236de (diff) |
Merge pull request #1284 from jeenu-arm/tspd-ehf
TSPD and EHF
Diffstat (limited to 'bl31')
-rw-r--r-- | bl31/ehf.c | 17 |
1 files changed, 15 insertions, 2 deletions
@@ -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); |