summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2016-09-30 18:23:51 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2016-09-30 18:23:50 -0700
commit0af03e722dcda0997a933c3fcaa3dfc5c2929cb3 (patch)
treeadf52e8e3624be57b7e5917a66f742863d9afc96
parente8200cdfa9763a52987f3cd48ea85186b43c3e09 (diff)
parent3f25aa2b782aef42da07fd54a89b9c3e729cc6bf (diff)
Merge "msm: kgsl: Do not free gpuaddr range if unmap fails"
-rw-r--r--drivers/gpu/msm/kgsl.c12
-rw-r--r--drivers/gpu/msm/kgsl_mmu.c7
-rw-r--r--drivers/gpu/msm/kgsl_sharedmem.c12
3 files changed, 22 insertions, 9 deletions
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 6e9abc99bcc4..88581b079246 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -485,6 +485,7 @@ err_put_proc_priv:
static void kgsl_mem_entry_detach_process(struct kgsl_mem_entry *entry)
{
unsigned int type;
+ int ret;
if (entry == NULL)
return;
@@ -501,9 +502,14 @@ static void kgsl_mem_entry_detach_process(struct kgsl_mem_entry *entry)
entry->priv->stats[type].cur -= entry->memdesc.size;
spin_unlock(&entry->priv->mem_lock);
- kgsl_mmu_unmap(entry->memdesc.pagetable, &entry->memdesc);
-
- kgsl_mem_entry_untrack_gpuaddr(entry->priv, entry);
+ ret = kgsl_mmu_unmap(entry->memdesc.pagetable, &entry->memdesc);
+ /*
+ * Do not free the gpuaddr/size if unmap fails. Because if we try
+ * to map this range in future, the iommu driver will throw
+ * a BUG_ON() because it feels we are overwriting a mapping.
+ */
+ if (ret == 0)
+ kgsl_mem_entry_untrack_gpuaddr(entry->priv, entry);
kgsl_process_private_put(entry->priv);
diff --git a/drivers/gpu/msm/kgsl_mmu.c b/drivers/gpu/msm/kgsl_mmu.c
index 4371c9a1b87e..ba564b2851f9 100644
--- a/drivers/gpu/msm/kgsl_mmu.c
+++ b/drivers/gpu/msm/kgsl_mmu.c
@@ -450,24 +450,23 @@ int
kgsl_mmu_unmap(struct kgsl_pagetable *pagetable,
struct kgsl_memdesc *memdesc)
{
+ int ret = 0;
+
if (memdesc->size == 0)
return -EINVAL;
if (PT_OP_VALID(pagetable, mmu_unmap)) {
- int ret;
uint64_t size;
size = kgsl_memdesc_footprint(memdesc);
ret = pagetable->pt_ops->mmu_unmap(pagetable, memdesc);
- if (ret)
- return ret;
atomic_dec(&pagetable->stats.entries);
atomic_long_sub(size, &pagetable->stats.mapped);
}
- return 0;
+ return ret;
}
EXPORT_SYMBOL(kgsl_mmu_unmap);
diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c
index 73edc3f7e146..72895c18119f 100644
--- a/drivers/gpu/msm/kgsl_sharedmem.c
+++ b/drivers/gpu/msm/kgsl_sharedmem.c
@@ -807,8 +807,16 @@ void kgsl_sharedmem_free(struct kgsl_memdesc *memdesc)
return;
if (memdesc->gpuaddr) {
- kgsl_mmu_unmap(memdesc->pagetable, memdesc);
- kgsl_mmu_put_gpuaddr(memdesc->pagetable, memdesc);
+ int ret = 0;
+
+ ret = kgsl_mmu_unmap(memdesc->pagetable, memdesc);
+ /*
+ * Do not free the gpuaddr/size if unmap fails. Because if we
+ * try to map this range in future, the iommu driver will throw
+ * a BUG_ON() because it feels we are overwriting a mapping.
+ */
+ if (ret == 0)
+ kgsl_mmu_put_gpuaddr(memdesc->pagetable, memdesc);
}
if (memdesc->ops && memdesc->ops->free)