KVM: arm/arm64: Helper to locate free rdist index

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>
This commit is contained in:
Eric Auger 2018-05-22 09:55:09 +02:00 committed by Marc Zyngier
parent dbd9733ab6
commit dc52461936
3 changed files with 35 additions and 2 deletions

View 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;

View 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;

View 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);