When GICR CDIA for the virtual interrupt domain acknowledges an edge
handling-mode interrupt, it causes it to no longer be pending.  If
this is a PPI which is being direct-injected, we need to update the
physical PPI pending state, not the virtual state.

Signed-off-by: Peter Maydell <[email protected]>
---
 target/arm/tcg/gicv5-cpuif.c | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/target/arm/tcg/gicv5-cpuif.c b/target/arm/tcg/gicv5-cpuif.c
index 5a2927faf75..1f032e39bf6 100644
--- a/target/arm/tcg/gicv5-cpuif.c
+++ b/target/arm/tcg/gicv5-cpuif.c
@@ -1317,6 +1317,27 @@ static bool gic_hppi_is_nmi(CPUARMState *env, 
GICv5PendingIrq hppi,
     return hppi.prio == 0 && arm_sctlr(env, arm_current_el(env)) & SCTLR_NMI;
 }
 
+static void gic_clear_vppi_pending(CPUARMState *env, uint32_t ppireg,
+                                   uint64_t ppibit)
+{
+    /*
+     * Mark the specified virtual PPI as no longer pending.  ppireg is
+     * the PPI register index (0 or 1) and ppibit is a mask with
+     * exactly 1 bit set in it.
+     */
+    uint64_t dvi_mask = gic_virt_dvi_mask(env, ppireg);
+
+    if (!(dvi_mask & ppibit)) {
+        /* Easy case: vPPI not direct injected */
+        env->gicv5_cpuif.ich_ppi_pend[ppireg] &= ~ppibit;
+        return;
+    }
+    /* vPPI is direct-injected: unpend the physical PPI */
+    ppibit = gic_ppi_vpend_to_ppend(env, ppibit, ppireg);
+    env->gicv5_cpuif.ppi_pend[ppireg] &= ~ppibit;
+    gic_recalc_ppi_hppi(env);
+}
+
 static uint64_t gicr_cdia_read(CPUARMState *env, const ARMCPRegInfo *ri)
 {
     /* Acknowledge HPPI in the current interrupt domain */
@@ -1381,7 +1402,7 @@ static uint64_t gicr_cdia_read(CPUARMState *env, const 
ARMCPRegInfo *ri)
             env->gicv5_cpuif.ich_ppi_active[ppireg] |= ppibit;
             if (hm_edge) {
                 /* handling mode is Edge: clear pending */
-                env->gicv5_cpuif.ich_ppi_pend[ppireg] &= ~ppibit;
+                gic_clear_vppi_pending(env, ppireg, ppibit);
             }
             gic_recalc_virt_ppi_hppi(env);
         } else {
-- 
2.43.0


Reply via email to