Implement the redirection of the ICC_APR_EL1 encoding to the
hypervisor guest's view ICV_APR_EL1; the data for this is stored in
the ICH_APR_EL2 register.

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

diff --git a/target/arm/tcg/gicv5-cpuif.c b/target/arm/tcg/gicv5-cpuif.c
index 93141c751e4..b183c8a6e79 100644
--- a/target/arm/tcg/gicv5-cpuif.c
+++ b/target/arm/tcg/gicv5-cpuif.c
@@ -99,6 +99,17 @@ static bool gicv5_legacy_enabled(CPUARMState *env)
     return false;
 }
 
+static bool gicv5_icv_access(CPUARMState *env)
+{
+    /*
+     * Return true if ICC_*_EL1 accesses should redirect to ICV_*_EL1
+     * (i.e. we are in a hypervisor guest). Note that unlike GICv3 we
+     * don't need to care about HCR_FMO. See I_XVDWC.
+     */
+    return arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_IMO) &&
+            !gicv5_legacy_enabled(env);
+}
+
 static GICv5Domain gicv5_logical_domain(CPUARMState *env)
 {
     /*
@@ -522,16 +533,25 @@ static void gic_icc_apr_el1_write(CPUARMState *env, const 
ARMCPRegInfo *ri,
      * With an architectural 5 bits of priority, this register has 32
      * non-RES0 bits
      */
-    GICv5Domain domain = gicv5_logical_domain(env);
     value &= 0xffffffff;
-    env->gicv5_cpuif.icc_apr[domain] = value;
-    gicv5_update_irq_fiq(env);
+
+    if (gicv5_icv_access(env)) {
+        env->gicv5_cpuif.ich_apr_el2 = value;
+    } else {
+        GICv5Domain domain = gicv5_logical_domain(env);
+        env->gicv5_cpuif.icc_apr[domain] = value;
+        gicv5_update_irq_fiq(env);
+    }
 }
 
 static uint64_t gic_icc_apr_el1_read(CPUARMState *env, const ARMCPRegInfo *ri)
 {
-    GICv5Domain domain = gicv5_logical_domain(env);
-    return env->gicv5_cpuif.icc_apr[domain];
+    if (gicv5_icv_access(env)) {
+        return env->gicv5_cpuif.ich_apr_el2;
+    } else {
+        GICv5Domain domain = gicv5_logical_domain(env);
+        return env->gicv5_cpuif.icc_apr[domain];
+    }
 }
 
 static void gic_icc_apr_el1_reset(CPUARMState *env, const ARMCPRegInfo *ri)
-- 
2.43.0


Reply via email to