summaryrefslogtreecommitdiffstats
path: root/hw/intc/armv7m_nvic.c
diff options
context:
space:
mode:
authorPeter Maydell2017-09-14 19:43:17 +0200
committerPeter Maydell2017-09-14 19:43:17 +0200
commit22a9c26af62f9772b7c0512e88f97d0d1f2e0872 (patch)
treeaed57ca516513b057c8a3277a0919973704742c7 /hw/intc/armv7m_nvic.c
parenttarget/arm: Get PRECISERR and IBUSERR the right way round (diff)
downloadqemu-22a9c26af62f9772b7c0512e88f97d0d1f2e0872.tar.gz
qemu-22a9c26af62f9772b7c0512e88f97d0d1f2e0872.tar.xz
qemu-22a9c26af62f9772b7c0512e88f97d0d1f2e0872.zip
nvic: Don't apply group priority mask to negative priorities
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> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 1505137930-13255-5-git-send-email-peter.maydell@linaro.org
Diffstat (limited to 'hw/intc/armv7m_nvic.c')
-rw-r--r--hw/intc/armv7m_nvic.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 1fecfd6377..d3e20561c7 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);