Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: marc.zyngier@arm.com (Marc Zyngier)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 27/33] KVM: arm/arm64: Helper to register a new redistributor region
Date: Fri,  1 Jun 2018 16:27:41 +0100	[thread overview]
Message-ID: <20180601152747.23613-28-marc.zyngier@arm.com> (raw)
In-Reply-To: <20180601152747.23613-1-marc.zyngier@arm.com>

From: Eric Auger <eric.auger@redhat.com>

We introduce a new helper that creates and inserts a new redistributor
region into the rdist region list. This helper both handles the case
where the redistributor region size is known at registration time
and the legacy case where it is not (eventually depending on the number
of online vcpus). Depending on pfns, we perform all the possible checks
that we can do:

- end of memory crossing
- incorrect alignment of the base address
- collision with distributor region if already defined
- collision with already registered rdist regions
- check of the new index

Rdist regions must be inserted by increasing order of indices. Indices
must be contiguous.

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 | 89 ++++++++++++++++++++++++++------
 virt/kvm/arm/vgic/vgic.h         |  8 +++
 2 files changed, 81 insertions(+), 16 deletions(-)

diff --git a/virt/kvm/arm/vgic/vgic-mmio-v3.c b/virt/kvm/arm/vgic/vgic-mmio-v3.c
index ce5c927fad06..3dbc057f861b 100644
--- a/virt/kvm/arm/vgic/vgic-mmio-v3.c
+++ b/virt/kvm/arm/vgic/vgic-mmio-v3.c
@@ -680,14 +680,63 @@ static int vgic_register_all_redist_iodevs(struct kvm *kvm)
 	return ret;
 }
 
