If the guest maps or unmaps the vLPI or vSPI for a VM via
IRS_VMAP_VISTR, this affects the vHPPI for every VPE in that VM, so
we need to recalculate it.  Similarly, if the guest maps a VPE for a
VM via IRS_VMAP_VPER_WRITE, we need to calculate the initial vHPPI
for that VPE.

Add the calls to recalculate the vHPPI for these register writes.

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

diff --git a/hw/intc/arm_gicv5.c b/hw/intc/arm_gicv5.c
index b4dbe7ce3e7..199547abaed 100644
--- a/hw/intc/arm_gicv5.c
+++ b/hw/intc/arm_gicv5.c
@@ -613,6 +613,19 @@ static void irs_recalc_vhppi(GICv5 *s, VMTE *vmte, 
uint32_t iaffid)
     /* TODO: we may need to generate a doorbell interrupt. */
 }
 
+static void irs_recalc_all_vhppi_for_vm(GICv5 *s, VMTE *vmte)
+{
+    /* Recalculate the vHPPI for all VPEs in this VM */
+
+    for (uint32_t i = 0; i < (1 << vmte->vpe_id_bits); i++) {
+        VPE *vpe = &vmte->vpet[i];
+
+        if (vpe->valid) {
+            irs_recalc_vhppi(s, vmte, i);
+        }
+    }
+}
+
 static const GICv5ISTConfig *ist_for_vint(GICv5 *s,
                                           GICv5Common *cs,
                                           GICv5Domain domain,
@@ -2131,6 +2144,8 @@ static void irs_vmap_vistr_write(GICv5 *s, GICv5Domain 
domain, uint64_t value)
     }
     return;
 
+    irs_recalc_all_vhppi_for_vm(s, vmte);
+
 txfail:
     /* Reportable with EC=0x0 if sw error reporting implemented */
     qemu_log_mask(LOG_GUEST_ERROR, "L2 VMTE update failed for VMID 0x%x at "
@@ -2228,6 +2243,8 @@ static void irs_vmap_vper_write(GICv5 *s, GICv5Domain 
domain, uint64_t value)
     init_vpe_from_vpete(&vmte->vpet[vpeid], vmte, vpete);
     trace_gicv5_irs_vmap_vper_write(domain_name[domain], vmte->vmid, vpeid);
 
+    irs_recalc_vhppi(s, vmte, vpeid);
+
     return;
 
 txfail:
-- 
2.43.0


Reply via email to