[14/19] nvic: Disable the non-secure HardFault if AIRCR.BFHFNMINS is clear

Message ID 1505240046-11454-15-git-send-email-peter.maydell@linaro.org
State Superseded
Headers show
Series
  • ARMv8M: support security extn in the NVIC
Related show

Commit Message

Peter Maydell Sept. 12, 2017, 6:14 p.m.
If AIRCR.BFHFNMINS is clear, then although NonSecure HardFault
can still be pended via SHCSR.HARDFAULTPENDED it mustn't actually
preempt execution. The simple way to achieve this is to clear the
enable bit for it, since the enable bit isn't guest visible.

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

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

-- 
2.7.4

Comments

Richard Henderson Sept. 19, 2017, 6:59 p.m. | #1
On 09/12/2017 01:14 PM, Peter Maydell wrote:
> If AIRCR.BFHFNMINS is clear, then although NonSecure HardFault

> can still be pended via SHCSR.HARDFAULTPENDED it mustn't actually

> preempt execution. The simple way to achieve this is to clear the

> enable bit for it, since the enable bit isn't guest visible.

> 

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

> ---

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

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


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


r~

Patch

diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index db2f170..91d2f33 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -937,11 +937,16 @@  static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
                     (R_V7M_AIRCR_SYSRESETREQS_MASK |
                      R_V7M_AIRCR_BFHFNMINS_MASK |
                      R_V7M_AIRCR_PRIS_MASK);
-                /* BFHFNMINS changes the priority of Secure HardFault */
+                /* BFHFNMINS changes the priority of Secure HardFault, and
+                 * allows a pending Non-secure HardFault to preempt (which
+                 * we implement by marking it enabled).
+                 */
                 if (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) {
                     s->sec_vectors[ARMV7M_EXCP_HARD].prio = -3;
+                    s->vectors[ARMV7M_EXCP_HARD].enabled = 1;
                 } else {
                     s->sec_vectors[ARMV7M_EXCP_HARD].prio = -1;
+                    s->vectors[ARMV7M_EXCP_HARD].enabled = 0;
                 }
             }
             nvic_irq_update(s);
@@ -1562,7 +1567,6 @@  static void armv7m_nvic_reset(DeviceState *dev)
     NVICState *s = NVIC(dev);
 
     s->vectors[ARMV7M_EXCP_NMI].enabled = 1;
-    s->vectors[ARMV7M_EXCP_HARD].enabled = 1;
     /* MEM, BUS, and USAGE are enabled through
      * the System Handler Control register
      */
@@ -1584,6 +1588,10 @@  static void armv7m_nvic_reset(DeviceState *dev)
 
         /* AIRCR.BFHFNMINS resets to 0 so Secure HF is priority -1 (R_CMTC) */
         s->sec_vectors[ARMV7M_EXCP_HARD].prio = -1;
+        /* If AIRCR.BFHFNMINS is 0 then NS HF is (effectively) disabled */
+        s->vectors[ARMV7M_EXCP_HARD].enabled = 0;
+    } else {
+        s->vectors[ARMV7M_EXCP_HARD].enabled = 1;
     }
 
     /* Strictly speaking the reset handler should be enabled.