GIC CDEOI does a priority-drop for the current interrupt domain; when
this is the virtual interrupt domain we must update the virtual APR
register rather than a physical one.

Signed-off-by: Peter Maydell <[email protected]>
---
 target/arm/tcg/gicv5-cpuif.c | 21 ++++++++++++++++-----
 target/arm/tcg/trace-events  |  1 +
 2 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/target/arm/tcg/gicv5-cpuif.c b/target/arm/tcg/gicv5-cpuif.c
index f8d58b5a537..aeacc812fe0 100644
--- a/target/arm/tcg/gicv5-cpuif.c
+++ b/target/arm/tcg/gicv5-cpuif.c
@@ -1221,13 +1221,24 @@ static void gic_cdeoi_write(CPUARMState *env, const 
ARMCPRegInfo *ri,
      */
     bool virtual;
     GICv5Domain domain = gicv5_domain_for_insn(env, ri, &virtual);
-    uint64_t *apr = &env->gicv5_cpuif.icc_apr[domain];
 
-    trace_gicv5_cdeoi(domain);
+    if (virtual) {
+        uint64_t *apr = &env->gicv5_cpuif.ich_apr_el2;
 
-    /* clear lowest bit, doing nothing if already zero */
-    *apr &= *apr - 1;
-    gicv5_update_irq_fiq(env);
+        trace_gicv5_vcdeoi();
+
+        /* clear lowest bit, doing nothing if already zero */
+        *apr &= *apr - 1;
+        gicv5_update_virq_vfiq(env);
+    } else {
+        uint64_t *apr = &env->gicv5_cpuif.icc_apr[domain];
+
+        trace_gicv5_cdeoi(domain);
+
+        /* clear lowest bit, doing nothing if already zero */
+        *apr &= *apr - 1;
+        gicv5_update_irq_fiq(env);
+    }
 }
 
 static void gic_cddi_write(CPUARMState *env, const ARMCPRegInfo *ri,
diff --git a/target/arm/tcg/trace-events b/target/arm/tcg/trace-events
index 75f40c44f26..8e7e4c119db 100644
--- a/target/arm/tcg/trace-events
+++ b/target/arm/tcg/trace-events
@@ -7,6 +7,7 @@ gicv5_recalc_virt_ppi_hppi(uint32_t id, uint8_t prio) "virtual 
domain new PPI HP
 gicv5_gicr_cdia_fail(int domain, const char *reason) "domain %d CDIA attempt 
failed: %s"
 gicv5_gicr_cdia(int domain, uint32_t id) "domain %d CDIA acknowledge of 
interrupt 0x%x"
 gicv5_cdeoi(int domain) "domain %d CDEOI performing priority drop"
+gicv5_vcdeoi(void) "virtual interrupt domain CDEOI performing priority drop"
 gicv5_cddi(int domain, uint32_t id) "domain %d CDDI deactivating interrupt ID 
0x%x"
 gicv5_update_irq_fiq(bool irq, bool fiq, bool nmi) "now IRQ %d FIQ %d NMI %d"
 gicv5_update_virq_vfiq(bool virq, bool vinmi) "now VIRQ %d VINMI %d"
-- 
2.43.0


Reply via email to