-int vgic_v3_set_redist_base(struct kvm *kvm, u64 addr)
+/**
+ * vgic_v3_insert_redist_region - Insert a new redistributor region
+ *
+ * Performs various checks before inserting the rdist region in the list.
+ * Those tests depend on whether the size of the rdist region is known
+ * (ie. count != 0). The list is sorted by rdist region index.
+ *
+ * @kvm: kvm handle
+ * @index: redist region index
+ * @base: base of the new rdist region
+ * @count: number of redistributors the region is made of (0 in the old style
+ * single region, whose size is induced from the number of vcpus)
+ *
+ * Return 0 on success, < 0 otherwise
+ */
+static int vgic_v3_insert_redist_region(struct kvm *kvm, uint32_t index,
+					gpa_t base, uint32_t count)
 {
-	struct vgic_dist *vgic = &kvm->arch.vgic;
+	struct vgic_dist *d = &kvm->arch.vgic;
 	struct vgic_redist_region *rdreg;
+	struct list_head *rd_regions = &d->rd_regions;
+	size_t size = count * KVM_VGIC_V3_REDIST_SIZE;
 	int ret;
 
-	/* vgic_check_ioaddr makes sure we don't do this twice */
-	if (!list_empty(&vgic->rd_regions))
+	/* single rdist region already set ?*/
+	if (!count && !list_empty(rd_regions))
+		return -EINVAL;
+
+	/* cross the end of memory ? */
+	if (base + size < base)
+		return -EINVAL;
+
+	if (list_empty(rd_regions)) {
+		if (index != 0)
+			return -EINVAL;
+	} else {
+		rdreg = list_last_entry(rd_regions,
+					struct vgic_redist_region, list);
+		if (index != rdreg->index + 1)
+			return -EINVAL;
+
+		/* Cannot add an explicitly sized regions after legacy region */
+		if (!rdreg->count)
+			return -EINVAL;
+	}
+
+	/*
+	 * For legacy single-region redistributor regions (!count),
+	 * check that the redistributor region does not overlap with the
+	 * distributor's address space.
+	 */
+	if (!count && !IS_VGIC_ADDR_UNDEF(d->vgic_dist_base) &&
+		vgic_dist_overlap(kvm, base, size))
+		return -EINVAL;
+
+	/* collision with any other rdist region? */
+	if (vgic_v3_rdist_overlap(kvm, base, size))
 		return -EINVAL;
 
 	rdreg = kzalloc(sizeof(*rdreg), GFP_KERNEL);
@@ -696,17 +745,29 @@ int vgic_v3_set_redist_base(struct kvm *kvm, u64 addr)
 
 	rdreg->base = VGIC_ADDR_UNDEF;
 
-	ret = vgic_check_ioaddr(kvm, &rdreg->base, addr, SZ_64K);
+	ret = vgic_check_ioaddr(kvm, &rdreg->base, base, SZ_64K);
 	if (ret)
-		goto out;
+		goto free;
 
-	rdreg->base = addr;
-	if (!vgic_v3_check_base(kvm)) {
-		ret = -EINVAL;
-		goto out;
-	}
+	rdreg->base = base;
+	rdreg->count = count;
+	rdreg->free_index = 0;
+	rdreg->index = index;
 
-	list_add(&rdreg->list, &vgic->rd_regions);
+	list_add_tail(&rdreg->list, rd_regions);
+	return 0;
+free:
+	kfree(rdreg);
+	return ret;
+}
+
+int vgic_v3_set_redist_base(struct kvm *kvm, u64 addr)
+{
+	int ret;
+
+	ret = vgic_v3_insert_redist_region(kvm, 0, addr, 0);
+	if (ret)
+		return ret;
 
 	/*
 	 * Register iodevs for each existing VCPU.  Adding more VCPUs
@@ -717,10 +778,6 @@ int vgic_v3_set_redist_base(struct kvm *kvm, u64 addr)
 		return ret;
 
 	return 0;
-
-out:
-	kfree(rdreg);
-	return ret;
 }
 
 int vgic_v3_has_attr_regs(struct kvm_device *dev, struct kvm_device_attr *attr)
diff --git a/virt/kvm/arm/vgic/vgic.h b/virt/kvm/arm/vgic/vgic.h
index e9f192660097..1c8af4e4131c 100644
--- a/virt/kvm/arm/vgic/vgic.h
+++ b/virt/kvm/arm/vgic/vgic.h
@@ -286,6 +286,14 @@ vgic_v3_rd_region_size(struct kvm *kvm, struct vgic_redist_region *rdreg)
 }
 bool vgic_v3_rdist_overlap(struct kvm *kvm, gpa_t base, size_t size);
 
+static inline bool vgic_dist_overlap(struct kvm *kvm, gpa_t base, size_t size)
+{
+	struct vgic_dist *d = &kvm->arch.vgic;
+
+	return (base + size > d->vgic_dist_base) &&
+		(base < d->vgic_dist_base + KVM_VGIC_V3_DIST_SIZE);
+}
+
 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);
-- 
2.17.1

  parent reply	other threads:[~2018-06-01 15:27 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-06-01 15:27 [GIT PULL] KVM/ARM updates for 4.18 Marc Zyngier
2018-06-01 15:27 ` [PATCH 01/33] arm64: KVM: Use lm_alias() for kvm_ksym_ref() Marc Zyngier
2018-06-01 15:27 ` [PATCH 02/33] arm64: fpsimd: Fix TIF_FOREIGN_FPSTATE after invalidating cpu regs Marc Zyngier
2018-06-01 15:27 ` [PATCH 03/33] thread_info: Add update_thread_flag() helpers Marc Zyngier
2018-06-01 15:27 ` [PATCH 04/33] arm64: Use update{,_tsk}_thread_flag() Marc Zyngier
2018-06-01 15:27 ` [PATCH 05/33] KVM: arm/arm64: Introduce kvm_arch_vcpu_run_pid_change Marc Zyngier
2018-06-01 15:27 ` [PATCH 06/33] KVM: arm64: Convert lazy FPSIMD context switch trap to C Marc Zyngier
2018-06-01 15:27 ` [PATCH 07/33] arm64: fpsimd: Generalise context saving for non-task contexts Marc Zyngier
2018-06-01 15:27 ` [PATCH 08/33] arm64: fpsimd: Avoid FPSIMD context leakage for the init task Marc Zyngier
2018-06-01 15:27 ` [PATCH 09/33] arm64: fpsimd: Eliminate task->mm checks Marc Zyngier
2018-06-01 15:27 ` [PATCH 10/33] arm64/sve: Refactor user SVE trap maintenance for external use Marc Zyngier
2018-06-01 15:27 ` [PATCH 11/33] KVM: arm64: Repurpose vcpu_arch.debug_flags for general-purpose flags Marc Zyngier
2018-06-01 15:27 ` [PATCH 12/33] KVM: arm64: Optimise FPSIMD handling to reduce guest/host thrashing Marc Zyngier
2018-06-01 15:27 ` [PATCH 13/33] arm64/sve: Move read_zcr_features() out of cpufeature.h Marc Zyngier
2018-06-01 15:27 ` [PATCH 14/33] arm64/sve: Switch sve_pffr() argument from task to thread Marc Zyngier
2018-06-01 15:27 ` [PATCH 15/33] arm64/sve: Move sve_pffr() to fpsimd.h and make inline Marc Zyngier
2018-06-01 15:27 ` [PATCH 16/33] KVM: arm64: Save host SVE context as appropriate Marc Zyngier
2018-06-01 15:27 ` [PATCH 17/33] KVM: arm64: Remove eager host SVE state saving Marc Zyngier
2018-06-01 15:27 ` [PATCH 18/33] KVM: arm64: Remove redundant *exit_code changes in fpsimd_guest_exit() Marc Zyngier
2018-06-01 15:27 ` [PATCH 19/33] KVM: arm64: Fold redundant exit code checks out of fixup_guest_exit() Marc Zyngier
2018-06-01 15:27 ` [PATCH 20/33] KVM: arm64: Invoke FPSIMD context switch trap from C Marc Zyngier
2018-06-01 15:27 ` [PATCH 21/33] KVM: arm/arm64: Set dist->spis to NULL after kfree Marc Zyngier
2018-06-01 15:27 ` [PATCH 22/33] KVM: arm/arm64: Document KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION Marc Zyngier
2018-06-01 15:27 ` [PATCH 23/33] KVM: arm/arm64: Replace the single rdist region by a list Marc Zyngier
2018-06-01 15:27 ` [PATCH 24/33] KVM: arm/arm64: Helper to locate free rdist index Marc Zyngier
2018-06-01 15:27 ` [PATCH 25/33] KVM: arm/arm64: Revisit Redistributor TYPER last bit computation Marc Zyngier
2018-06-01 15:27 ` [PATCH 26/33] KVM: arm/arm64: Adapt vgic_v3_check_base to multiple rdist regions Marc Zyngier
2018-06-01 15:27 ` Marc Zyngier [this message]
2018-06-01 15:27 ` [PATCH 28/33] KVM: arm/arm64: Remove kvm_vgic_vcpu_early_init Marc Zyngier
2018-06-01 15:27 ` [PATCH 29/33] KVM: arm/arm64: Check vcpu redist base before registering an iodev Marc Zyngier
2018-06-01 15:27 ` [PATCH 30/33] KVM: arm/arm64: Check all vcpu redistributors are set on map_resources Marc Zyngier
2018-06-01 15:27 ` [PATCH 31/33] KVM: arm/arm64: Add KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION Marc Zyngier
2018-06-01 15:27 ` [PATCH 32/33] KVM: arm/arm64: Implement KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION Marc Zyngier
2018-06-01 15:27 ` [PATCH 33/33] KVM: arm/arm64: Bump VGIC_V3_MAX_CPUS to 512 Marc Zyngier
2018-06-01 17:18 ` [GIT PULL] KVM/ARM updates for 4.18 Paolo Bonzini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180601152747.23613-28-marc.zyngier@arm.com \
    --to=marc.zyngier@arm.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox