[PATCH v4 13/15] hw/intc: hvf: sync state in c->ich* registers when virt on

Mohamed Mediouni posted 15 patches 6 months, 2 weeks ago
Maintainers: Cameron Esfahani <dirty@apple.com>, Roman Bolshakov <rbolshakov@ddn.com>, Phil Dennis-Jordan <phil@philjordan.eu>, Mads Ynddal <mads@ynddal.dk>, Shannon Zhao <shannon.zhaosl@gmail.com>, Peter Maydell <peter.maydell@linaro.org>, "Michael S. Tsirkin" <mst@redhat.com>, Igor Mammedov <imammedo@redhat.com>, Ani Sinha <anisinha@redhat.com>, Paolo Bonzini <pbonzini@redhat.com>, Alexander Graf <agraf@csgraf.de>
There is a newer version of this series
[PATCH v4 13/15] hw/intc: hvf: sync state in c->ich* registers when virt on
Posted by Mohamed Mediouni 6 months, 2 weeks ago
Part of vGIC state to save/restore.

Signed-off-by: Mohamed Mediouni <mohamed@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)