Commit 7062af3e authored by Jean-Philippe Brucker's avatar Jean-Philippe Brucker Committed by Joerg Roedel
Browse files

iommu/virtio: Fix freeing of incomplete domains



Calling viommu_domain_free() on a domain that hasn't been finalised (not
attached to any device, for example) can currently cause an Oops,
because we attempt to call ida_free() on ID 0, which may either be
unallocated or used by another domain.

Only initialise the vdomain->viommu pointer, which denotes a finalised
domain, at the end of a successful viommu_domain_finalise().

Fixes: edcd69ab ("iommu: Add virtio-iommu driver")
Reported-by: default avatarEric Auger <eric.auger@redhat.com>
Signed-off-by: default avatarJean-Philippe Brucker <jean-philippe@linaro.org>
Reviewed-by: default avatarRobin Murphy <robin.murphy@arm.com>
Link: https://lore.kernel.org/r/20200326093558.2641019-3-jean-philippe@linaro.org


Signed-off-by: default avatarJoerg Roedel <jroedel@suse.de>
parent 3f84b96c
Loading
Loading
Loading
Loading
+9 −7
Original line number Diff line number Diff line
@@ -613,18 +613,20 @@ static int viommu_domain_finalise(struct viommu_dev *viommu,
	int ret;
	struct viommu_domain *vdomain = to_viommu_domain(domain);

	vdomain->viommu		= viommu;
	vdomain->map_flags	= viommu->map_flags;
	ret = ida_alloc_range(&viommu->domain_ids, viommu->first_domain,
			      viommu->last_domain, GFP_KERNEL);
	if (ret < 0)
		return ret;

	vdomain->id		= (unsigned int)ret;

	domain->pgsize_bitmap	= viommu->pgsize_bitmap;
	domain->geometry	= viommu->geometry;

	ret = ida_alloc_range(&viommu->domain_ids, viommu->first_domain,
			      viommu->last_domain, GFP_KERNEL);
	if (ret >= 0)
		vdomain->id = (unsigned int)ret;
	vdomain->map_flags	= viommu->map_flags;
	vdomain->viommu		= viommu;

	return ret > 0 ? 0 : ret;
	return 0;
}

static void viommu_domain_free(struct iommu_domain *domain)