#include "rockchip-iommu.h"
+#define IOMMU_REGION_GUARD (2<<PAGE_SHIFT)
+
static struct rk_vm_region *find_region(struct rk_iovmm *vmm, dma_addr_t iova)
{
struct rk_vm_region *region;
goto err_map_nomem;
}
- start = (dma_addr_t)gen_pool_alloc(vmm->vmm_pool, size);
+ start = (dma_addr_t)gen_pool_alloc(vmm->vmm_pool,
+ size+IOMMU_REGION_GUARD);
if (!start) {
ret = -ENOMEM;
goto err_map_noiomem;
spin_unlock(&vmm->lock);
ret = rockchip_iommu_tlb_invalidate(dev);
- if (ret)
+ if (ret) {
+ spin_lock(&vmm->lock);
+ list_del(®ion->node);
+ spin_unlock(&vmm->lock);
goto err_map_map;
-
+ }
dev_dbg(dev->archdata.iommu, "IOVMM: Allocated VM region @ %p/%#X bytes.\n",
®ion->start, region->size);
return region->start;
err_map_map:
- spin_lock(&vmm->lock);
- list_del(®ion->node);
- spin_unlock(&vmm->lock);
iommu_unmap(vmm->domain, start, mapped_size);
gen_pool_free(vmm->vmm_pool, start, size);
err_map_noiomem:
/*
rockchip_iommu_tlb_invalidate(dev);
*/
- gen_pool_free(vmm->vmm_pool, region->start, region->size);
+ gen_pool_free(vmm->vmm_pool, region->start,
+ region->size+IOMMU_REGION_GUARD);
WARN_ON(unmapped_size != region->size);