summaryrefslogtreecommitdiff
path: root/virt/kvm/arm/vgic/vgic-v3.c
diff options
context:
space:
mode:
authorEric Auger <eric.auger@redhat.com>2018-05-22 09:55:08 +0200
committerMarc Zyngier <marc.zyngier@arm.com>2018-05-25 12:29:26 +0100
commitdbd9733ab6742dfb7d4f6c49e7d412d4e792d8be (patch)
tree1864d271a760667d958b2d54a925b64f42aec7c0 /virt/kvm/arm/vgic/vgic-v3.c
parentd6c77bd19c0f755dc603bf26a0bbc2d44dcd8625 (diff)
KVM: arm/arm64: Replace the single rdist region by a list
At the moment KVM supports a single rdist region. We want to support several separate rdist regions so let's introduce a list of them. This patch currently only cares about a single entry in this list as the functionality to register several redist regions is not yet there. So this only translates the existing code into something functionally similar using that new data struct. The redistributor region handle is stored in the vgic_cpu structure to allow later computation of the TYPER last bit. 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>
Diffstat (limited to 'virt/kvm/arm/vgic/vgic-v3.c')
-rw-r--r--virt/kvm/arm/vgic/vgic-v3.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/virt/kvm/arm/vgic/vgic-v3.c b/virt/kvm/arm/vgic/vgic-v3.c
index c7423f3768e5..56e6e903d998 100644
--- a/virt/kvm/arm/vgic/vgic-v3.c
+++ b/virt/kvm/arm/vgic/vgic-v3.c
@@ -427,6 +427,9 @@ bool vgic_v3_check_base(struct kvm *kvm)
{
struct vgic_dist *d = &kvm->arch.vgic;
gpa_t redist_size = KVM_VGIC_V3_REDIST_SIZE;
+ struct vgic_redist_region *rdreg =
+ list_first_entry(&d->rd_regions,
+ struct vgic_redist_region, list);
redist_size *= atomic_read(&kvm->online_vcpus);
@@ -434,18 +437,17 @@ bool vgic_v3_check_base(struct kvm *kvm)
d->vgic_dist_base + KVM_VGIC_V3_DIST_SIZE < d->vgic_dist_base)
return false;
- if (!IS_VGIC_ADDR_UNDEF(d->vgic_redist_base) &&
- d->vgic_redist_base + redist_size < d->vgic_redist_base)
+ if (rdreg && (rdreg->base + redist_size < rdreg->base))
return false;
/* Both base addresses must be set to check if they overlap */
- if (IS_VGIC_ADDR_UNDEF(d->vgic_dist_base) ||
- IS_VGIC_ADDR_UNDEF(d->vgic_redist_base))
+ if (IS_VGIC_ADDR_UNDEF(d->vgic_dist_base) || !rdreg)
return true;
- if (d->vgic_dist_base + KVM_VGIC_V3_DIST_SIZE <= d->vgic_redist_base)
+ if (d->vgic_dist_base + KVM_VGIC_V3_DIST_SIZE <= rdreg->base)
return true;
- if (d->vgic_redist_base + redist_size <= d->vgic_dist_base)
+
+ if (rdreg->base + redist_size <= d->vgic_dist_base)
return true;
return false;
@@ -455,12 +457,14 @@ int vgic_v3_map_resources(struct kvm *kvm)
{
int ret = 0;
struct vgic_dist *dist = &kvm->arch.vgic;
+ struct vgic_redist_region *rdreg =
+ list_first_entry(&dist->rd_regions,
+ struct vgic_redist_region, list);
if (vgic_ready(kvm))
goto out;
- if (IS_VGIC_ADDR_UNDEF(dist->vgic_dist_base) ||
- IS_VGIC_ADDR_UNDEF(dist->vgic_redist_base)) {
+ if (IS_VGIC_ADDR_UNDEF(dist->vgic_dist_base) || !rdreg) {
kvm_err("Need to set vgic distributor addresses first\n");
ret = -ENXIO;
goto out;