aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2021-12-13 13:24:53 +0000
committerPeter Maydell <peter.maydell@linaro.org>2022-02-21 10:32:10 +0000
commit0af1efe0a6792a29cc7bc2131c7116ba2a206944 (patch)
tree76898f6d6acd41841ccf51255a460449f3e11ce6
parenta4e8963d66cd7b7e96664b3322c3b0d3d12bc935 (diff)
hw/intc/arm_gicv3: Keep pointers to every connected ITS
The GICv4 ITS VMOVP command's semantics require it to perform the operation on every ITS connected to the same GIC that the ITS that received the command is attached to. This means that the GIC object needs to keep a pointer to every ITS that is connected to it (previously it was sufficient for the ITS to have a pointer to its GIC). Add a glib ptrarray to the GICv3 object which holds pointers to every connected ITS, and make the ITS add itself to the array for the GIC it is connected to when it is realized. Note that currently all QEMU machine types with an ITS have exactly one ITS in the system, so typically the length of this ptrarray will be 1. Multiple ITSes are typically used to improve performance on real hardware, so we wouldn't need to have more than one unless we were modelling a real machine type that had multile ITSes. Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--hw/intc/arm_gicv3_common.c2
-rw-r--r--hw/intc/arm_gicv3_its.c2
-rw-r--r--hw/intc/arm_gicv3_its_kvm.c2
-rw-r--r--hw/intc/gicv3_internal.h9
-rw-r--r--include/hw/intc/arm_gicv3_common.h2
5 files changed, 17 insertions, 0 deletions
diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c
index 4ca5ae9bc5..8d1c183477 100644
--- a/hw/intc/arm_gicv3_common.c
+++ b/hw/intc/arm_gicv3_common.c
@@ -410,6 +410,8 @@ static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
cpuidx += s->redist_region_count[i];
s->cpu[cpuidx - 1].gicr_typer |= GICR_TYPER_LAST;
}
+
+ s->itslist = g_ptr_array_new();
}
static void arm_gicv3_finalize(Object *obj)
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
index 88671e995d..6081ad04e7 100644
--- a/hw/intc/arm_gicv3_its.c
+++ b/hw/intc/arm_gicv3_its.c
@@ -1533,6 +1533,8 @@ static void gicv3_arm_its_realize(DeviceState *dev, Error **errp)
}
}
+ gicv3_add_its(s->gicv3, dev);
+
gicv3_its_init_mmio(s, &gicv3_its_control_ops, &gicv3_its_translation_ops);
/* set the ITS default features supported */
diff --git a/hw/intc/arm_gicv3_its_kvm.c b/hw/intc/arm_gicv3_its_kvm.c
index 0b4cbed28b..529c7bd494 100644
--- a/hw/intc/arm_gicv3_its_kvm.c
+++ b/hw/intc/arm_gicv3_its_kvm.c
@@ -106,6 +106,8 @@ static void kvm_arm_its_realize(DeviceState *dev, Error **errp)
kvm_arm_register_device(&s->iomem_its_cntrl, -1, KVM_DEV_ARM_VGIC_GRP_ADDR,
KVM_VGIC_ITS_ADDR_TYPE, s->dev_fd, 0);
+ gicv3_add_its(s->gicv3, dev);
+
gicv3_its_init_mmio(s, NULL, NULL);
if (!kvm_device_check_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h
index 395618833b..15a7bb5b15 100644
--- a/hw/intc/gicv3_internal.h
+++ b/hw/intc/gicv3_internal.h
@@ -680,4 +680,13 @@ static inline void gicv3_cache_all_target_cpustates(GICv3State *s)
void gicv3_set_gicv3state(CPUState *cpu, GICv3CPUState *s);
+/*
+ * The ITS should call this when it is realized to add itself
+ * to its GIC's list of connected ITSes.
+ */
+static inline void gicv3_add_its(GICv3State *s, DeviceState *its)
+{
+ g_ptr_array_add(s->itslist, its);
+}
+
#endif /* QEMU_ARM_GICV3_INTERNAL_H */
diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h
index fc38e4b7dc..08b2778938 100644
--- a/include/hw/intc/arm_gicv3_common.h
+++ b/include/hw/intc/arm_gicv3_common.h
@@ -272,6 +272,8 @@ struct GICv3State {
uint32_t gicd_nsacr[DIV_ROUND_UP(GICV3_MAXIRQ, 16)];
GICv3CPUState *cpu;
+ /* List of all ITSes connected to this GIC */
+ GPtrArray *itslist;
};
#define GICV3_BITMAP_ACCESSORS(BMP) \