Handle activation of a virtual interrupt.  Because this is more
complex than just updating a single field in the L2_ISTE, we can't
use the DEF_SET_FIELD_FOR_IST() macro, but activate_for_ist() follows
the same basic pattern.

Signed-off-by: Peter Maydell <[email protected]>
---
 hw/intc/arm_gicv5.c | 41 ++++++++++++++++++++++++++++++-----------
 1 file changed, 30 insertions(+), 11 deletions(-)

diff --git a/hw/intc/arm_gicv5.c b/hw/intc/arm_gicv5.c
index 5a038fc14e9..39c96fe0526 100644
--- a/hw/intc/arm_gicv5.c
+++ b/hw/intc/arm_gicv5.c
@@ -1031,6 +1031,29 @@ uint64_t gicv5_request_config(GICv5Common *cs, uint32_t 
id, GICv5Domain domain,
     }
 }
 
+static bool activate_for_ist(GICv5Common *cs,
+                             const GICv5ISTConfig *cfg,
+                             uint32_t id,
+                             uint32_t *iaffid)
+{
+    L2_ISTE_Handle h;
+    uint32_t *l2_iste_p;
+    if (!cfg) {
+        return false;
+    }
+    l2_iste_p = get_l2_iste(cs, cfg, id, &h);
+    if (!l2_iste_p) {
+        return false;
+    }
+    *l2_iste_p = FIELD_DP32(*l2_iste_p, L2_ISTE, ACTIVE, true);
+    if (FIELD_EX32(*l2_iste_p, L2_ISTE, HM) == GICV5_EDGE) {
+        *l2_iste_p = FIELD_DP32(*l2_iste_p, L2_ISTE, PENDING, false);
+    }
+    *iaffid = FIELD_EX32(*l2_iste_p, L2_ISTE, IAFFID);
+    put_l2_iste(cs, cfg, &h);
+    return true;
+}
+
 void gicv5_activate(GICv5Common *cs, uint32_t id, GICv5Domain domain,
                     GICv5IntType type, bool virtual, uint32_t cpuidx)
 {
@@ -1040,8 +1063,12 @@ void gicv5_activate(GICv5Common *cs, uint32_t id, 
GICv5Domain domain,
     trace_gicv5_activate(domain_name[domain], inttype_name(type), virtual, id);
 
     if (virtual) {
-        qemu_log_mask(LOG_GUEST_ERROR, "gicv5_activate: tried to "
-                      "activate a virtual interrupt\n");
+        const GICv5ISTConfig *cfg = ist_for_vint(s, cs, domain, type, cpuidx);
+
+        if (!activate_for_ist(cs, cfg, id, &iaffid)) {
+            return;
+        }
+        irs_recalc_vhppi(s, s->res_vpe[cpuidx]->vmte, iaffid);
         return;
     }
 
@@ -1049,18 +1076,10 @@ void gicv5_activate(GICv5Common *cs, uint32_t id, 
GICv5Domain domain,
     case GICV5_LPI:
     {
         const GICv5ISTConfig *cfg = &s->phys_lpi_config[domain];
-        L2_ISTE_Handle h;
-        uint32_t *l2_iste_p = get_l2_iste(cs, cfg, id, &h);
 
-        if (!l2_iste_p) {
+        if (!activate_for_ist(cs, cfg, id, &iaffid)) {
             return;
         }
-        *l2_iste_p = FIELD_DP32(*l2_iste_p, L2_ISTE, ACTIVE, true);
-        if (FIELD_EX32(*l2_iste_p, L2_ISTE, HM) == GICV5_EDGE) {
-            *l2_iste_p = FIELD_DP32(*l2_iste_p, L2_ISTE, PENDING, false);
-        }
-        iaffid = FIELD_EX32(*l2_iste_p, L2_ISTE, IAFFID);
-        put_l2_iste(cs, cfg, &h);
         break;
     }
     case GICV5_SPI:
-- 
2.43.0


Reply via email to