[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1455264797-2334-10-git-send-email-eric.auger@linaro.org>
Date: Fri, 12 Feb 2016 08:13:11 +0000
From: Eric Auger <eric.auger@...aro.org>
To: eric.auger@...com, eric.auger@...aro.org,
alex.williamson@...hat.com, will.deacon@....com, joro@...tes.org,
tglx@...utronix.de, jason@...edaemon.net, marc.zyngier@....com,
christoffer.dall@...aro.org, linux-arm-kernel@...ts.infradead.org,
kvmarm@...ts.cs.columbia.edu, kvm@...r.kernel.org
Cc: suravee.suthikulpanit@....com, patches@...aro.org,
linux-kernel@...r.kernel.org, Manish.Jaggi@...iumnetworks.com,
Bharat.Bhushan@...escale.com, pranav.sawargaonkar@...il.com,
p.fedin@...sung.com, iommu@...ts.linux-foundation.org,
sherry.hurwitz@....com, brijesh.singh@....com, leo.duran@....com,
Thomas.Lendacky@....com
Subject: [RFC v3 09/15] iommu/arm-smmu: relinquish reserved resources on domain deletion
arm_smmu_unmap_reserved releases all reserved binding resources:
destroy all bindings, free iova, free iova_domain. This happens
on domain deletion.
Signed-off-by: Eric Auger <eric.auger@...aro.org>
---
drivers/iommu/arm-smmu.c | 34 +++++++++++++++++++++++++++++-----
1 file changed, 29 insertions(+), 5 deletions(-)
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 9961bfd..ae8a97d 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -363,6 +363,7 @@ struct arm_smmu_reserved_binding {
dma_addr_t iova;
size_t size;
};
+static void arm_smmu_unmap_reserved(struct iommu_domain *domain);
static struct iommu_ops arm_smmu_ops;
@@ -1057,6 +1058,7 @@ static void arm_smmu_domain_free(struct iommu_domain *domain)
* already been detached.
*/
arm_smmu_destroy_domain_context(domain);
+ arm_smmu_unmap_reserved(domain);
kfree(smmu_domain);
}
@@ -1547,19 +1549,23 @@ unlock:
return ret;
}
-static void arm_smmu_free_reserved_iova_domain(struct iommu_domain *domain)
+static void __arm_smmu_free_reserved_iova_domain(struct arm_smmu_domain *sd)
{
- struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
- struct iova_domain *iovad = smmu_domain->reserved_iova_domain;
+ struct iova_domain *iovad = sd->reserved_iova_domain;
if (!iovad)
return;
- mutex_lock(&smmu_domain->reserved_mutex);
-
put_iova_domain(iovad);
kfree(iovad);
+}
+static void arm_smmu_free_reserved_iova_domain(struct iommu_domain *domain)
+{
+ struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
+
+ mutex_lock(&smmu_domain->reserved_mutex);
+ __arm_smmu_free_reserved_iova_domain(smmu_domain);
mutex_unlock(&smmu_domain->reserved_mutex);
}
@@ -1675,6 +1681,24 @@ unlock:
mutex_unlock(&smmu_domain->reserved_mutex);
}
+static void arm_smmu_unmap_reserved(struct iommu_domain *domain)
+{
+ struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
+ struct rb_node *node;
+
+ mutex_lock(&smmu_domain->reserved_mutex);
+ while ((node = rb_first(&smmu_domain->reserved_binding_list))) {
+ struct arm_smmu_reserved_binding *b =
+ rb_entry(node, struct arm_smmu_reserved_binding, node);
+
+ while (!kref_put(&b->kref, reserved_binding_release))
+ ;
+ }
+ smmu_domain->reserved_binding_list = RB_ROOT;
+ __arm_smmu_free_reserved_iova_domain(smmu_domain);
+ mutex_unlock(&smmu_domain->reserved_mutex);
+}
+
static struct iommu_ops arm_smmu_ops = {
.capable = arm_smmu_capable,
.domain_alloc = arm_smmu_domain_alloc,
--
1.9.1
Powered by blists - more mailing lists