iommu: msm: ensure lazy mappings are unmapped on detach
Ensure that on detach any lazy mappings for that device are released. We don't want to leave any outstanding mappings after detach because the client expects all mappings to have been unmapped, also we don't want to leave references, in the lazy mapping framework, to devices which could cease to exists. CRs-Fixed: 1053605 Change-Id: I9894257c4783073fdba734a175bac486d6ee9347 Signed-off-by: Liam Mark <lmark@codeaurora.org>
This commit is contained in:
parent
e94b446eac
commit
05f15e3f74
4 changed files with 45 additions and 2 deletions
|
@ -28,6 +28,7 @@
|
|||
#include <linux/vmalloc.h>
|
||||
#include <linux/sizes.h>
|
||||
#include <linux/cma.h>
|
||||
#include <linux/msm_dma_iommu_mapping.h>
|
||||
|
||||
#include <asm/memory.h>
|
||||
#include <asm/highmem.h>
|
||||
|
@ -2190,6 +2191,9 @@ static void __arm_iommu_detach_device(struct device *dev)
|
|||
return;
|
||||
}
|
||||
|
||||
if (msm_dma_unmap_all_for_dev(dev))
|
||||
dev_warn(dev, "IOMMU detach with outstanding mappings\n");
|
||||
|
||||
iommu_detach_device(mapping->domain, dev);
|
||||
kref_put(&mapping->kref, release_iommu_mapping);
|
||||
to_dma_iommu_mapping(dev) = NULL;
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <linux/io.h>
|
||||
#include <asm/dma-iommu.h>
|
||||
#include <linux/dma-mapping-fast.h>
|
||||
#include <linux/msm_dma_iommu_mapping.h>
|
||||
|
||||
#include "mm.h"
|
||||
|
||||
|
@ -2164,6 +2165,9 @@ void arm_iommu_detach_device(struct device *dev)
|
|||
iommu_domain_get_attr(mapping->domain, DOMAIN_ATTR_S1_BYPASS,
|
||||
&s1_bypass);
|
||||
|
||||
if (msm_dma_unmap_all_for_dev(dev))
|
||||
dev_warn(dev, "IOMMU detach with outstanding mappings\n");
|
||||
|
||||
iommu_detach_device(mapping->domain, dev);
|
||||
kref_put(&mapping->kref, release_iommu_mapping);
|
||||
dev->archdata.mapping = NULL;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -344,6 +344,35 @@ out:
|
|||
return;
|
||||
}
|
||||
|
||||
int msm_dma_unmap_all_for_dev(struct device *dev)
|
||||
{
|
||||
int ret = 0;
|
||||
struct msm_iommu_meta *meta;
|
||||
struct rb_root *root;
|
||||
struct rb_node *meta_node;
|
||||
|
||||
mutex_lock(&msm_iommu_map_mutex);
|
||||
root = &iommu_root;
|
||||
meta_node = rb_first(root);
|
||||
while (meta_node) {
|
||||
struct msm_iommu_map *iommu_map;
|
||||
|
||||
meta = rb_entry(meta_node, struct msm_iommu_meta, node);
|
||||
mutex_lock(&meta->lock);
|
||||
list_for_each_entry(iommu_map, &meta->iommu_maps, lnode)
|
||||
if (iommu_map->dev == dev)
|
||||
if (!kref_put(&iommu_map->ref,
|
||||
msm_iommu_map_release))
|
||||
ret = -EINVAL;
|
||||
|
||||
mutex_unlock(&meta->lock);
|
||||
meta_node = rb_next(meta_node);
|
||||
}
|
||||
mutex_unlock(&msm_iommu_map_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Only to be called by ION code when a buffer is freed
|
||||
*/
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -50,6 +50,7 @@ static inline int msm_dma_map_sg(struct device *dev, struct scatterlist *sg,
|
|||
void msm_dma_unmap_sg(struct device *dev, struct scatterlist *sgl, int nents,
|
||||
enum dma_data_direction dir, struct dma_buf *dma_buf);
|
||||
|
||||
int msm_dma_unmap_all_for_dev(struct device *dev);
|
||||
|
||||
/*
|
||||
* Below is private function only to be called by framework (ION) and not by
|
||||
|
@ -89,6 +90,11 @@ static inline void msm_dma_unmap_sg(struct device *dev,
|
|||
{
|
||||
}
|
||||
|
||||
int msm_dma_unmap_all_for_dev(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void msm_dma_buf_freed(void *buffer) {}
|
||||
#endif /*CONFIG_IOMMU_API*/
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue