[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v2 24/28] hw/intc/armv7m_nvic: Fix "return from inactive handler"
From: |
Peter Maydell |
Subject: |
[PATCH v2 24/28] hw/intc/armv7m_nvic: Fix "return from inactive handler" check |
Date: |
Thu, 19 Nov 2020 21:56:13 +0000 |
In commit 077d7449100d824a4 we added code to handle the v8M
requirement that returns from NMI or HardFault forcibly deactivate
those exceptions regardless of what interrupt the guest is trying to
deactivate. Unfortunately this broke the handling of the "illegal
exception return because the returning exception number is not
active" check for those cases. In the pseudocode this test is done
on the exception the guest asks to return from, but because our
implementation was doing this in armv7m_nvic_complete_irq() after the
new "deactivate NMI/HardFault regardless" code we ended up doing the
test on the VecInfo for that exception instead, which usually meant
failing to raise the illegal exception return fault.
In the case for "configurable exception targeting the opposite
security state" we detected the illegal-return case but went ahead
and deactivated the VecInfo anyway, which is wrong because that is
the VecInfo for the other security state.
Rearrange the code so that we first identify the illegal return
cases, then see if we really need to deactivate NMI or HardFault
instead, and finally do the deactivation.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/intc/armv7m_nvic.c | 59 +++++++++++++++++++++++--------------------
1 file changed, 32 insertions(+), 27 deletions(-)
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index c901d20ae00..fa8aeca82ec 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -832,10 +832,40 @@ int armv7m_nvic_complete_irq(void *opaque, int irq, bool
secure)
{
NVICState *s = (NVICState *)opaque;
VecInfo *vec = NULL;
- int ret;
+ int ret = 0;
assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
+ trace_nvic_complete_irq(irq, secure);
+
+ if (secure && exc_is_banked(irq)) {
+ vec = &s->sec_vectors[irq];
+ } else {
+ vec = &s->vectors[irq];
+ }
+
+ /*
+ * Identify illegal exception return cases. We can't immediately
+ * return at this point because we still need to deactivate
+ * (either this exception or NMI/HardFault) first.
+ */
+ if (!exc_is_banked(irq) && exc_targets_secure(s, irq) != secure) {
+ /*
+ * Return from a configurable exception targeting the opposite
+ * security state from the one we're trying to complete it for.
+ * Clear vec because it's not really the VecInfo for this
+ * (irq, secstate) so we mustn't deactivate it.
+ */
+ ret = -1;
+ vec = NULL;
+ } else if (!vec->active) {
+ /* Return from an inactive interrupt */
+ ret = -1;
+ } else {
+ /* Legal return, we will return the RETTOBASE bit value to the caller
*/
+ ret = nvic_rettobase(s);
+ }
+
/*
* For negative priorities, v8M will forcibly deactivate the appropriate
* NMI or HardFault regardless of what interrupt we're being asked to
@@ -865,32 +895,7 @@ int armv7m_nvic_complete_irq(void *opaque, int irq, bool
secure)
}
if (!vec) {
- if (secure && exc_is_banked(irq)) {
- vec = &s->sec_vectors[irq];
- } else {
- vec = &s->vectors[irq];
- }
- }
-
- trace_nvic_complete_irq(irq, secure);
-
- if (!vec->active) {
- /* Tell the caller this was an illegal exception return */
- return -1;
- }
-
- /*
- * 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);
+ return ret;
}
vec->active = 0;
--
2.20.1
- Re: [PATCH v2 12/28] target/arm: Factor out preserve-fp-state from full_vfp_access_check(), (continued)
- [PATCH v2 17/28] target/arm: In v8.1M, don't set HFSR.FORCED on vector table fetch failures, Peter Maydell, 2020/11/19
- [PATCH v2 13/28] target/arm: Implement FPCXT_S fp system register, Peter Maydell, 2020/11/19
- [PATCH v2 11/28] target/arm: Use new FPCR_NZCV_MASK constant, Peter Maydell, 2020/11/19
- [PATCH v2 16/28] target/arm: For v8.1M, always clear R0-R3, R12, APSR, EPSR on exception entry, Peter Maydell, 2020/11/19
- [PATCH v2 15/28] hw/intc/armv7m_nvic: Update FPDSCR masking for v8.1M, Peter Maydell, 2020/11/19
- [PATCH v2 18/28] target/arm: Implement v8.1M REVIDR register, Peter Maydell, 2020/11/19
- [PATCH v2 19/28] target/arm: Implement new v8.1M NOCP check for exception return, Peter Maydell, 2020/11/19
- [PATCH v2 21/28] hw/intc/armv7m_nvic: Correct handling of CCR.BFHFNMIGN, Peter Maydell, 2020/11/19
- [PATCH v2 20/28] target/arm: Implement new v8.1M VLLDM and VLSTM encodings, Peter Maydell, 2020/11/19
- [PATCH v2 24/28] hw/intc/armv7m_nvic: Fix "return from inactive handler" check,
Peter Maydell <=
- [PATCH v2 22/28] hw/intc/armv7m_nvic: Support v8.1M CCR.TRD bit, Peter Maydell, 2020/11/19
- [PATCH v2 23/28] target/arm: Implement CCR_S.TRD behaviour for SG insns, Peter Maydell, 2020/11/19
- [PATCH v2 26/28] hw/intc/armv7m_nvic: Implement read/write for RAS register block, Peter Maydell, 2020/11/19
- [PATCH v2 27/28] hw/arm/armv7m: Correct typo in QOM object name, Peter Maydell, 2020/11/19
- [PATCH v2 28/28] target/arm: Implement Cortex-M55 model, Peter Maydell, 2020/11/19
- [PATCH v2 25/28] target/arm: Implement M-profile "minimal RAS implementation", Peter Maydell, 2020/11/19