diff mbox series

[1/4] hw/intc/armv7m_nvic: Rebuild hflags on reset

Message ID 20200303174950.3298-2-peter.maydell@linaro.org
State New
Headers show
Series target/arm: Fix hflags mismatches for M-profile | expand

Commit Message

Peter Maydell March 3, 2020, 5:49 p.m. UTC
Some of an M-profile CPU's cached hflags state depends on state that's
in our NVIC object. We already do an hflags rebuild when the NVIC
registers are written, but we also need to do this on NVIC reset,
because there's no guarantee that this will happen before the
CPU reset.

This fixes an assertion due to mismatched hflags which happens if
the CPU is reset from inside a HardFault handler.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/intc/armv7m_nvic.c | 6 ++++++
 1 file changed, 6 insertions(+)

Comments

Richard Henderson March 3, 2020, 6:35 p.m. UTC | #1
On 3/3/20 9:49 AM, Peter Maydell wrote:
> Some of an M-profile CPU's cached hflags state depends on state that's
> in our NVIC object. We already do an hflags rebuild when the NVIC
> registers are written, but we also need to do this on NVIC reset,
> because there's no guarantee that this will happen before the
> CPU reset.
> 
> This fixes an assertion due to mismatched hflags which happens if
> the CPU is reset from inside a HardFault handler.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  hw/intc/armv7m_nvic.c | 6 ++++++
>  1 file changed, 6 insertions(+)

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 a62587eb3f0..1ad35e55292 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -2593,6 +2593,12 @@  static void armv7m_nvic_reset(DeviceState *dev)
             s->itns[i] = true;
         }
     }
+
+    /*
+     * We updated state that affects the CPU's MMUidx and thus its hflags;
+     * and we can't guarantee that we run before the CPU reset function.
+     */
+    arm_rebuild_hflags(&s->cpu->env);
 }
 
 static void nvic_systick_trigger(void *opaque, int n, int level)