Merge "fix(optee): set interrupt handler before kernel boot" into integration
diff --git a/services/spd/opteed/opteed_main.c b/services/spd/opteed/opteed_main.c
index 83b001a..d6c0040 100644
--- a/services/spd/opteed/opteed_main.c
+++ b/services/spd/opteed/opteed_main.c
@@ -87,6 +87,13 @@
 	uint32_t linear_id;
 	optee_context_t *optee_ctx;
 
+#if OPTEE_ALLOW_SMC_LOAD
+	if (optee_vector_table == NULL) {
+		/* OPTEE is not loaded yet, ignore this interrupt */
+		SMC_RET0(handle);
+	}
+#endif
+
 	/* Check the security state when the exception was generated */
 	assert(get_interrupt_src_ss(flags) == NON_SECURE);
 
@@ -115,6 +122,24 @@
 	SMC_RET1(&optee_ctx->cpu_ctx, read_elr_el3());
 }
 
+/*
+ * Registers an interrupt handler for S-EL1 interrupts when generated during
+ * code executing in the non-secure state. Panics if it fails to do so.
+ */
+static void register_opteed_interrupt_handler(void)
+{
+	u_register_t flags;
+	uint64_t rc;
+
+	flags = 0;
+	set_interrupt_rm_flag(flags, NON_SECURE);
+	rc = register_interrupt_type_handler(INTR_TYPE_S_EL1,
+			opteed_sel1_interrupt_handler,
+			flags);
+	if (rc)
+		panic();
+}
+
 /*******************************************************************************
  * OPTEE Dispatcher setup. The OPTEED finds out the OPTEE entrypoint and type
  * (aarch32/aarch64) if not already known and initialises the context for entry
@@ -125,6 +150,11 @@
 #if OPTEE_ALLOW_SMC_LOAD
 	opteed_allow_load = true;
 	INFO("Delaying OP-TEE setup until we receive an SMC call to load it\n");
+	/*
+	 * We must register the interrupt handler now so that the interrupt
+	 * priorities are not changed after starting the linux kernel.
+	 */
+	register_opteed_interrupt_handler();
 	return 0;
 #else
 	entry_point_info_t *optee_ep_info;
@@ -575,7 +605,6 @@
 	cpu_context_t *ns_cpu_context;
 	uint32_t linear_id = plat_my_core_pos();
 	optee_context_t *optee_ctx = &opteed_sp_context[linear_id];
-	uint64_t rc;
 
 	/*
 	 * Determine which security state this SMC originated from
@@ -709,18 +738,9 @@
 			 */
 			psci_register_spd_pm_hook(&opteed_pm);
 
-			/*
-			 * Register an interrupt handler for S-EL1 interrupts
-			 * when generated during code executing in the
-			 * non-secure state.
-			 */
-			flags = 0;
-			set_interrupt_rm_flag(flags, NON_SECURE);
-			rc = register_interrupt_type_handler(INTR_TYPE_S_EL1,
-						opteed_sel1_interrupt_handler,
-						flags);
-			if (rc)
-				panic();
+#if !OPTEE_ALLOW_SMC_LOAD
+			register_opteed_interrupt_handler();
+#endif
 		}
 
 		/*