hw/intc/arm_gicv3: Keep pointers to every connected ITS
authorPeter Maydell <peter.maydell@linaro.org>
Fri, 8 Apr 2022 14:15:24 +0000 (15:15 +0100)
committerPeter Maydell <peter.maydell@linaro.org>
Fri, 22 Apr 2022 08:24:44 +0000 (09:24 +0100)
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>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
[PMM: Moved gicv3_add_its() to arm_gicv3_its_common.h to avoid
 compilation error building the KVM ITS]
Message-id: 20220408141550.1271295-16-peter.maydell@linaro.org

hw/intc/arm_gicv3_common.c
hw/intc/arm_gicv3_its.c
hw/intc/arm_gicv3_its_kvm.c
include/hw/intc/arm_gicv3_common.h
include/hw/intc/arm_gicv3_its_common.h

index c797c82786bd96e87997289e53c2dfca36116d3b..dcc5ce28c6acf1963de91bb38a828d6c1430bd57 100644 (file)
@@ -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)
index d2c0ca5f7263f52dfd66acf837a5d518e6fd026c..46d9e0169f9aa3a111cc0c0211c21a5a5195a5c1 100644 (file)
@@ -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 */
index 0b4cbed28b3b4128ca9c1cb530ed4128118ed1ff..529c7bd494649df8bfba6db379f39969d5d3bf27 100644 (file)
@@ -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,
index fc38e4b7dca4ac7f4a5e0377a5cc300e9a13feaf..08b277893850730f46f7556541f9ba42e3073770 100644 (file)
@@ -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)                                     \
index 7d1cc0f7177f15d8d0e2fd2402f06ebb8a586dc5..2b1c08b01b4def328f4cbba1333c04447b848437 100644 (file)
@@ -89,6 +89,15 @@ typedef struct GICv3ITSState GICv3ITSState;
 void gicv3_its_init_mmio(GICv3ITSState *s, const MemoryRegionOps *ops,
                    const MemoryRegionOps *tops);
 
+/*
+ * 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);
+}
+
 #define TYPE_ARM_GICV3_ITS_COMMON "arm-gicv3-its-common"
 typedef struct GICv3ITSCommonClass GICv3ITSCommonClass;
 DECLARE_OBJ_CHECKERS(GICv3ITSState, GICv3ITSCommonClass,