Part of vGIC state to save/restore.

Signed-off-by: Mohamed Mediouni <moha...@unpredictable.fr>
---
 hw/intc/arm_gicv3_hvf.c | 113 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 113 insertions(+)

diff --git a/hw/intc/arm_gicv3_hvf.c b/hw/intc/arm_gicv3_hvf.c
index a154b27318..30362540f2 100644
--- a/hw/intc/arm_gicv3_hvf.c
+++ b/hw/intc/arm_gicv3_hvf.c
@@ -15,6 +15,7 @@
 #include "system/runstate.h"
 #include "system/hvf.h"
 #include "system/hvf_int.h"
+#include "hvf_arm.h"
 #include "gicv3_internal.h"
 #include "vgic_common.h"
 #include "qom/object.h"
@@ -315,6 +316,62 @@ static void hvf_gicv3_put(GICv3State *s)
             hv_gic_set_icc_reg(vcpu, HV_GIC_ICC_REG_AP1R0_EL1, reg64);
         }
     }
+
+    /* Registers beyond this are with nested virt only */
+    if (!hvf_arm_el2_enabled()) {
+        return;
+    }
+
+    /* ICH */
+    for (ncpu = 0; ncpu < s->num_cpu; ncpu++) {
+        GICv3CPUState *c = &s->cpu[ncpu];
+        hv_vcpu_t vcpu = c->cpu->accel->fd;
+        int num_pri_bits;
+
+        hv_gic_set_ich_reg(vcpu, HV_GIC_ICH_REG_VMCR_EL2,
+                    c->ich_vmcr_el2);
+        hv_gic_set_ich_reg(vcpu, HV_GIC_ICH_REG_HCR_EL2,
+                    c->ich_hcr_el2);
+
+        for (int i = 0; i < GICV3_LR_MAX; i++) {
+            hv_gic_set_ich_reg(vcpu, HV_GIC_ICH_REG_LR0_EL2,
+                c->ich_lr_el2[i]);
+        }
+
+        num_pri_bits = c->vpribits;
+
+        switch (num_pri_bits) {
+        case 7:
+            hv_gic_set_ich_reg(vcpu, HV_GIC_ICH_REG_AP0R0_EL2 + 3
+                , c->ich_apr[GICV3_G0][3]);
+            hv_gic_set_ich_reg(vcpu, HV_GIC_ICH_REG_AP0R0_EL2 + 2
+                , c->ich_apr[GICV3_G0][2]);
+            /* fall through */
+        case 6:
+            hv_gic_set_ich_reg(vcpu, HV_GIC_ICH_REG_AP0R0_EL2 + 1
+                , c->ich_apr[GICV3_G0][1]);
+            /* fall through */
+        default:
+            hv_gic_set_ich_reg(vcpu, HV_GIC_ICH_REG_AP0R0_EL2
+                , c->ich_apr[GICV3_G0][0]);
+        }
+
+        switch (num_pri_bits) {
+        case 7:
+            hv_gic_set_ich_reg(vcpu, HV_GIC_ICH_REG_AP1R0_EL2 + 3
+                , c->ich_apr[GICV3_G1NS][3]);
+            hv_gic_set_ich_reg(vcpu, HV_GIC_ICH_REG_AP1R0_EL2 + 2
+                , c->ich_apr[GICV3_G1NS][2]);
+            /* fall through */
+        case 6:
+            hv_gic_set_ich_reg(vcpu, HV_GIC_ICH_REG_AP1R0_EL2 + 1
+                , c->ich_apr[GICV3_G1NS][1]);
+            /* fall through */
+        default:
+            hv_gic_set_ich_reg(vcpu, HV_GIC_ICH_REG_AP1R0_EL2
+                , c->ich_apr[GICV3_G1NS][0]);
+        }
+    }
 }
 
 static void hvf_gicv3_get(GICv3State *s)
@@ -452,6 +509,62 @@ static void hvf_gicv3_get(GICv3State *s)
                 , &c->icc_apr[GICV3_G1NS][0]);
         }
     }
+
+    /* Registers beyond this are with nested virt only */
+    if (!hvf_arm_el2_enabled()) {
+        return;
+    }
+
+    /* ICH */
+    for (ncpu = 0; ncpu < s->num_cpu; ncpu++) {
+        GICv3CPUState *c = &s->cpu[ncpu];
+        hv_vcpu_t vcpu = c->cpu->accel->fd;
+        int num_pri_bits;
+
+        hv_gic_get_ich_reg(vcpu, HV_GIC_ICH_REG_VMCR_EL2,
+                        &c->ich_vmcr_el2);
+        hv_gic_get_ich_reg(vcpu, HV_GIC_ICH_REG_HCR_EL2,
+                        &c->ich_hcr_el2);
+
+        for (int i = 0; i < GICV3_LR_MAX; i++) {
+            hv_gic_get_ich_reg(vcpu, HV_GIC_ICH_REG_LR0_EL2,
+                &c->ich_lr_el2[i]);
+        }
+
+        num_pri_bits = c->vpribits;
+
+        switch (num_pri_bits) {
+        case 7:
+            hv_gic_get_ich_reg(vcpu, HV_GIC_ICH_REG_AP0R0_EL2 + 3
+                , &c->ich_apr[GICV3_G0][3]);
+            hv_gic_get_ich_reg(vcpu, HV_GIC_ICH_REG_AP0R0_EL2 + 2
+                , &c->ich_apr[GICV3_G0][2]);
+            /* fall through */
+        case 6:
+            hv_gic_get_ich_reg(vcpu, HV_GIC_ICH_REG_AP0R0_EL2 + 1
+                , &c->ich_apr[GICV3_G0][1]);
+            /* fall through */
+        default:
+            hv_gic_get_ich_reg(vcpu, HV_GIC_ICH_REG_AP0R0_EL2
+                , &c->ich_apr[GICV3_G0][0]);
+        }
+
+        switch (num_pri_bits) {
+        case 7:
+            hv_gic_get_ich_reg(vcpu, HV_GIC_ICH_REG_AP1R0_EL2 + 3
+                , &c->ich_apr[GICV3_G1NS][3]);
+            hv_gic_get_ich_reg(vcpu, HV_GIC_ICH_REG_AP1R0_EL2 + 2
+                , &c->ich_apr[GICV3_G1NS][2]);
+            /* fall through */
+        case 6:
+            hv_gic_get_ich_reg(vcpu, HV_GIC_ICH_REG_AP1R0_EL2 + 1
+                , &c->ich_apr[GICV3_G1NS][1]);
+            /* fall through */
+        default:
+            hv_gic_get_ich_reg(vcpu, HV_GIC_ICH_REG_AP1R0_EL2
+                , &c->ich_apr[GICV3_G1NS][0]);
+        }
+    }
 }
 
 static void hvf_gicv3_set_irq(void *opaque, int irq, int level)
-- 
2.39.5 (Apple Git-154)


Reply via email to