lkml.org 
[lkml]   [2015]   [Feb]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH v4 26/28] vfio: powerpc/spapr: Rework an IOMMU group attach/detach
Date
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
---
drivers/vfio/vfio_iommu_spapr_tce.c | 62 +++++++++++++++++++++++--------------
1 file changed, 38 insertions(+), 24 deletions(-)

diff --git a/drivers/vfio/vfio_iommu_spapr_tce.c b/drivers/vfio/vfio_iommu_spapr_tce.c
index fdcc04c..4ff8289 100644
--- a/drivers/vfio/vfio_iommu_spapr_tce.c
+++ b/drivers/vfio/vfio_iommu_spapr_tce.c
@@ -435,7 +435,7 @@ static void tce_iommu_release(void *iommu_data)
iommu = iommu_group_get_iommudata(container->grp);
tbl = &iommu->tables[0];
tce_iommu_clear(container, tbl, tbl->it_offset, tbl->it_size);
-
+ iommu->ops->free_table(tbl);
tce_iommu_detach_group(iommu_data, container->grp);
}

@@ -796,6 +796,7 @@ static int tce_iommu_attach_group(void *iommu_data,
int ret = 0;
struct tce_container *container = iommu_data;
struct powerpc_iommu *iommu;
+ struct iommu_table tbltmp = { 0 }, *tbl = &tbltmp;

mutex_lock(&container->lock);

@@ -806,35 +807,44 @@ static int tce_iommu_attach_group(void *iommu_data,
iommu_group_id(container->grp),
iommu_group_id(iommu_group));
ret = -EBUSY;
- } else if (container->enabled) {
+ goto unlock_exit;
+ }
+
+ if (container->enabled) {
pr_err("tce_vfio: attaching group #%u to enabled container\n",
iommu_group_id(iommu_group));
ret = -EBUSY;
+ goto unlock_exit;
+ }
+
+ iommu = iommu_group_get_iommudata(iommu_group);
+ if (WARN_ON_ONCE(!iommu)) {
+ ret = -ENXIO;
+ goto unlock_exit;
+ }
+
+ /*
+ * Disable iommu bypass, otherwise the user can DMA to all of
+ * our physical memory via the bypass window instead of just
+ * the pages that has been explicitly mapped into the iommu
+ */
+ if (iommu->ops && iommu->ops->set_ownership) {
+ iommu->ops->set_ownership(iommu, true);
} else {
- iommu = iommu_group_get_iommudata(iommu_group);
- if (WARN_ON_ONCE(!iommu)) {
- ret = -ENXIO;
- } else if (iommu->ops && iommu->ops->set_ownership) {
- /*
- * Disable iommu bypass, otherwise the user can DMA to all of
- * our physical memory via the bypass window instead of just
- * the pages that has been explicitly mapped into the iommu
- */
- struct iommu_table tbltmp = { 0 }, *tbl = &tbltmp;
-
- iommu->ops->set_ownership(iommu, true);
- container->grp = iommu_group;
-
- ret = iommu->ops->create_table(iommu, 0,
- IOMMU_PAGE_SHIFT_4K,
- ilog2(iommu->tce32_size), 1, tbl);
- if (!ret)
- ret = iommu->ops->set_window(iommu, 0, tbl);
- } else {
- ret = -ENODEV;
- }
+ ret = -ENODEV;
+ goto unlock_exit;
}

+ container->grp = iommu_group;
+
+ /* Create the default window as only now we know the parameters */
+ ret = iommu->ops->create_table(iommu, 0,
+ IOMMU_PAGE_SHIFT_4K,
+ ilog2(iommu->tce32_size), 1, tbl);
+ if (!ret)
+ ret = iommu->ops->set_window(iommu, 0, tbl);
+
+unlock_exit:
mutex_unlock(&container->lock);

return ret;
@@ -845,6 +855,7 @@ static void tce_iommu_detach_group(void *iommu_data,
{
struct tce_container *container = iommu_data;
struct powerpc_iommu *iommu;
+ long i;

mutex_lock(&container->lock);
if (iommu_group != container->grp) {
@@ -865,6 +876,9 @@ static void tce_iommu_detach_group(void *iommu_data,
iommu = iommu_group_get_iommudata(iommu_group);
BUG_ON(!iommu);

+ for (i = 0; i < POWERPC_IOMMU_MAX_TABLES; ++i)
+ iommu->ops->unset_window(iommu, i);
+
/* Kernel owns the device now, we can restore bypass */
if (iommu->ops && iommu->ops->set_ownership)
iommu->ops->set_ownership(iommu, false);
--
2.0.0


\
 
 \ /
  Last update: 2015-02-16 11:21    [W:0.079 / U:0.572 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site