aboutsummaryrefslogtreecommitdiff
path: root/plat
diff options
context:
space:
mode:
authorMing Huang <huangming@linux.alibaba.com>2020-11-09 17:22:05 +0800
committerManish Pandey <manish.pandey2@arm.com>2021-01-20 22:09:36 +0000
commit9feb1e2f4b1946d6042de0f0de3d8ae9edc21632 (patch)
treed3ac15e1d069d64ff88e08b7c31d5e034066bd76 /plat
parent6b2924bbbf37a6ae06a044021c006fd1fa553e5d (diff)
downloadarm-trusted-firmware-9feb1e2f4b1946d6042de0f0de3d8ae9edc21632.tar.gz
plat/arm/css/sgi: Fix bl32 receive event - 0xC4000061 issue
The issue is that, when interrupt is triggered and RAS handler is entered, after interrupt handler finishes, TF-A will re-enter bl32 and then crash. sdei_dispatch_event() may return failing result in some cases, for example kernel may not have registered a handler or RAS event may happen early during boot. We restore the NS context when sdei_dispatch_event() returns failing result. error log : Received delegated event X0 : 0xC4000061 X1 : 0x0 X2 : 0x0 X3 : 0x0 Received event - 0xC4000061 on cpu 0 UnRecognized Event - 0xC4000061 Failed delegated event 0xC4000061, Status Invalid Parameter Unhandled Exception in EL3. x30 = 0x000000000401f700 x0 = 0xfffffffffffffffe x1 = 0xfffffffffffffffe x2 = 0x00000000600003c0 Signed-off-by: Ming Huang <huangming@linux.alibaba.com> Change-Id: I9802e9a32eee0ac3b5a8bcc0362d0b0e3b71dc9f
Diffstat (limited to 'plat')
-rw-r--r--plat/arm/css/sgi/sgi_ras.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/plat/arm/css/sgi/sgi_ras.c b/plat/arm/css/sgi/sgi_ras.c
index f56544e72..f06c952cd 100644
--- a/plat/arm/css/sgi/sgi_ras.c
+++ b/plat/arm/css/sgi/sgi_ras.c
@@ -111,6 +111,7 @@ static int sgi_ras_intr_handler(const struct err_record_info *err_rec,
struct sgi_ras_ev_map *ras_map;
mm_communicate_header_t *header;
uint32_t intr;
+ int ret;
cm_el1_sysregs_context_save(NON_SECURE);
intr = data->interrupt;
@@ -152,9 +153,20 @@ static int sgi_ras_intr_handler(const struct err_record_info *err_rec,
plat_ic_end_of_interrupt(intr);
/* Dispatch the event to the SDEI client */
- sdei_dispatch_event(ras_map->sdei_ev_num);
+ ret = sdei_dispatch_event(ras_map->sdei_ev_num);
+ if (ret != 0) {
+ /*
+ * sdei_dispatch_event() may return failing result in some cases,
+ * for example kernel may not have registered a handler or RAS event
+ * may happen early during boot. We restore the NS context when
+ * sdei_dispatch_event() returns failing result.
+ */
+ ERROR("SDEI dispatch failed: %d", ret);
+ cm_el1_sysregs_context_restore(NON_SECURE);
+ cm_set_next_eret_context(NON_SECURE);
+ }
- return 0;
+ return ret;
}
int sgi_ras_intr_handler_setup(void)