diff mbox series

[4/7] nvic: Don't apply group priority mask to negative priorities

Message ID 1505137930-13255-5-git-send-email-peter.maydell@linaro.org
State Superseded
Headers show
Series ARMv8M: some bugfixes and prep. cleanup | expand

Commit Message

Peter Maydell Sept. 11, 2017, 1:52 p.m. UTC
In several places we were unconditionally applying the
nvic_gprio_mask() to a priority value. This is incorrect
if the priority is one of the fixed negative priority
values (for NMI and HardFault), so don't do it.

This bug would have caused both NMI and HardFault to be
considered as the same priority and so NMI wouldn't
correctly preempt HardFault.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

---
 hw/intc/armv7m_nvic.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

-- 
2.7.4

Comments

Richard Henderson Sept. 13, 2017, 3:58 p.m. UTC | #1
On 09/11/2017 06:52 AM, Peter Maydell wrote:
> In several places we were unconditionally applying the

> nvic_gprio_mask() to a priority value. This is incorrect

> if the priority is one of the fixed negative priority

> values (for NMI and HardFault), so don't do it.

> 

> This bug would have caused both NMI and HardFault to be

> considered as the same priority and so NMI wouldn't

> correctly preempt HardFault.

> 

> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

> ---

>  hw/intc/armv7m_nvic.c | 11 +++++++++--

>  1 file changed, 9 insertions(+), 2 deletions(-)


Reviewed-by: Richard Henderson <richard.henderson@linaro.org>



r~
diff mbox series

Patch

diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 1fecfd6..d3e2056 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -152,8 +152,12 @@  static void nvic_recompute_state(NVICState *s)
         }
     }
 
+    if (active_prio > 0) {
+        active_prio &= nvic_gprio_mask(s);
+    }
+
     s->vectpending = pend_irq;
-    s->exception_prio = active_prio & nvic_gprio_mask(s);
+    s->exception_prio = active_prio;
 
     trace_nvic_recompute_state(s->vectpending, s->exception_prio);
 }
@@ -329,7 +333,10 @@  void armv7m_nvic_acknowledge_irq(void *opaque)
     assert(vec->enabled);
     assert(vec->pending);
 
-    pendgroupprio = vec->prio & nvic_gprio_mask(s);
+    pendgroupprio = vec->prio;
+    if (pendgroupprio > 0) {
+        pendgroupprio &= nvic_gprio_mask(s);
+    }
     assert(pendgroupprio < running);
 
     trace_nvic_acknowledge_irq(pending, vec->prio);