aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean-Philippe Brucker <jean-philippe.brucker@arm.com>2018-06-18 19:42:11 +0100
committerWill Deacon <will.deacon@arm.com>2018-06-19 12:26:41 +0100
commit41d773e2070aabd3c4ff20c059f45c3e9a0f9d20 (patch)
tree1c84a94f99e52515ab39beedfb8f6af49e9735b9
parentfa1076ab6342355f2b400656233fb6fe0477e098 (diff)
downloadkvmtool-41d773e2070aabd3c4ff20c059f45c3e9a0f9d20.tar.gz
vfio: check reserved regions before mapping DMA
Use the new reserved_regions API to ensure that RAM doesn't overlap any reserved region. This prevents for instance from mapping an MSI doorbell into the guest IPA space. For the moment we reject any overlapping. In the future, we might carve reserved regions out of the guest physical space. Reviewed-by: Punit Agrawal <punit.agrawal@arm.com> Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
-rw-r--r--vfio/core.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/vfio/core.c b/vfio/core.c
index a4a257a7..17b5b0cf 100644
--- a/vfio/core.c
+++ b/vfio/core.c
@@ -379,6 +379,51 @@ static int vfio_unmap_mem_bank(struct kvm *kvm, struct kvm_mem_bank *bank, void
return 0;
}
+static int vfio_configure_reserved_regions(struct kvm *kvm,
+ struct vfio_group *group)
+{
+ FILE *file;
+ int ret = 0;
+ char type[9];
+ char filename[PATH_MAX];
+ unsigned long long start, end;
+
+ snprintf(filename, PATH_MAX, IOMMU_GROUP_DIR "/%lu/reserved_regions",
+ group->id);
+
+ /* reserved_regions might not be present on older systems */
+ if (access(filename, F_OK))
+ return 0;
+
+ file = fopen(filename, "r");
+ if (!file)
+ return -errno;
+
+ while (fscanf(file, "0x%llx 0x%llx %8s\n", &start, &end, type) == 3) {
+ ret = kvm__reserve_mem(kvm, start, end - start + 1);
+ if (ret)
+ break;
+ }
+
+ fclose(file);
+
+ return ret;
+}
+
+static int vfio_configure_groups(struct kvm *kvm)
+{
+ int ret;
+ struct vfio_group *group;
+
+ list_for_each_entry(group, &vfio_groups, list) {
+ ret = vfio_configure_reserved_regions(kvm, group);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
static struct vfio_group *vfio_group_create(struct kvm *kvm, unsigned long id)
{
int ret;
@@ -597,6 +642,10 @@ static int vfio__init(struct kvm *kvm)
if (ret)
return ret;
+ ret = vfio_configure_groups(kvm);
+ if (ret)
+ return ret;
+
ret = vfio_configure_devices(kvm);
if (ret)
return ret;