diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2016-09-30 18:23:51 -0700 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2016-09-30 18:23:50 -0700 |
commit | 0af03e722dcda0997a933c3fcaa3dfc5c2929cb3 (patch) | |
tree | adf52e8e3624be57b7e5917a66f742863d9afc96 /drivers/gpu | |
parent | e8200cdfa9763a52987f3cd48ea85186b43c3e09 (diff) | |
parent | 3f25aa2b782aef42da07fd54a89b9c3e729cc6bf (diff) |
Merge "msm: kgsl: Do not free gpuaddr range if unmap fails"
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/msm/kgsl.c | 12 | ||||
-rw-r--r-- | drivers/gpu/msm/kgsl_mmu.c | 7 | ||||
-rw-r--r-- | drivers/gpu/msm/kgsl_sharedmem.c | 12 |
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) |