diff mbox series

[15/41] hw/intc/arm_gicv3: Keep pointers to every connected ITS

Message ID 20220408141550.1271295-16-peter.maydell@linaro.org
State Superseded
Headers show
Series arm: Implement GICv4 | expand

Commit Message

Peter Maydell April 8, 2022, 2:15 p.m. UTC
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>
---
 hw/intc/gicv3_internal.h           | 9 +++++++++
 include/hw/intc/arm_gicv3_common.h | 2 ++
 hw/intc/arm_gicv3_common.c         | 2 ++
 hw/intc/arm_gicv3_its.c            | 2 ++
 hw/intc/arm_gicv3_its_kvm.c        | 2 ++
 5 files changed, 17 insertions(+)

Comments

Richard Henderson April 9, 2022, 6:06 p.m. UTC | #1
On 4/8/22 07:15, Peter Maydell wrote:
> 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>
> ---
>   hw/intc/gicv3_internal.h           | 9 +++++++++
>   include/hw/intc/arm_gicv3_common.h | 2 ++
>   hw/intc/arm_gicv3_common.c         | 2 ++
>   hw/intc/arm_gicv3_its.c            | 2 ++
>   hw/intc/arm_gicv3_its_kvm.c        | 2 ++
>   5 files changed, 17 insertions(+)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

r~
diff mbox series

Patch

diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h
index 6e22c8072e9..69a59daf867 100644
--- a/hw/intc/gicv3_internal.h
+++ b/hw/intc/gicv3_internal.h
@@ -709,4 +709,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 fc38e4b7dca..08b27789385 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)                                     \
diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c
index c797c82786b..dcc5ce28c6a 100644
--- a/hw/intc/arm_gicv3_common.c
+++ b/hw/intc/arm_gicv3_common.c
@@ -414,6 +414,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 21bc1a6c18b..6ff3c3b0348 100644
--- a/hw/intc/arm_gicv3_its.c
+++ b/hw/intc/arm_gicv3_its.c
@@ -1680,6 +1680,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 0b4cbed28b3..529c7bd4946 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,