aboutsummaryrefslogtreecommitdiff
path: root/hw/intc/armv7m_nvic.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/intc/armv7m_nvic.c')
-rw-r--r--hw/intc/armv7m_nvic.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 330eb728dd..9f8f0d3ff5 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -860,7 +860,19 @@ int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure)
return -1;
}
- ret = nvic_rettobase(s);
+ /*
+ * If this is a configurable exception and it is currently
+ * targeting the opposite security state from the one we're trying
+ * to complete it for, this counts as an illegal exception return.
+ * We still need to deactivate whatever vector the logic above has
+ * selected, though, as it might not be the same as the one for the
+ * requested exception number.
+ */
+ if (!exc_is_banked(irq) && exc_targets_secure(s, irq) != secure) {
+ ret = -1;
+ } else {
+ ret = nvic_rettobase(s);
+ }
vec->active = 0;
if (vec->level) {