From 63b8440fcc3954817e20d3ba7a0be74435a284d2 Mon Sep 17 00:00:00 2001 From: Soby Mathew Date: Fri, 13 Nov 2015 02:08:43 +0000 Subject: TSP: Allow preemption of synchronous S-EL1 interrupt handling Earlier the TSP only ever expected to be preempted during Standard SMC processing. If a S-EL1 interrupt triggered while in the normal world, it will routed to S-EL1 `synchronously` for handling. The `synchronous` S-EL1 interrupt handler `tsp_sel1_intr_entry` used to panic if this S-EL1 interrupt was preempted by another higher priority pending interrupt which should be handled in EL3 e.g. Group0 interrupt in GICv3. With this patch, the `tsp_sel1_intr_entry` now expects `TSP_PREEMPTED` as the return code from the `tsp_common_int_handler` in addition to 0 (interrupt successfully handled) and in both cases it issues an SMC with id `TSP_HANDLED_S_EL1_INTR`. The TSPD switches the context and returns back to normal world. In case a higher priority EL3 interrupt was pending, the execution will be routed to EL3 where interrupt will be handled. On return back to normal world, the pending S-EL1 interrupt which was preempted will get routed to S-EL1 to be handled `synchronously` via `tsp_sel1_intr_entry`. Change-Id: I2087c7fedb37746fbd9200cdda9b6dba93e16201 --- services/spd/tspd/tspd_main.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'services/spd') diff --git a/services/spd/tspd/tspd_main.c b/services/spd/tspd/tspd_main.c index 4c4861d7..4b894258 100644 --- a/services/spd/tspd/tspd_main.c +++ b/services/spd/tspd/tspd_main.c @@ -89,18 +89,22 @@ uint64_t tspd_handle_sp_preemption(void *handle) assert(ns_cpu_context); /* - * Restore non-secure state. The secure system - * register context will be saved when required. + * To allow Secure EL1 interrupt handler to re-enter TSP while TSP + * is preempted, the secure system register context which will get + * overwritten must be additionally saved. This is currently done + * by the TSPD S-EL1 interrupt handler. + */ + + /* + * Restore non-secure state. */ cm_el1_sysregs_context_restore(NON_SECURE); cm_set_next_eret_context(NON_SECURE); /* - * We need to restore non secure context according to - * the SEL1 context which got preempted and currently - * TSP can only be preempted when a STD SMC is ongoing. - * Return SMC_PREEMPTED in x0 and restore non secure - * context. + * The TSP was preempted during STD SMC execution. + * Return back to the normal world with SMC_PREEMPTED as error + * code in x0. */ SMC_RET1(ns_cpu_context, SMC_PREEMPTED); } @@ -327,7 +331,8 @@ uint64_t tspd_smc_handler(uint32_t smc_fid, /* * This function ID is used only by the TSP to indicate that it has - * finished handling a S-EL1 interrupt. Execution should resume + * finished handling a S-EL1 interrupt or was preempted by a higher + * priority pending EL3 interrupt. Execution should resume * in the normal world. */ case TSP_HANDLED_S_EL1_INTR: -- cgit v1.2.3