diff options
author | Ming Huang <huangming@linux.alibaba.com> | 2021-04-23 15:06:17 +0800 |
---|---|---|
committer | Joanna Farley <joanna.farley@arm.com> | 2021-07-28 11:12:44 +0200 |
commit | d21f1ddb71fc9e13f4f352f34e2a707a5b7df301 (patch) | |
tree | ed376ad8e71fa156886b56ae6e19c49edd5ee196 /services/std_svc/sdei | |
parent | 743e3b4147a74ebedf9d59058537c1729955c0b0 (diff) | |
download | arm-trusted-firmware-d21f1ddb71fc9e13f4f352f34e2a707a5b7df301.tar.gz |
services: Fix pmr_el1 rewrote issue in sdei_disaptch_event()
Consider a RAS scenario:
Enter EL3 by sync exception, then call spm_mm_sp_call() enter
EL0s to handle this error, then call sdei_dispatch_event() to
inform OS. Finally, return back to OS from sync exception flow.
Similar flow is sgi_ras_intr_handler() in sgi_ras.c.
The icc_pmr_el1 register will be change in above flow:
1 cm_el1_sysregs_context_save(NON_SECURE);
-> ehf_exited_normal_world();
##icc_pmr_el1: 0xf8 => 0x80
2 spm_mm_sp_call();
3 sdei_dispatch_event();
4 ehf_activate_priority(sdei_event_priority(map));
##icc_pmr_el1: 0x80 => 0x60
5 restore_and_resume_ns_context();
-> ehf_exited_normal_world();
##return due to has_valid_pri_activations(pe_data) == 1
6 ehf_deactivate_priority(sdei_event_priority(map));
##icc_pmr_el1: 0x60 => 0x80
The icc_pmr_el1 was rewrote from 0xf8 to 0x80. This issue will
result in OS hang when eret to OS from RAS flow.
Move ehf_activate_priority(sdei_event_priority(map)) after
restore_and_resume_ns_context() can fix this issue.
Signed-off-by: Ming Huang <huangming@linux.alibaba.com>
Change-Id: If01ec55cf0aabf1594dece1ad50d3ec3406cdabc
Diffstat (limited to 'services/std_svc/sdei')
-rw-r--r-- | services/std_svc/sdei/sdei_intr_mgmt.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/services/std_svc/sdei/sdei_intr_mgmt.c b/services/std_svc/sdei/sdei_intr_mgmt.c index f12b2ca3d..5d176c209 100644 --- a/services/std_svc/sdei/sdei_intr_mgmt.c +++ b/services/std_svc/sdei/sdei_intr_mgmt.c @@ -636,15 +636,15 @@ int sdei_dispatch_event(int ev_num) if (!can_sdei_state_trans(se, DO_DISPATCH)) return -1; - /* Activate the priority corresponding to the event being dispatched */ - ehf_activate_priority(sdei_event_priority(map)); - /* * Prepare for NS dispatch by restoring the Non-secure context and * marking that as active. */ ns_ctx = restore_and_resume_ns_context(); + /* Activate the priority corresponding to the event being dispatched */ + ehf_activate_priority(sdei_event_priority(map)); + /* Dispatch event synchronously */ setup_ns_dispatch(map, se, ns_ctx, &dispatch_jmp); begin_sdei_synchronous_dispatch(&dispatch_jmp); |