Commit dc524619369c320e057cb198bbca017f3a0bb69a
Committed by
Marc Zyngier
1 parent
dbd9733ab6
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>
Showing 3 changed files with 35 additions and 2 deletions Side-by-side Diff
virt/kvm/arm/vgic/vgic-mmio-v3.c
... | ... | @@ -593,8 +593,7 @@ |
593 | 593 | * function for all VCPUs when the base address is set. Just return |
594 | 594 | * without doing any work for now. |
595 | 595 | */ |
596 | - rdreg = list_first_entry(&vgic->rd_regions, | |
597 | - struct vgic_redist_region, list); | |
596 | + rdreg = vgic_v3_rdist_free_slot(&vgic->rd_regions); | |
598 | 597 | if (!rdreg) |
599 | 598 | return 0; |
600 | 599 |
virt/kvm/arm/vgic/vgic-v3.c
... | ... | @@ -453,6 +453,29 @@ |
453 | 453 | return false; |
454 | 454 | } |
455 | 455 | |
456 | +/** | |
457 | + * vgic_v3_rdist_free_slot - Look up registered rdist regions and identify one | |
458 | + * which has free space to put a new rdist region. | |
459 | + * | |
460 | + * @rd_regions: redistributor region list head | |
461 | + * | |
462 | + * A redistributor regions maps n redistributors, n = region size / (2 x 64kB). | |
463 | + * Stride between redistributors is 0 and regions are filled in the index order. | |
464 | + * | |
465 | + * Return: the redist region handle, if any, that has space to map a new rdist | |
466 | + * region. | |
467 | + */ | |
468 | +struct vgic_redist_region *vgic_v3_rdist_free_slot(struct list_head *rd_regions) | |
469 | +{ | |
470 | + struct vgic_redist_region *rdreg; | |
471 | + | |
472 | + list_for_each_entry(rdreg, rd_regions, list) { | |
473 | + if (!vgic_v3_redist_region_full(rdreg)) | |
474 | + return rdreg; | |
475 | + } | |
476 | + return NULL; | |
477 | +} | |
478 | + | |
456 | 479 | int vgic_v3_map_resources(struct kvm *kvm) |
457 | 480 | { |
458 | 481 | int ret = 0; |
virt/kvm/arm/vgic/vgic.h
... | ... | @@ -265,6 +265,17 @@ |
265 | 265 | } |
266 | 266 | } |
267 | 267 | |
268 | +static inline bool | |
269 | +vgic_v3_redist_region_full(struct vgic_redist_region *region) | |
270 | +{ | |
271 | + if (!region->count) | |
272 | + return false; | |
273 | + | |
274 | + return (region->free_index >= region->count); | |
275 | +} | |
276 | + | |
277 | +struct vgic_redist_region *vgic_v3_rdist_free_slot(struct list_head *rdregs); | |
278 | + | |
268 | 279 | int vgic_its_resolve_lpi(struct kvm *kvm, struct vgic_its *its, |
269 | 280 | u32 devid, u32 eventid, struct vgic_irq **irq); |
270 | 281 | struct vgic_its *vgic_msi_to_its(struct kvm *kvm, struct kvm_msi *msi); |