]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
KVM: arm/arm64: Helper to locate free rdist index
authorEric Auger <eric.auger@redhat.com>
Tue, 22 May 2018 07:55:09 +0000 (09:55 +0200)
committerMarc Zyngier <marc.zyngier@arm.com>
Fri, 25 May 2018 11:29:26 +0000 (12:29 +0100)
We introduce vgic_v3_rdist_free_slot to help identifying
where we can place a new 2x64KB redistributor.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Christoffer Dall <christoffer.dall@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
virt/kvm/arm/vgic/vgic-mmio-v3.c
virt/kvm/arm/vgic/vgic-v3.c
virt/kvm/arm/vgic/vgic.h

index d1aab183a1cc4c51a2c21b33a312809b4e2d7738..49ca176e2e0890a6ab8044bf6e1614f3c16aae4f 100644 (file)
@@ -593,8 +593,7 @@ int vgic_register_redist_iodev(struct kvm_vcpu *vcpu)
         * function for all VCPUs when the base address is set.  Just return
         * without doing any work for now.
         */
-       rdreg = list_first_entry(&vgic->rd_regions,
-                                struct vgic_redist_region, list);
+       rdreg = vgic_v3_rdist_free_slot(&vgic->rd_regions);
        if (!rdreg)
                return 0;
 
index 56e6e903d99865b340bcfe80390e04563988bc5e..2a11fe89943a2a95342071050a4cf233c7b8c49f 100644 (file)
@@ -453,6 +453,29 @@ bool vgic_v3_check_base(struct kvm *kvm)
        return false;
 }
 
+/**
+ * vgic_v3_rdist_free_slot - Look up registered rdist regions and identify one
+ * which has free space to put a new rdist region.
+ *
+ * @rd_regions: redistributor region list head
+ *
+ * A redistributor regions maps n redistributors, n = region size / (2 x 64kB).
+ * Stride between redistributors is 0 and regions are filled in the index order.
+ *
+ * Return: the redist region handle, if any, that has space to map a new rdist
+ * region.
+ */
+struct vgic_redist_region *vgic_v3_rdist_free_slot(struct list_head *rd_regions)
+{
+       struct vgic_redist_region *rdreg;
+
+       list_for_each_entry(rdreg, rd_regions, list) {
+               if (!vgic_v3_redist_region_full(rdreg))
+                       return rdreg;
+       }
+       return NULL;
+}
+
 int vgic_v3_map_resources(struct kvm *kvm)
 {
        int ret = 0;
index 32c25d42c93f401390f5d00fca80e637c8670151..fddd57ff652934ce4e16e9f307f51cd56541e41a 100644 (file)
@@ -265,6 +265,17 @@ static inline int vgic_v3_max_apr_idx(struct kvm_vcpu *vcpu)
        }
 }
 
+static inline bool
+vgic_v3_redist_region_full(struct vgic_redist_region *region)
+{
+       if (!region->count)
+               return false;
+
+       return (region->free_index >= region->count);
+}
+
+struct vgic_redist_region *vgic_v3_rdist_free_slot(struct list_head *rdregs);
+
 int vgic_its_resolve_lpi(struct kvm *kvm, struct vgic_its *its,
                         u32 devid, u32 eventid, struct vgic_irq **irq);
 struct vgic_its *vgic_msi_to_its(struct kvm *kvm, struct kvm_msi *msi);