SDEI: Determine client EL from NS context's SCR_EL3
authorJeenu Viswambharan <jeenu.viswambharan@arm.com>
Thu, 21 Jun 2018 07:47:42 +0000 (08:47 +0100)
committerJeenu Viswambharan <jeenu.viswambharan@arm.com>
Thu, 21 Jun 2018 15:15:23 +0000 (16:15 +0100)
Currently, the dispatcher reads from SCR_EL3 register directly to
determine the EL of SDEI client. This is with the assumption that
SCR_EL3 is not modified throughout. However, with RAS work flows, it's
possible that SCR_EL3 register contains values corresponding to Secure
world, and therefore EL determination can go wrong. To mitigate this,
always read the register from the saved Non-secure context.

Change-Id: Ic85e4021deb18eb58757f676f9a001174998543a
Signed-off-by: Jeenu Viswambharan <jeenu.viswambharan@arm.com>
services/std_svc/sdei/sdei_intr_mgmt.c
services/std_svc/sdei/sdei_main.c
services/std_svc/sdei/sdei_private.h

index a7104b4f5dade7be69ceb3d64cedc5536e7cbcd7..d6324b9c98d8140bdef007620d476cccc25e6225 100644 (file)
@@ -8,7 +8,6 @@
 #include <assert.h>
 #include <bl_common.h>
 #include <cassert.h>
-#include <context_mgmt.h>
 #include <debug.h>
 #include <ehf.h>
 #include <interrupt_mgmt.h>
index f881ba82ba949ab0d9b542797afa6467f2dd2875..d6d092decd0bdee1c31129d22c743b4fbb84b109 100644 (file)
@@ -10,7 +10,6 @@
 #include <bl_common.h>
 #include <cassert.h>
 #include <context.h>
-#include <context_mgmt.h>
 #include <debug.h>
 #include <ehf.h>
 #include <interrupt_mgmt.h>
index 45d537f5dbf2339a20af2b5eb4d80dcb1cefed27..ec4148c6bc0062f290967198aae74cd02d3ddaee 100644 (file)
@@ -8,6 +8,7 @@
 #define __SDEI_PRIVATE_H__
 
 #include <arch_helpers.h>
+#include <context_mgmt.h>
 #include <debug.h>
 #include <errno.h>
 #include <interrupt_mgmt.h>
@@ -159,7 +160,11 @@ static inline int is_secure_sgi(unsigned int intr)
  */
 static inline unsigned int sdei_client_el(void)
 {
-       return read_scr_el3() & SCR_HCE_BIT ? MODE_EL2 : MODE_EL1;
+       cpu_context_t *ns_ctx = cm_get_context(NON_SECURE);
+       el3_state_t *el3_ctx = get_el3state_ctx(ns_ctx);
+
+       return read_ctx_reg(el3_ctx, CTX_SPSR_EL3) & SCR_HCE_BIT ? MODE_EL2 :
+               MODE_EL1;
 }
 
 static inline unsigned int sdei_event_priority(sdei_ev_map_t *map)